I am upgrading crosstools from gcc-7.5.0 to gcc 11.4.0.
Using gcc 7.5.0, below source files can be built successfully.
But using gcc 11.4.0, linking errors occur:
PATH-TO-CROSSTOOLS/ld:test_beta/libtest_beta.a(test_b.o):/common.h:1: multipledefinition of `g_common';test_beta/libtest_beta.a(test_a.o):/common.h:1: firstdefined here
PATH-TO-CROSSTOOLS/ld:test_beta/libtest_beta.a(test_c.o):/common.h:1: multipledefinition of `g_common';test_beta/libtest_beta.a(test_a.o):/common.h:1: firstdefined here
I can totally understand the error, indeed we should not define variables at C header files, but the code are from third-party library, so it is not easy to modify it.
My question: Why gcc 7.5.0 can build them successfully?
In my opinion the code should always fail building, using gcc 7.5.0 or 11.4.0.
Code is defined as below:
common.h:
int g_common;int comp(int a, int b);int plus(int a, int b);int minus(int a, int b);
test_a.c:
#include <stdio.h>#include "common.h"int comp(int a, int b){ g_common = 1; printf("g_common: %d\n", g_common); return (a > b);}
test_b.c:
#include "common.h"int plus(int a, int b){ return (a + b);}
test_c.c:
#include "common.h"int minus(int a, int b){ return (a - b);}
build script(based gcc 7.5.0):
#!/bin/shecho "Clean build dir"rm -rf test_alpha/*for src in test_a test_b test_c;do echo "Build $src.c"<PATH-TO-CROSSTOOLS>/aarch64-openwrt-linux-gcc -fno-builtin -Wno-ignored-qualifiers -g -O2 -Wall -Wbad-function-cast -Wmissing-declarations -Wmissing-format-attribute -Wmissing-prototypes -Wmultichar -Wstrict-prototypes -Wdiv-by-zero -Wpointer-arith -Wextra -Wchar-subscripts -Wdeprecated-declarations -Winvalid-pch -Wnested-externs -Wsystem-headers -Wunused -fPIC -rdynamic -Werror -Wformat-nonliteral -Wmissing-noreturn -Wwrite-strings -Wshadow -Wswitch-enum -Wswitch-default -c -I. $src.c -o test_alpha/$src.odoneecho "making libtest_alpha.a"<PATH-TO-CROSSTOOLS>/aarch64-openwrt-linux-ar rc test_alpha/libtest_alpha.a test_alpha/test_a.o test_alpha/test_b.o test_alpha/test_c.oecho "making libtest_alpha.so"<PATH-TO-CROSSTOOLS>/aarch64-openwrt-linux-gcc -fno-builtin -Wno-ignored-qualifiers -g -O2 -Wall -Wbad-function-cast -Wmissing-declarations -Wmissing-format-attribute -Wmissing-prototypes -Wmultichar -Wstrict-prototypes -Wdiv-by-zero -Wpointer-arith -Wextra -Wchar-subscripts -Wdeprecated-declarations -Winvalid-pch -Wnested-externs -Wsystem-headers -Wunused -fPIC -rdynamic -Werror -Wformat-nonliteral -Wmissing-noreturn -Wwrite-strings -Wshadow -Wswitch-enum -Wswitch-default -shared -Wl,-soname,libtest_alpha.so -Wl,--whole-archive test_alpha/libtest_alpha.a -Wl,--no-whole-archive -o test_alpha/libtest_alpha.so
build script(based gcc 11.4.0):
#!/bin/shPATH=<PATH-TO-CROSSTOOLS>:$PATHecho "Clean build dir"rm -rf test_beta/*for src in test_a test_b test_c;do echo "Build $src.c"; aarch64-openwrt-linux-gcc --sysroot=<PATH-TO-SYSROOT>/recipe-sysroot -fno-builtin -Wno-ignored-qualifiers -g -O2 -Wall -Wbad-function-cast -Wmissing-declarations -Wmissing-format-attribute -Wmissing-prototypes -Wmultichar -Wstrict-prototypes -Wdiv-by-zero -Wpointer-arith -Wextra -Wchar-subscripts -Wdeprecated-declarations -Winvalid-pch -Wnested-externs -Wsystem-headers -Wunused -fPIC -rdynamic -Werror -Wformat-nonliteral -Wmissing-noreturn -Wwrite-strings -Wshadow -Wswitch-enum -Wswitch-default -c -I. $src.c -o test_beta/$src.odoneecho "making libtest_beta.a"aarch64-openwrt-linux-ar rc test_beta/libtest_beta.a test_beta/test_a.o test_beta/test_b.o test_beta/test_c.oecho "making libtest_beta.so"aarch64-openwrt-linux-gcc --sysroot=<PATH-TO-SYSROOT>/recipe-sysroot -fno-builtin -Wno-ignored-qualifiers -g -O2 -Wall -Wbad-function-cast -Wmissing-declarations -Wmissing-format-attribute -Wmissing-prototypes -Wmultichar -Wstrict-prototypes -Wdiv-by-zero -Wpointer-arith -Wextra -Wchar-subscripts -Wdeprecated-declarations -Winvalid-pch -Wnested-externs -Wsystem-headers -Wunused -fPIC -rdynamic -Werror -Wformat-nonliteral -Wmissing-noreturn -Wwrite-strings -Wshadow -Wswitch-enum -Wswitch-default -shared -Wl,-soname,libtest_beta.so -Wl,--whole-archive test_beta/libtest_beta.a -Wl,--no-whole-archive -o test_beta/libtest_beta.so