linux-can / socketcand

Server to access CAN sockets over ASCII protocol
169 stars 43 forks source link

Build error on opensuse #14

Open agronick opened 4 years ago

agronick commented 4 years ago

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 commented 4 years ago

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

marckleinebudde commented 4 years ago

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.