socketcand icon indicating copy to clipboard operation
socketcand copied to clipboard

Build error on opensuse

Open agronick opened this issue 4 years ago • 2 comments

I'm getting the following error during build. I don't know if its a bug or an issue with my system. Appreceate if anyone knows how to fix it.

make
gcc -Wall -Wno-parentheses -DPF_CAN=29 -DAF_CAN=PF_CAN -DHAVE_CONFIG_H   -I . -I ./include -o socketcand ./socketcand.c ./statistics.c ./beacon.c ./state_bcm.c ./state_raw.c ./state_isotp.c ./state_control.c -lpthread 
/usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/ccJ8QkBR.o:(.bss+0x20): multiple definition of `ifr'; /tmp/cctNtctR.o:(.bss+0x2200): first defined here
/usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/ccJ8QkBR.o:(.bss+0x60): multiple definition of `readfds'; /tmp/ccETFL7Q.o:(.bss+0x0): first defined here
/usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/ccJ8QkBR.o:(.bss+0x180): multiple definition of `tv'; /tmp/ccETFL7Q.o:(.bss+0x80): first defined here
/usr/lib64/gcc/x86_64-suse-linux/10/../../../../x86_64-suse-linux/bin/ld: /tmp/ccvecglO.o:(.bss+0x0): multiple definition of `readfds'; /tmp/ccETFL7Q.o:(.bss+0x0): first defined here
collect2: error: ld returned 1 exit status
make: *** [Makefile:32: socketcand] Error 1

When I try LDFLAGS=--allow-multiple-definition it says the c++ compiler isn't working.

When I try with g++ I get this error:

./socketcand.c: In function ‘int main(int, char**)’:
./socketcand.c:208:22: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
  208 |  description = malloc(sizeof(BEACON_DESCRIPTION));
      |                ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                      |
      |                      void*
./socketcand.c:210:27: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
  210 |  interface_string = malloc(strlen(DEFAULT_INTERFACE)+ 1);
      |                     ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                           |
      |                           void*
./socketcand.c:212:24: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
  212 |  busses_string = malloc(strlen(DEFAULT_BUSNAME)+ 1);
      |                  ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                        |
      |                        void*
./socketcand.c:264:27: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
  264 |    busses_string = realloc(busses_string, strlen(optarg)+1);
      |                    ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                           |
      |                           void*
./socketcand.c:273:22: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
  273 |    afuxname = realloc(afuxname, strlen(optarg)+1);
      |               ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                      |
      |                      void*
./socketcand.c:278:30: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
  278 |    interface_string = realloc(interface_string, strlen(optarg)+1);
      |                       ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                              |
      |                              void*
./socketcand.c:319:26: error: invalid conversion from ‘void*’ to ‘char**’ [-fpermissive]
  319 |  interface_names = malloc(sizeof(char *) * interface_count);
      |                    ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      |                          |
      |                          void*
./socketcand.c:334:28: error: invalid conversion from ‘void (*)()’ to ‘__sighandler_t’ {aka ‘void (*)(int)’} [-fpermissive]
  334 |  signalaction.sa_handler = &childdied;
      |                            ^~~~~~~~~~
      |                            |
      |                            void (*)()
./socketcand.c:339:29: error: invalid conversion from ‘void (*)()’ to ‘__sighandler_t’ {aka ‘void (*)(int)’} [-fpermissive]
  339 |  sigint_action.sa_handler = &sigint;
      |                             ^~~~~~~
      |                             |
      |                             void (*)()
./statistics.c: In function ‘void* statistics_loop(void*)’:
./statistics.c:61:12: warning: comparison of integer expressions of different signedness: ‘int’ and ‘size_t’ {aka ‘long unsigned int’} [-Wsign-compare]
   61 |    for(;pos<strlen(name);pos++)
      |         ~~~^~~~~~~~~~~~~
./state_bcm.c: In function ‘void state_bcm()’:
./state_bcm.c:372:18: warning: comparison of integer expressions of different signedness: ‘int’ and ‘__u32’ {aka ‘unsigned int’} [-Wsign-compare]
  372 |    for (i = 0; i < muxmsg.msg_head.nframes; i++) {
      |                ~~^~~~~~~~~~~~~~~~~~~~~~~~~
./state_raw.c: In function ‘void state_raw()’:
./state_raw.c:107:10: warning: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’ [-Wsign-compare]
  107 |   if(ret < sizeof(struct can_frame)) {
      |      ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
./state_raw.c:120:13: error: expected primary-expression before ‘class’
  120 |     canid_t class = frame.can_id  & CAN_EFF_MASK;
      |             ^~~~~
./state_raw.c:121:52: error: expected primary-expression before ‘class’
  121 |     ret = sprintf(buf, "< error %03X %ld.%06ld >", class, tv.tv_sec, tv.tv_usec);
      |                                    

Edit: So I can get rid of the errors here by renaming the variable class to _class and by using -fpermissive. After that I get the same errors I was getting on gcc.

agronick avatar Jun 07 '20 18:06 agronick

Running configure LDFLAGS="-z muldefs" ./configure worked for some reason.

agronick avatar Jun 07 '20 19:06 agronick

It's a problem with gcc-10.

gcc-10 fails if you have a global symbol defined in more than one source file, see https://gcc.gnu.org/gcc-10/porting_to.html

A common mistake in C is omitting extern when declaring a global variable in a header file. If the header is included by several files it results in multiple definitions of the same variable. In previous GCC versions this error is ignored. GCC 10 defaults to -fno-common, which means a linker error will now be reported. To fix this, use extern in header files when declaring global variables, and ensure each global is defined in exactly one C file. If tentative definitions of particular variables need to be placed in a common block, __attribute__((__common__)) can be used to force that behavior even in code compiled without -fcommon. As a workaround, legacy C code where all tentative definitions should be placed into a common block can be compiled with -fcommon.

So the proper fix is to put the true globals into a header file and define them as extern, while declaring all other variables as static or moving them into the scope of functions.

marckleinebudde avatar Jun 07 '20 19:06 marckleinebudde