I'm using atomic<>
for the first time, and just as using <thread>
requires you to link a thread library, it seems like using <atomic>
wants you to do... something. What?
> uname -a
Linux sdclxd00239 3.10.0-693.11.6.el7.x86_64 #1 SMP Thu Dec 28 14:23:39 EST 2017 x86_64 x86_64 x86_64 GNU/Linu
> g++ Foo.cxx -g -o MsgQueueNoLock -pthread
/tmp/ccnGOKUG.o: In function `std::atomic<Ptr_T>::store(Ptr_T, std::memory_order)':
/opt/rh/devtoolset-7/root/usr/include/c++/7/atomic:239: undefined reference to `__atomic_store_16'
/tmp/ccnGOKUG.o: In function `std::atomic<Ptr_T>::load(std::memory_order) const':
/opt/rh/devtoolset-7/root/usr/include/c++/7/atomic:250: undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status>
g++ Foo.cxx -g -o Foo -pthread
/tmp/ccnGOKUG.o: In function `std::atomic<Ptr_T>::store(Ptr_T, std::memory_order)':
/opt/rh/devtoolset-7/root/usr/include/c++/7/atomic:239: undefined reference to `__atomic_store_16'
/tmp/ccnGOKUG.o: In function `std::atomic<Ptr_T>::load(std::memory_order) const':
/opt/rh/devtoolset-7/root/usr/include/c++/7/atomic:250: undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status
UPDATE: I need to use -latomic
. Fair enough! However I can't find one I can actually use.
First I look under /usr/lib
, and I see I have a simlink under gcc/.../4.8.2
pointing to gcc/.../4.8.5
?!!? I've never in my life seen an old version depend on a new version though the timestamp causes me to suspect either manual intervention by someone in the past, or a complicated history.
> l `find /usr/lib -name '*atomic*'`
-rw-r--r--. 2 root root 1379 Jul 13 2017 /usr/lib/python2.7/site-packages/sos/plugins/atomichost.pyo
-rw-r--r--. 2 root root 1379 Jul 13 2017 /usr/lib/python2.7/site-packages/sos/plugins/atomichost.pyc
-rw-r--r--. 1 root root 1672 Jul 13 2017 /usr/lib/python2.7/site-packages/sos/plugins/atomichost.py
-rw-r--r-- 1 root root 40 Sep 22 2017 /usr/lib/gcc/x86_64-redhat-linux/4.8.2/libatomic.so
-rw-r--r-- 1 root root 38 Sep 22 2017 /usr/lib/gcc/x86_64-redhat-linux/4.8.2/32/libatomic.so
lrwxrwxrwx 1 root root 44 Jul 3 2018 /usr/lib/gcc/x86_64-redhat-linux/4.8.2/32/libatomic.a -> ../../../i686-redhat-linux/4.8.5/libatomic.a
Something on the 'net suggested I might find joy under /usr/local/lib
but in fact joy is not to be found:
> find /usr/local/lib -name '*atomic*'
>
The gcc actually installed is old (4.8.5) and I'm running 7.2.1 via the scl utility, which puts /opt/rh/devtoolset-7/root/usr/bin/gcc
into the path. Anticipating that the requisite lib was probably delivered with the gcc, I look at /opt/rh/devtoolset-7
... and like a bad dream the libatomic.a again is a symlink to a non-existent file.
> l `find /opt/rh/devtoolset-7/ -name '*atomic*'`
:
(headers elided)
:
-rw-r--r-- 1 root root 40975 Aug 31 2017 /opt/rh/devtoolset-7/root/usr/include/c++/7/atomic
-rw-r--r-- 1 root root 80 Aug 31 2017 /opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/32/libatomic.so
-rw-r--r-- 1 root root 1553 Oct 6 2017 /opt/rh/devtoolset-7/root/usr/share/systemtap/tapset/linux/atomic.stp
lrwxrwxrwx 1 root root 40 Jul 3 2018 /opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/32/libatomic.a -> ../../../i686-redhat-linux/7/libatomic.a
So using -L
options with every path I can think of based on what find
found, here's all the errors:
> g++ MsgQueueNoLock.cxx -g -o MsgQueueNoLock -pthread -latomic
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: cannot find -latomic
collect2: error: ld returned 1 exit status
> g++ MsgQueueNoLock.cxx -g -o MsgQueueNoLock -pthread -L/usr/lib/gcc/x86_64-redhat-linux/4.8.2 -latomic
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: cannot find /usr/lib64/libatomic.so.1.0.0
collect2: error: ld returned 1 exit status
> g++ MsgQueueNoLock.cxx -g -o MsgQueueNoLock -pthread -L/usr/lib/gcc/x86_64-redhat-linux/4.8.2/32 -latomic
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: cannot find /usr/lib/libatomic.so.1.0.0
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/4.8.2/32/libstdc++.so when searching for -lstdc++
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/4.8.2/32/libgcc_s.so when searching for -lgcc_s
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: skipping incompatible /usr/lib/gcc/x86_64-redhat-linux/4.8.2/32/libgcc.a when searching for libgcc.a
collect2: error: ld returned 1 exit status
> g++ MsgQueueNoLock.cxx -g -o MsgQueueNoLock -pthread -L/opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/32 -latomic
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: skipping incompatible /opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/32/libatomic.so when searching for -latomic
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: cannot find -latomic
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: skipping incompatible /opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/32/libstdc++.so when searching for -lstdc++
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: skipping incompatible /opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/32/libgcc_s.so when searching for -lgcc_s
/opt/rh/devtoolset-7/root/usr/libexec/gcc/x86_64-redhat-linux/7/ld: skipping incompatible /opt/rh/devtoolset-7/root/usr/lib/gcc/x86_64-redhat-linux/7/32/libgcc.a when searching for libgcc.a
collect2: error: ld returned 1 exit status
There is a sample libatomic.c implementation here: https://gcc.gnu.org/wiki/Atomic/GCCMM?action=AttachFile&do=view&target=libatomic.c Its compilation produces several warnings but ultimately produces an object file.
> gcc -c -o libatomic.o libatomic.c
libatomic.c:475:1: warning: conflicting types for built-in function '__atomic_compare_exchange_1' [-Wbuiltin-declaration-mismatch]
__atomic_compare_exchange_ ## SIZE (I ## SIZE *mem, I ## SIZE *expect, I ## SIZE desired, int success, int failure) \
^
libatomic.c:524:1: note: in expansion of macro 'ATOMIC_COMPARE_EXCHANGE'
ATOMIC_COMPARE_EXCHANGE (1)
^~~~~~~~~~~~~~~~~~~~~~~
libatomic.c:475:1: warning: conflicting types for built-in function '__atomic_compare_exchange_2' [-Wbuiltin-declaration-mismatch]
__atomic_compare_exchange_ ## SIZE (I ## SIZE *mem, I ## SIZE *expect, I ## SIZE desired, int success, int failure) \
^
libatomic.c:537:1: note: in expansion of macro 'ATOMIC_COMPARE_EXCHANGE'
ATOMIC_COMPARE_EXCHANGE (2)
^~~~~~~~~~~~~~~~~~~~~~~
libatomic.c:475:1: warning: conflicting types for built-in function '__atomic_compare_exchange_4' [-Wbuiltin-declaration-mismatch]
__atomic_compare_exchange_ ## SIZE (I ## SIZE *mem, I ## SIZE *expect, I ## SIZE desired, int success, int failure) \
^
libatomic.c:551:1: note: in expansion of macro 'ATOMIC_COMPARE_EXCHANGE'
ATOMIC_COMPARE_EXCHANGE (4)
^~~~~~~~~~~~~~~~~~~~~~~
libatomic.c:475:1: warning: conflicting types for built-in function '__atomic_compare_exchange_8' [-Wbuiltin-declaration-mismatch]
__atomic_compare_exchange_ ## SIZE (I ## SIZE *mem, I ## SIZE *expect, I ## SIZE desired, int success, int failure) \
^
libatomic.c:565:1: note: in expansion of macro 'ATOMIC_COMPARE_EXCHANGE'
ATOMIC_COMPARE_EXCHANGE (8)
^~~~~~~~~~~~~~~~~~~~~~~
libatomic.c:475:1: warning: conflicting types for built-in function '__atomic_compare_exchange_16' [-Wbuiltin-declaration-mismatch]
__atomic_compare_exchange_ ## SIZE (I ## SIZE *mem, I ## SIZE *expect, I ## SIZE desired, int success, int failure) \
^
libatomic.c:579:1: note: in expansion of macro 'ATOMIC_COMPARE_EXCHANGE'
ATOMIC_COMPARE_EXCHANGE (16)
^~~~~~~~~~~~~~~~~~~~~~~
> ar rcs libatomic.a libatomic.o
> g++ Foo.cxx -g -o Foo-pthread -L. -latomic
Linking success: binary is created without error. My application is too partially-written to judge whether it actually works though.
Even if this works, it's pretty clearly "not what you're supposed to have to do to get it to work." So I'm not marking this as "the" answer, just leaving it for future reference.