socketcand
socketcand copied to clipboard
Build error on opensuse
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.
Running configure LDFLAGS="-z muldefs" ./configure
worked for some reason.
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.