undefined reference to sync_fetch_and_add_4 - c

Whenever I try to use __sync_fetch_and_add with -m32 on a 64 bit machine, I get the following error, while it compiles fine with normal 64 bit. I am using gcc compiler 4.1.2. What can be the problem here and what is the solution?
replication.cpp:(.text+0xb3b): undefined reference to `__sync_fetch_and_add_4'
replication.cpp:(.text+0xb82): undefined reference to `__sync_fetch_and_add_4'
replication.cpp:(.text+0xcc2): undefined reference to `__sync_fetch_and_add_4'
/tmp/cc7u9FLV.o: In function `potential_barrier_leader(unsigned int, pthread_barrier_t*)':
replication.cpp:(.text+0xd3f): undefined reference to `__sync_fetch_and_add_4'
replication.cpp:(.text+0xd54): undefined reference to `__sync_fetch_and_add_4'
/tmp/cc7u9FLV.o:replication.cpp:(.text+0xdb0): more undefined references to `__sync_fetch_and_add_4' follow
collect2: ld returned 1 exit status
make: *** [all] Error 1

Using -march=i486 flag did the trick for me.

Try using a more recent GCC compiler (e.g. GCC 4.6). I tried to compile with gcc -S -O3 -m32 -fverbose-asm sync-3.c the test file gcc/testsuite/gcc.c-torture/compile/sync-3.c and it works. My gcc (on Debian/Sid/AMD64) is the system gcc 4.6.2 compiler.

hahah! there are 5+ "standard atomic libs" (+kernel support) that's hardly atom
ic if you ask me. but ignore it, is all a timely distraction.
so your building, ie glibc and get that error (i did)
glibc-2.11.x expects gcc-4.4.x to define it internally, and you have gcc sans bu
ilt-in atomic, likely you didnt specify arch that gcc accepts (due to lacky dire
ctions). were glibc likes 786, gcc wants 386 and figures 786 maybe. use "nativ
e" should do it. opt(march) and opt(mtune) ARE NON OPTIONAL gcc builds wrong w/
o them (likely)
you won't find a header or libfoo that defines it (per say)
for linux-gnu you might use (a simple for moi build)
cd gcc-4.4.foo
./configure --with-glibc-version=2.11 --enable-threads=posix \
--disable-cloog --disable-ppl --disable-libssp --enable-__cxa_atexit \
--disable-rpath --disable-nls --disable-bootstrp --disable-multilib \
--with-system-libunwind
IMPORTANT: if you build gcc w/o mtune march right, gcc wont define sync_fetch_and_add
(p.s. glibc sync_fetch_and_add_4 is just macro for sync_fetch_and_add which, aga
in, glibc expects is defined)
also if you replace gcc-3.foo with gcc-4.4.foo and are compiling you may need:
[ -n "$newgnu" ] && CFLAGS="$CFLAGS -march=native -mtune=native "
[ -n "$newgnu" ] && \
CFLAGS="$CFLAGS -std=gnu89 " && CPPFLAGS="$CPPFLAGS -std=gnu89 "
i newly need this (newgnu) to build binutils-ver/: -Wstrict-aliasing=0
cd glibc-2.foo/
./configure --with-headers=/usr/src/linux/usr/include \
--enable-kernel=2.2.foo \
--disable-profile --disable-sanity-checks --with-tls \
--disable-rpath --disable-nls
thanks guy in holland for posting --std that might be an issue for gcc upgraders !
no thanks to comittees continually changing and also creating "standards" that make depends problems in gcc :( use .h or .c appropriately for foo "builtin" to add features you want in your code like everyone else !!
have fun :)

With old GCC versions (4.5 for example) you might encounter the problem of __sync_fetch_and_add() being undeclared when using the g++ driver instead of gcc for linking a shared library.
Background: __sync_fetch_and_add is defined within static libgcc and missing from shared library libgcc_s.
So simply adding -lgcc might solve the problem. But there is a more elegant solution.
See here for full information and workaround(s):
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46563

Related

flatcc undefined symbol aligned_free/aligned_malloc

Resolved
I'm currently working on LabWindows/CVI, this is a C. The only version of C supported is c99. I'm trying to integrate Google Flatbuffers (the c version flatcc) to my current project. When I'm trying to link my solution, I'm facing a linking error :
First question : how could I fix this error ?
According to the vendor, LabWindows/CVI use CLANG as compiler. if I take a look at the file where the symbol aligned_free /algined_malloc apear, I can read this :
/*
* NOTE: MSVC in general has no aligned alloc function that is
* compatible with free and it is not trivial to implement a version
* which is. Therefore, to remain portable, end user code needs to
* use `aligned_free` which is not part of C11 but defined in this header.
*
* glibc only provides aligned_alloc when _ISOC11_SOURCE is defined, but
* MingW does not support aligned_alloc despite of this, it uses the
* the _aligned_malloc as MSVC.
*
* The same issue is present on some Unix systems not providing
* posix_memalign.
*
* Note that clang and gcc with -std=c11 or -std=c99 will not define
* _POSIX_C_SOURCE and thus posix_memalign cannot be detected but
* aligned_alloc is not necessarily available either. We assume
* that clang always has posix_memalign although it is not strictly
* correct. For gcc, use -std=gnu99 or -std=gnu11 or don't use -std in
* order to enable posix_memalign, or live with the fallback until using
* a system where glibc has a version that supports aligned_alloc.
*
* For C11 compliant compilers and compilers with posix_memalign,
* it is valid to use free instead of aligned_free with the above
* caveats.
*/
Second question : According to the text above, I should have definition of aligned_free/aligned_malloc, but for some reason, I don't have it. Why ? What I'm missing ?
Additionnal information : LabWindows/CVI only accepte .lib as lib (no .a) so I had to compile flatcc using Cmake and MSVS19. I have try several configuration but nothing to do I always get the same error.
Best regard
EDIT : I fixed one undefined symbol '__allmul' by doing this cmake command :
cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=x86_64-w64-mingw32-c99 -DFLATCC_PORTABLE=true -DFLATCC_ALLOW_WERROR=false -DBUILD_TESTING=false -DFLATCC_CXX_TEST=false -DFLATCC_REFLECTION=false -B .
Then editing flatcc\src\compiler\CMakeFiles\flatcc.dir\flags.make and flatcc\src\runtime\CMakeFiles\flatcc.dir\flags.make
to looks like that : C_FLAGS = -m32 -DFLATCC_REFLECTION=0 -Wstrict-prototypes -Wsign-conversion -Wconversion -std=c99 -pedantic -Wall -Wextra -DFLATCC_PORTABLE
-m32 is for 32 bit binary and -std=c99 instead of -std=c11 (can't put c89 because flatcc contain some inline keyword)
Then editing flatcc\src\compiler\CMakeFiles\flatcc.dir\link.txt and flatcc\src\runtime\CMakeFiles\flatcc.dir\link.txt to look like this :
...\bin\clang\bin\ar.exe rc ..\..\..\lib\flatcc.lib CMakeFiles/flatcc.dir/__/__/external/hash/cmetrohash64.c.obj ...
...bin\clang\bin\ranlib.exe ..\..\..\lib\flatcc.lib
Then running Mingw32-make.exe
2 errors remain :
Could you try to compile flatcc as a static library and force the output as .lib instead of the (by default) .a (with the "-o flatcc.lib" flag)? The problem I guess is that you're using two different compilers here (msvc and clang), on the same plateform (win32), and clang by default could have a "unix way of doing things". ;)
But actually the important point here I guess is from this comment quote:
Note that clang and gcc with -std=c11 or -std=c99 will not define *
_POSIX_C_SOURCE and thus posix_memalign cannot be detected but * aligned_alloc is not necessarily available either. We assume * that
clang always has posix_memalign although it is not strictly *
correct.
Maybe simply try to compile flatcc with clang and with the "-std=c89" flag to avoid any problem.
Do:
cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=clang .
Then in the flatcc\src\compiler\CMakeFiles\flatcc.dir\flags.make file generated, you can change -std=c11 to -std=c89.
Then compile the project again with:
make
By default when I compile flatcc with mingw-32 on windows, I have the -std=c11 flag set (gcc version 7.3)
Well, to fix this issue, I had to compile flatcc Using clang in 32bit. To do this, I moved into flatcc directory and did :
cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=x86_64-w64-mingw32-c99 -DFLATCC_PORTABLE=true -DFLATCC_ALLOW_WERROR=false -DBUILD_TESTING=false -DFLATCC_CXX_TEST=false -DFLATCC_REFLECTION=false -DFLATCC_USE_GENERIC_ALIGNED_ALLOC -B .
Then edited flatcc\src\compiler\CMakeFiles\flatcc.dir\flags.make and flatcc\src\runtime\CMakeFiles\flatcc.dir\flags.make to add -m32 to C_FLAGS :
C_FLAGS = -m32 -DFLATCC_REFLECTION=0 -Wstrict-prototypes -Wsign-conversion -Wconversion -std=c11 -pedantic -Wall -Wextra -DFLATCC_PORTABLE -DFLATCC_USE_GENERIC_ALIGNED_ALLOC
Then changed flatcc\src\compiler\CMakeFiles\flatcc.dir\link.txt and flatcc\src\runtime\CMakeFiles\flatcc.dir\link.txt to look like this :
...\bin\clang\bin\ar.exe rc ..\..\..\lib\flatcc.lib CMakeFiles/flatcc.dir/__/__/external/hash/cmetrohash64.c.obj ...
...bin\clang\bin\ranlib.exe ..\..\..\lib\flatcc.lib
Note: I just changed name of .a generated to .lib
Then finally I run mingw32-make.exe (or make.exe)
Thanks to Victor Gallet

How to install latest glibc (version 2.29) beside system installed one & compile a program?

Based on This Stackoverflow link I downloaded & installed glibc v2.29 in "/usr/local/glibc" path of Linux OS. Then based on this Stackoverflow link I tried to compile This Example, But I got following errors.
First Try Command:
gcc -Wall -g -o main main.c -Wl,--rpath=/usr/local/glibc/lib -Wl,--dynamic-linker=/usr/local/glibc/lib/ld-linux-x86-64.so.2
First Try Error Log:
main.c:1:10: fatal error: threads.h: No such file or directory
#include <threads.h>
^~~~~~~~~~~
compilation terminated.
Second Try Command:
In second try, I am using "-I" & "-L" GCC command options.
gcc -Wall -g -I/usr/local/glibc/include -o main main.c -L/usr/local/glibc/lib -Wl,--rpath=/usr/local/glibc/lib -Wl,--dynamic-linker=/usr/local/glibc/lib/ld-linux-x86-64.so.2
Second Try Error Log:
/tmp/ccCNYemW.o: In function `main':
/home/.../main.c:14: undefined reference to `thrd_create'
/home/.../main.c:16: undefined reference to `thrd_join'
collect2: error: ld returned 1 exit status
So I don't know where is the problem. Please Help me.
First of all, don't put an alternate libc (or alternate version of your libc) in a path searched by the normal include and library search (both link-time and runtime library search) for your main system one. This is a recipe for disaster. Installing a different glibc in /usr/local/ does avoid clobbering your system one, but now you just have two installed in places where the same tools can see and use them.
To do this right, you really need a full separate toolchain (gcc, binutils) in some completely separate path (like ~/my_glibc_root/... or /opt/alt_glibc_root/...). I'm not sure if there's a recommended way to do this. The glibc build procedures in Linux From Scratch might be a good place to look for ideas. In theory it can be done in a single stage; I do that with musl libc in musl-cross-make by careful use of intermediate make rules in the gcc build system. But applying the same idea to glibc probably requires some extra care.
Second Try Command: In second try, I am using "-I" & "-L" GCC command options.
gcc -Wall -g -I/usr/local/glibc/include -o main main.c -L/usr/local/glibc/lib -Wl,--rpath=/usr/local/glibc/lib -Wl,--dynamic-linker=/usr/local/glibc/lib/ld-linux-x86-64.so.2
This command is almost correct. The thrd_create and thrd_join functions are defined in libpthread, which you didn't link against.
Add -pthread to your compile command, and the link should succeed.
P.S. R's advice of not installing alternate GLIBC into /usr/local is also a good one.

-lm doesnt work unless it's at the end of the command [duplicate]

This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 2 years ago.
Im currently writing a program for a uni asssessment and they have a set line to compile it, so if it doesn't work with that it won't be accepted.
They command they use is
gcc -Wall -ansi -lm program.c -o program.out
My program will not compile that way, and it'll give me a undefined referance error (Referring to my log10 using math.h library)
if i use:
gcc -Wall -ansi program.c -o program.out -lm
it works
What could be my issue?
Im using windows 10 64bit and have windows bash installed and gcc.
This would be explained if your instructors are using gold and you are using GNU ld. These are two linkers, both are part of the GNU project, and both are commonly used with GCC.
If you are using GNU ld, you get the "traditional" behavior:
The order of specifying the -L and -l options, and the order of specifying -l options with respect to pathname operands is significant.
This means that you have to put -lm after any object files and libraries that depend on it.
However, if you are using gold, the -l options may appear first.
If you have gold installed on your system, you can test it yourself.
Here is what I get:
$ gcc -lm program.c
/tmp/ccJmBjmd.o: In function `main':
program.c:(.text+0x15): undefined reference to `sin'
collect2: error: ld returned 1 exit status
But if I use gold, it works fine:
$ gcc -lm program.c -fuse-ld=gold
-lm needs to be at the end of the command, most likely in the first case with the literal the compiler is optimizing out the call to any function and therefore does not need to link against the library. This is called constant folding and for example we can see in the gcc docs on Other Built-in Functions Provided by GCC says:
GCC includes built-in versions of many of the functions in the
standard C library. The versions prefixed with __builtin_ are always
treated as having the same meaning as the C library function even if
you specify the -fno-builtin option. (see C Dialect Options) Many of
these functions are only optimized in certain cases; if they are not
optimized in a particular case, a call to the library function is
emitted.

Linking a C program directly with ld fails with undefined reference to `__libc_csu_fini`

I'm trying to compile a C program under Linux. However, out of curiosity, I'm trying to execute some steps by hand: I use:
the gcc frontend to produce assembler code
then run the GNU assembler to get an object file
and then link it with the C runtime to get a working executable.
Now I'm stuck with the linking part.
The program is a very basic "Hello world":
#include <stdio.h>
int main() {
printf("Hello\n");
return 0;
}
I use the following command to produce the assembly code:
gcc hello.c -S -masm=intel
I'm telling gcc to quit after compiling and dump the assembly code with Intel syntax.
Then I use th GNU assembler to produce the object file:
as -o hello.o hello.s
Then I try using ld to produce the final executable:
ld hello.o /usr/lib/libc.so /usr/lib/crt1.o -o hello
But I keep getting the following error message:
/usr/lib/crt1.o: In function `_start':
(.text+0xc): undefined reference to `__libc_csu_fini'
/usr/lib/crt1.o: In function `_start':
(.text+0x11): undefined reference to `__libc_csu_init'
The symbols __libc_csu_fini/init seem to be a part of glibc, but I can't find them anywhere! I tried linking against libc statically (against /usr/lib/libc.a) with the same result.
What could the problem be?
/usr/lib/libc.so is a linker script which tells the linker to pull in the shared library /lib/libc.so.6, and a non-shared portion, /usr/lib/libc_nonshared.a.
__libc_csu_init and __libc_csu_fini come from /usr/lib/libc_nonshared.a. They're not being found because references to symbols in non-shared libraries need to appear before the archive that defines them on the linker line. In your case, /usr/lib/crt1.o (which references them) appears after /usr/lib/libc.so (which pulls them in), so it doesn't work.
Fixing the order on the link line will get you a bit further, but then you'll probably get a new problem, where __libc_csu_init and __libc_csu_fini (which are now found) can't find _init and _fini. In order to call C library functions, you should also link /usr/lib/crti.o (after crt1.o but before the C library) and /usr/lib/crtn.o (after the C library), which contain initialisation and finalisation code.
Adding those should give you a successfully linked executable. It still won't work, because it uses the dynamically linked C library without specifying what the dynamic linker is. You'll need to tell the linker that as well, with something like -dynamic-linker /lib/ld-linux.so.2 (for 32-bit x86 at least; the name of the standard dynamic linker varies across platforms).
If you do all that (essentially as per Rob's answer), you'll get something that works in simple cases. But you may come across further problems with more complex code, as GCC provides some of its own library routines which may be needed if your code uses certain features. These will be buried somewhere deep inside the GCC installation directories...
You can see what gcc is doing by running it with either the -v option (which will show you the commands it invokes as it runs), or the -### option (which just prints the commands it would run, with all of the arguments quotes, but doesn't actually run anything). The output will be confusing unless you know that it usually invokes ld indirectly via one of its own components, collect2 (which is used to glue in C++ constructor calls at the right point).
I found another post which contained a clue: -dynamic-linker /lib/ld-linux.so.2.
Try this:
$ gcc hello.c -S -masm=intel
$ as -o hello.o hello.s
$ ld -o hello -dynamic-linker /lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o hello.o -lc /usr/lib/crtn.o
$ ./hello
hello, world
$
Assuming that a normal invocation of gcc -o hello hello.c produces a working build, run this command:
gcc --verbose -o hello hello.c
and gcc will tell you how it's linking things. That should give you a good idea of everything that you might need to account for in your link step.
In Ubuntu 14.04 (GCC 4.8), the minimal linking command is:
ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 \
/usr/lib/x86_64-linux-gnu/crt1.o \
/usr/lib/x86_64-linux-gnu/crti.o \
-L/usr/lib/gcc/x86_64-linux-gnu/4.8/ \
-lc -lgcc -lgcc_s \
hello.o \
/usr/lib/x86_64-linux-gnu/crtn.o
Although they may not be necessary, you should also link to -lgcc and -lgcc_s, since GCC may emit calls to functions present in those libraries for operations which your hardware does not implement natively, e.g. long long int operations on 32-bit. See also: Do I really need libgcc?
I had to add:
-L/usr/lib/gcc/x86_64-linux-gnu/4.8/ \
because the default linker script does not include that directory, and that is where libgcc.a was located.
As mentioned by Michael Burr, you can find the paths with gcc -v. More precisely, you need:
gcc -v hello_world.c |& grep 'collect2' | tr ' ' '\n'
This is how I fixed it on ubuntu 11.10:
apt-get remove libc-dev
Say yes to remove all the packages but copy the list to reinstall after.
apt-get install libc-dev
If you're running a 64-bit OS, your glibc(-devel) may be broken. By looking at this and this you can find these 3 possible solutions:
add lib64 to LD_LIBRARY_PATH
use lc_noshared
reinstall glibc-devel
Since you are doing the link process by hand, you are forgetting to link the C run time initializer, or whatever it is called.
To not get into the specifics of where and what you should link for you platform, after getting your intel asm file, use gcc to generate (compile and link) your executable.
simply doing gcc hello.c -o hello should work.
Take it:
$ echo 'main(){puts("ok");}' > hello.c
$ gcc -c hello.c -o hello.o
$ ld hello.o -o hello.exe /usr/lib/crt1.o /usr/lib/crti.o /usr/lib/crtn.o \
-dynamic-linker /lib/ld-linux.so.2 -lc
$ ./hello.exe
ok
Path to /usr/lib/crt*.o will when glibc configured with --prefix=/usr

Undefined Symbol when compiled with -O2 only on Mac

I'm working on a library that must compile on linux and mac os X. Until now, I had no problem, compiling with "-g" worked well under both OS.
I tried to compile with some optimization ("-O2") and it works well under linux but I get an Undefined Symbol when I try to link a program with my library under mac os X.
Does anyone have any clue what I should look for?
nm mylib.a | grep _the_symbol
This returns same thing for linux and mac (no leading underscore under linux) :
154:00000018 C _the_symbol
377: U _the_symbol
Here is the compile line under linux for the program using the library:
/usr/bin/gcc -std=c99 CMakeFiles/prod-cons.dir/prod-cons.c.o -o prod-cons -rdynamic -L/home/claferri/dev/build/src ../src/libckaapi.a -lpthread -Wl,-rpath,/home/claferri/dev/build/src
And under mac :
/usr/bin/gcc -std=c99 -Wl,-search_paths_first -headerpad_max_install_names -fPIC CMakeFiles/prod-cons.dir/prod-cons.c.o -o prod-cons -L/Volumes/Data/claferri/Work/build/src ../src/libckaapi.a /usr/lib/libpthread.dylib
Here's a guess at a workaround: try building the library with the -fno-common flag. If you have multiple definitions of this variable, you'll need to add "extern" to all but one.
Note that the following is a guess, and I can't say for certain unless/until you provide the exact compiler flags you're using -- but Xcode defaults to setting -fvisibility=hidden, which would hide pretty much any symbol in your library, unless it's declared as visible.
You can do the same on Linux, but GCC's default is not to hide symbols.
You'll find more information here: http://gcc.gnu.org/wiki/Visibility

Resources