When I’m compiling openvswitch-1.5.0, I’ve encountered the following compile error:
gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith
-Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init -g -O2 -export-dynamic ***-lpthread*** -o utilities/ovs-dpctl utilities/ovs-dpctl.o lib/libopenvswitch.a
/home/jyyoo/src/dpdk/build/lib/librte_eal.a
/home/jyyoo/src/dpdk/build/lib/libethdev.a
/home/jyyoo/src/dpdk/build/lib/librte_cmdline.a
/home/jyyoo/src/dpdk/build/lib/librte_hash.a
/home/jyyoo/src/dpdk/build/lib/librte_lpm.a
/home/jyyoo/src/dpdk/build/lib/librte_mbuf.a
/home/jyyoo/src/dpdk/build/lib/librte_ring.a
/home/jyyoo/src/dpdk/build/lib/librte_mempool.a
/home/jyyoo/src/dpdk/build/lib/librte_malloc.a -lrt -lm
/usr/bin/ld: /home/jyyoo/src/dpdk/build/lib/librte_eal.a(eal.o): undefined reference
to symbol 'pthread_create@@GLIBC_2.2.5'
/lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from
command line
If I try to see the symbols of libpthread
, it looks fine.
$ readelf -s /lib/x86_64-linux-gnu/libpthread.so.0 | grep pthread_create
199: 0000000000008220 2814 FUNC GLOBAL DEFAULT 13 pthread_create@@GLIBC_2.2.5
173: 0000000000008220 2814 FUNC LOCAL DEFAULT 13 __pthread_create_2_1
462: 0000000000008220 2814 FUNC GLOBAL DEFAULT 13 pthread_create@@GLIBC_2.2
Could you give any hints or pointers?
jww
97.9k91 gold badges413 silver badges887 bronze badges
asked Nov 11, 2013 at 8:33
4
You should mention the library on the command line after the object files being compiled:
gcc -Wstrict-prototypes -Wall -Wno-sign-compare -Wpointer-arith -Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init \
-g -O2 -export-dynamic -o utilities/ovs-dpctl utilities/ovs-dpctl.o \
lib/libopenvswitch.a \
/home/jyyoo/src/dpdk/build/lib/librte_eal.a /home/jyyoo/src/dpdk/build/lib/libethdev.a /home/jyyoo/src/dpdk/build/lib/librte_cmdline.a /home/jyyoo/src/dpdk/build/lib/librte_hash.a /home/jyyoo/src/dpdk/build/lib/librte_lpm.a /home/jyyoo/src/dpdk/build/lib/librte_mbuf.a /home/jyyoo/src/dpdk/build/lib/librte_ring.a /home/jyyoo/src/dpdk/build/lib/librte_mempool.a /home/jyyoo/src/dpdk/build/lib/librte_malloc.a \
-lrt -lm -lpthread
Explanation: the linking is dependent on the order of modules. Symbols are first requested, and then linked in from a library that has them. So you have to specify modules that use libraries first, and libraries after them. Like this:
gcc x.o y.o z.o -la -lb -lc
Moreover, in case there’s a circular dependency, you should specify the same library on the command line several times. So in case libb
needs symbol from libc
and libc
needs symbol from libb
, the command line should be:
gcc x.o y.o z.o -la -lb -lc -lb
answered Nov 11, 2013 at 11:53
Michael PankovMichael Pankov
3,5912 gold badges23 silver badges31 bronze badges
2
Background
The DSO missing from command line
message will be displayed when the linker does not find the required symbol with it’s normal search but the symbol is available in one of the dependencies of a directly specified dynamic library.
In the past the linker considered symbols in dependencies of specified languages to be available. But that changed in some later version and now the linker enforces a more strict view of what is available. The message thus is intended to help with that transition.
What to do?
If you are the maintainer of the software
You should solve this problem by making sure that all libraries that are needed to satisfy the needed symbols are directly specified on the linker command line. Also keep in mind that order often matters.
If you are just trying to compile the software
As a workaround it’s possible to switch back to the more permissive view of what symbols are available by using the option -Wl,--copy-dt-needed-entries
. Put this option before the linked libraries, like g++ main.cc -Wl,--copy-dt-needed-entries -ltensorflow
Common ways to inject this into a build are to export LDFLAGS before running configure
or similar like this:
export LDFLAGS="-Wl,--copy-dt-needed-entries"
Sometimes passing LDFLAGS="-Wl,--copy-dt-needed-entries"
directly to make
might also work.
answered Mar 10, 2019 at 10:18
textshelltextshell
1,75614 silver badges21 bronze badges
5
The error message depends on distribution / compiler version:
Ubuntu Saucy:
/usr/bin/ld: /mnt/root/ffmpeg-2.1.1//libavformat/libavformat.a(http.o): undefined reference to symbol 'inflateInit2_'
/lib/x86_64-linux-gnu/libz.so.1: error adding symbols: DSO missing from command line
Ubuntu Raring: (more informative)
/usr/bin/ld: note: 'uncompress' is defined in DSO /lib/x86_64-linux-gnu/libz.so.1 so try adding it to the linker command line
Solution: You may be missing a library in your compilation steps, during the linking stage. In my case, I added ‘-lz’ to makefile / GCC flags.
Background: DSO is a dynamic shared object or a shared library.
answered Nov 26, 2013 at 0:34
KevinKevin
2,7691 gold badge27 silver badges32 bronze badges
5
I found another case and therefore I thing you are all wrong.
This is what I had:
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/ld: eggtrayicon.o: undefined reference to symbol 'XFlush'
/usr/lib64/libX11.so.6: error adding symbols: DSO missing from command line
The problem is that the command line DID NOT contain -lX11
— although the libX11.so should be added as a dependency because there were also GTK and GNOME libraries in the arguments.
So, the only explanation for me is that this message might have been intended to help you, but it didn’t do it properly. This was probably simple: the library that provides the symbol was not added to the command line.
Please note three important rules concerning linkage in POSIX:
- Dynamic libraries have defined dependencies, so only libraries from the top-dependency should be supplied in whatever order (although after the static libraries)
- Static libraries have just undefined symbols — it’s up to you to know their dependencies and supply all of them in the command line
- The order in static libraries is always: requester first, provider follows. Otherwise you’ll get undefined symbol message, just like when you forgot to add the library to the command line
- When you specify the library with
-l<name>
, you never know whether it will takelib<name>.so
orlib<name>.a
. The dynamic library is preferred, if found, and static libraries only can be enforced by compiler option — that’s all. And whether you have any problems as above, it depends on whether you had static or dynamic libraries - Well, sometimes the dependencies may be lacking in dynamic libraries
answered Jul 14, 2016 at 13:34
EthourisEthouris
1,79113 silver badges18 bronze badges
3
I also encountered same problem. I do not know why, i just add -lpthread
option to compiler and everything ok.
Old:
$ g++ -rdynamic -m64 -fPIE -pie -o /tmp/node/out/Release/mksnapshot ...*.o *.a -ldl -lrt
got following error. If i append -lpthread
option to above command then OK.
/usr/bin/ld: /tmp/node/out/Release/obj.host/v8_libbase/deps/v8/src/base/platform/condition-variable.o: undefined reference to symbol 'pthread_condattr_setclock@@GLIBC_2.3.3'
//lib/x86_64-linux-gnu/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
answered Aug 29, 2016 at 16:43
osexp2000osexp2000
2,9101 gold badge30 silver badges29 bronze badges
1
I found I had the same error. I was compiling a code with both lapack and blas. When I switched the order that the two libraries were called the error went away.
«LAPACK_LIB = -llapack -lblas» worked where
«LAPACK_LIB = -lblas -llapack» gave the error described above.
answered Dec 17, 2013 at 19:30
2
If you are using CMake, there are some ways that you could solve it:
Solution 1: The most elegant one
add_executable(...)
target_include_directories(...)
target_link_libraries(target_name pthread)
Solution 2: using CMake find_package
find_package(Threads REQUIRED) # this will generate the flag for CMAKE_THREAD_LIBS_INIT
add_executable(...)
target_include_directories(...)
target_link_libraries(target_name ${CMAKE_THREAD_LIBS_INIT})
Solution 3: Change CMake flags
# e.g. with C++ 17, change to other version if you need
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -pthread")
answered Apr 21, 2020 at 15:02
biendltbbiendltb
1,1691 gold badge13 silver badges20 bronze badges
What I have found is that sometimes the library that the linker complains about is not the one causing the problem. Possibly there is a clever way to work out where the problem is but this is what I do:
- Comment out all the linked libraries in the link command.
- Clean out all .o’s, .so’s etc (Usually make clean is enough, but you may want to run a recursive find + rm, or something similar).
- Uncomment the libraries in the link command one at a time and re-arrange the order as necessary.
@peter karasev: I have come across the same problem with a gcc 4.8.2 cmake project on CentOS7. The order of the libraries in «target_link_libraries» section is important. I guess cmake just passes the list on to the linker as-is, i.e. it doesn’t try and work out the correct order. This is reasonable — when you think about it cmake can’t know what the correct order is until the linking is successfully completed.
answered Feb 5, 2015 at 9:31
AhrBAhrB
1111 silver badge3 bronze badges
Please add: CFLAGS="-lrt"
and LDFLAGS="-lrt"
Martin Evans
45.8k17 gold badges81 silver badges97 bronze badges
answered Apr 13, 2017 at 8:16
劉大為劉大為
1972 silver badges5 bronze badges
When working with code that uses mathematical functions, you should also link them.
In my Case when compiling I provided the following, which worked for me.
mpicc -o testname testname.c -lm
answered Jun 12, 2021 at 13:17
The same problem happened to me when I use distcc
to make my c++ project;
Finally I solved it with export CXX="distcc g++"
.
answered Feb 9, 2018 at 4:24
Jason GengJason Geng
591 silver badge8 bronze badges
Try to add -pthread
at the end of the library list in the Makefile.
It worked for me.
Ivan Aracki
4,86111 gold badges59 silver badges73 bronze badges
answered Nov 21, 2019 at 8:57
RickyRicky
791 silver badge8 bronze badges
if you are using cmake and used pthreads, try add the following lines
find_package(Threads)
target_link_libraries(${CMAKE_THREAD_LIBS_INIT})
answered Feb 1, 2020 at 14:56
bowman hanbowman han
1,09515 silver badges25 bronze badges
The same thing happened to me as I was installing the HPCC benchmark (includes HPL and a few other benchmarks). I added -lm
to the compiler flags in my build script and then it successfully compiled.
answered Dec 4, 2016 at 18:41
1
If using g++
, make sure that you are not running gcc
instead
answered Jun 21, 2018 at 22:46
Martin R.Martin R.
1,57417 silver badges16 bronze badges
2
Compile with g++ instead. It has worked in my case switching from gcc to g++.
answered Jul 2, 2021 at 15:34
alienflowalienflow
4007 silver badges19 bronze badges
The DSO missing from command line error happens when developers mention and include the specific library before the object. Therefore, the system displays an error message with different forms, but developers usually see the following statement: libz error adding symbols: DSO missing from command line CMake error.
As a result, our team wrote this extended article that includes several examples, solutions methods, and valuable tips on removing the DSO missing from command line ROS bug.
So, you will effortlessly remove this annoying mistake from your system when you finish reading all DSO missing from command line G++ chapters.
Contents
- What Causes the Common DSO Missing From Command Line Error?
- – Compiling Functions Causes a Mistake
- – Creating a Download Tar From a Home Page
- Fix the DSO Missing From Command Line Error: Several Solutions
- – Introducing the -Lpthread Option
- Conclusion
What Causes the Common DSO Missing From Command Line Error?
The DSO missing from the command line is caused when programmers and developers introduce and mention the specific library before the object. As a result, the system cannot initiate the intended command because the entity does not have a library for the data.
Unfortunately, this is not the only common culprit because this error can appear when developers fail to include a library in the compilation steps. Although this depends on the distribution’s version and compiler, it can occur when developers expect the least.
In addition, the command line error has different forms, so less experienced programmers should not worry if the entire error message differs from our example. We will show you three models that display the same error with different programs and versions.
For instance, the error may appear with the following structure:
libtbb so 2 error adding symbols: dso missing from command line
As you can tell, the final code line includes the generic mistake, but the beginning explains more about the version and possible causes. However, this bug can affect other versions and programs, as confirmed by the following example:
libc.so.6: error adding symbols: dso missing from command line
The system displays mistakes due to inadequate libraries or values, although developers may use different programs and elements.
Lastly, this error can have another form, as shown in the following message:
libgobject.0.so.0: error adding symbols: dso missing from command line
All error messages are common, but the actual bug can differ based on your script.
– Compiling Functions Causes a Mistake
The same error can appear when programmers compile several functions in a single script. For instance, they can include the commands and locations inside the element, but the system will display the mistake unless all values are correct.
Therefore, our experts suggest double-checking the script for compiling function errors that can ruin your programming experience. We will show you an example that specifies several locations, but be aware this may vary from your syntax.
Please look at the following example that compiles several functions:
-Wdeclaration-after-statement -Wformat-security -Wswitch-enum -Wunused-parameter -Wstrict-aliasing -Wbad-function-cast -Wcast-align -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-field-initializers -Wno-override-init -g -O2 -export-dynamic ***-lpthread*** -o utilities/ovs-dpctl utilities/ovs-dpctl.o lib/libopenvswitch.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_eal.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ libethdev.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_cmdline.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_hash.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_lpm.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_mbuf.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_ring.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_mempool.a
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_malloc.a -lrt -lm
/usr/ bin/ ld: /home /jyyoo/ src/ dpdk/ build/ lib/ librte_eal.a(eal.o): undefined reference
to symbol ‘pthread_create@@GLIBC_2.2.5’
/lib/ x86_64-linux-gnu/ libpthread.so.0: error adding symbols: DSO missing from
command line
As you can tell, the declarations appear correct and fully functional, but the program displays the error.
This happens when developers include the library before the objects and locations, as explained in the previous chapter. We will show you another example before explaining the debugging methods and solutions.
– Creating a Download Tar From a Home Page
Developers and programmers will experience the same error when creating a download tar from a home page. Tarring files from home pages requires following the instructions explicitly because the system must download the correct compiled data. However, an error might appear at some point when developers use J8 or J9 on Linux operating systems.
The following example captures the error when creating a download tar:
[ 85%] Linking CXX executable ../bin/ step-54.debug
/usr/ lib64/ gcc/ x86_64-suse-linux/ 7/../../../../x86_64-suse-linux/ bin/ ld: CMakeFiles/ step-59.debug.dir/ step-59/ step-59.cc.o: undefined reference to symbol ‘pthread_rwlock_unlock@@GLIBC_2.2.5’
/usr/ lib64/ gcc/ x86_64-suse-linux/ 7/../../../../x86_64-suse-linux/ bin/ ld: /usr/ lib64/ gcc/ x86_64-suse-linux/ 7/../../../../lib64/libpthread.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
make[2]: *** [examples/ CMakeFiles/ step-59.debug.dir/build.make:109: bin/step-59.debug] Error 1
make[1]: *** [CMakeFiles/ Makefile2:5808: examples/ CMakeFiles/ step-59.debug.dir/ all] Error 2
[ 85%] Built target step-54.debug
[ 85%] Built target obj_matrix_free_release
make: *** [Makefile:157: all] Error 2
This is the error developers will see when downloading the tar from a home page. However, the solutions are simple, as explained in the following chapters.
Fix the DSO Missing From Command Line Error: Several Solutions
You can fix the DSO error by mentioning the command line after the object files that developers compile to remove the error message. Beginners may need help locating the command line quickly. Introducing -lpthread option to the compiler is also used to fix this error.
Fortunately, our experts provide several examples that debug the error without affecting other primary and secondary functions. For instance, we will show you a script that fixes this article’s first error.
Refer to the following syntax to learn how to mention the command line after the object:
-p -O2 -export-dynamic -u utilities/ovs-dpctl utilities/ovs-dpctl.u \
lib/libopenvswitch.a \
/home/ jyyoo/ src/ dpdk/ build/ lib/ librte_eal.a / home/ jyyoo/ src/ dpdk/ build/ lib/ libethdev.a / home/ jyyoo/ src/ dpdk/ build/ lib/ librte_cmdline.a / home/ jyyoo/ src/ dpdk/ build/ lib/ librte_hash.a / home/ jyyoo/ src/ dpdk/ build/ lib/ librte_lpm.a / home/ jyyoo/ src/ dpdk/ build/ lib/ librte_mbuf.a / home/ jyyoo/ src/ dpdk/ build/ lib/ librte_ring.a / home/ jyyoo/ src/ dpdk/ build/ lib/ librte_mempool.a / home/ jyyoo/ src/ dpdk/ build/ lib/ librte_malloc.a \
-lrt -lm -lpthread
Programmers can copy and paste this script into their documents to debug the error, although they might need to change several values and tags.
Still, the command line appears after the object, a minor change that debugs the syntax and its functions. In addition, this article provides another solution for the same error.
– Introducing the -Lpthread Option
Another standard solution for the same error is introducing the -lpthread option to the compiler. This debugs the mistake because the command has a new link used by the system to locate the missing command line.
Although your values and commands will differ, we suggest introducing the -lpthread option above the original location.
Doing this is not complicated, as confirmed in the next example:
//lib/ x86_64-linux-gnu/ libpthread.so.0: error adding symbols: -lpthread enabling the function
collect2: error: ld returned 1 exit status
We kept the syntax short to help less experienced developers quickly follow the changes. Therefore, we are confident you will overcome all obstacles for the missing command line error.
Conclusion
Debugging annoying mistakes in your document is sometimes challenging, as confirmed by the missing command line error. However, our experts explained several terms summarized in the following bullet list:
- The missing command line error usually appears when developers and programmers mention the library before the object
- The same command line error has several forms and locations with similar elements and tags
- Our experts suggest introducing the library after the object to debug your script and its functions
- Programmers can use alternative solutions to fix the mistake by including a backup option
- Our experts suggest double-checking your syntax before writing the commands because you can ruin other elements
The command line error can affect all operating systems and versions because developers use the same command. However, you no longer have to worry because by following this profound guide, you can get rid of this error message efficiently.
- Author
- Recent Posts
Your Go-To Resource for Learn & Build: CSS,JavaScript,HTML,PHP,C++ and MYSQL. Meet The Team
Coding has become far simpler these days as compared to what it used to be with languages like C and even Assembly requiring programmers to put in a lot of time and study to get up to speed. However, as easy as programming has become with modern languages, there are still random bugs and glitches that keep popping up from time to time.
In this article, we’re talking about the “error adding symbols: DSO missing from command line” issue, the reasons behind it and what you can do to fix the problem.
Also read: Fix: Panic: Runtime error: Invalid memory address or nil pointer dereference
The issue generally occurs when the linker can’t find the required symbol with its normal search but the symbol is otherwise available in one or more dependencies of a mentioned dynamic library. This means that mentioning a specific library before the object doesn’t allow the system to initiate the intended command as the entity doesn’t have a library for the data.
Other common causes include:
- Syntax issues or other bugs in code
- Library isn’t included in compilation steps
How to fix the error adding symbols: DSO missing from command line issue?
Based on whether you’re a maintainer or just trying to compile or run the software, there are different approaches to the problem.
If you’re a software maintainer
Really the only thing you can do in such scenarios is to ensure that all libraries required to successfully compile the program are directly specified in the linker command line or are bundled with the package otherwise. Do keep in mind that the order in which the libraries are mentioned can also matter here.
If you’re trying to compile or run a program
If you’re just trying to compile or run a program, the first step is checking the program dependencies and making sure that you have the compilation environment set up properly. Once again, the order in which the libraries are mentioned can also come into play here so you might have to experiment with different orders based on when you’re referencing the library in your code.
Another common way of injecting this into a build is to either use lpthreads or ldflags before building the program as follows.
export LDFLAGS="-Wl,--copy-dt-needed-entries"
The aforementioned command can allow for a more permissive view of what symbols or libraries are available to the compiler and hence avoid the issue.
Also read: Fix: Unknown error: soap-error: encoding: object has no uirequestid property
I’m trying to compile tutorial 01 from enter link description herehttp://dranger.com/ffmpeg/tutorial01.html
copy pasted the code from here: http://dranger.com/ffmpeg/tutorial01.c
tried to compile (on linux) like the tutorial said with:
gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lswscale -lz
and got an error
: /usr/bin/ld: /tmp/ccIT5t82.o: undefined reference to symbol 'av_malloc@@LIBAVUTIL_51'
/usr/lib/i386-linux-gnu/libavutil.so.51: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
any suggestions?
- linux
- gcc
- ffmpeg
asked Aug 10, 2015 at 12:32
ben marderben marder
1051 silver badge7 bronze badges
1 Answer
You forgot to link avutil library, Please add -lavutil while compiling code.
gcc -o tutorial01 tutorial01.c -lavformat -lavcodec -lswscale -lz -lavutil
answered Aug 10, 2015 at 13:08
Rahul R DhobiRahul R Dhobi
5,6681 gold badge29 silver badges39 bronze badges
1
-
added , and now have : /tmp/ccIskNE0.o: In function
main': tutorial1.c:(.text+0x501): undefined reference to
avcodec_free_frame’ tutorial1.c:(.text+0x50d): undefined reference to `avcodec_free_frame’ collect2: error: ld returned 1 exit statusAug 10, 2015 at 13:22
Back when I was coding in C, I found a very strange problem: the ld
library has been linked in the plug-in loader, but when the application is linked to the plug-in loader, it still needs to link ld
explicitly. Otherwise, it will report: DSO missing from command line
. It means the dynamic library is not specified on the command line.
/usr/bin/ld: /tmp/ccDQXTKy.o: undefined reference to symbol '_Z5funB2v'
.//libB.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Code language: JavaScript (javascript)
The DSO missing from command line
message will be shown when the linker can’t find the required symbol with its normal search, but the symbol is available in one of the dependencies of a directly specified dynamic library.
In the past, the linker thought that symbols in languages that depended on other languages were available. But in a later version, that changed, and now the linker has a stricter view of what is available. So, the message is meant to help with this change.
Reproduce the error
Let’s take a look at an example: When linking an executable file, it depends on libA.so
, and libA.so
depends on libB.so
, and the function in libB.so
is directly called in the executable file, then the link An error will occur
.
libA.so
is explicitly linked to libB.so
during the compilation process. The executable file uses the function of libB.so
, binuntils version ≥ 2.22.
Not much to say , let’s take a look at the code that can reproduce the problem
Below is the source code of libB.so
:
#include <stdio.h>
int funB1(){
printf("in funB1");
return 0;
}
libB.so
int funB2(){
printf("in funB2");
return 0;
}
Code language: PHP (php)
There are two functions: funB1
and funB2
.
The funB1
function will be called by libA
, and the funB2
will be called by the executable file.
Now we compile libB.so
:
gcc libB.cpp -fPIC -shared -o libB.so
Code language: CSS (css)
Below is the source code of libA.so
:
#include <stdio.h>
int funB1();
int funA1(){
printf("in funA1 \n");
funB1();
return 0;
}
Code language: PHP (php)
There is only one function funA1
in this library, which calls funB1
function in libB
. And this function will then be called by the executable file.
Compile libA.so
:
$ gcc libA.cpp -fPIC -shared -o libA.so -Wl,-rpath=./ -L./ -lB
Below is the source code of main.cpp
:
int funA1();
int funB2();
int main(){
funA1();
funB2();
return 0;
}
Code language: JavaScript (javascript)
Compile main.cpp: (compilation method to reproduce the error)
gcc main.cpp -L./ -lA
When we compiled main.cpp
using gcc main.cpp -L./ -lA
, the DSO missing from command line
error will be printed out.
/usr/bin/ld: /tmp/ccDQXTKy.o: undefined reference to symbol '_Z5funB2v'
.//libB.so: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Code language: JavaScript (javascript)
Let’s use the following command to see if libA.so
specify to use libB.so
.
$ ldd libA.so
The output contains some useful information:
linux-vdso.so.1 => (0x00007ffd09def000)
libB.so => ./libB.so (0x00007fc513d7d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc5139b3000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc514181000)
Code language: PHP (php)
Obviously libA.so
has explicitly indicated that I want to rely on libB.so
, so why did libA.so
be linked when compiling main.cpp
, but GCC also asked us to explicitly link libB.so
?
The answer is simple, that is, GCC just wants you to link it explicitly.
Since binutils version 2.22, if you use functions in the dynamic library that you depend on, you must also explicitly specify the dynamic library on which the dynamic library you depend depends on.
In fact, this is binutils
after version 2.22, with the --no-copy-dt-needed-entries
option turned on by default. When this option is enabled, the compiler will not recursively fetch dependencies that depend on dynamic libraries when linking, so the above problem occurs.
Below is the help message on --no-copy-dt-needed-entries
:
--copy-dt-needed-entries
--no-copy-dt-needed-entries
This option affects the treatment of dynamic libraries referred to by DT_NEEDED tags inside ELF dynamic libraries mentioned on the command line. Normally the linker won't add a DT_NEEDED
tag to the output binary for each library mentioned in a DT_NEEDED tag in an input dynamic library. With --copy-dt-needed-entries specified on the command line however any dynamic
libraries that follow it will have their DT_NEEDED entries added. The default behaviour can be restored with --no-copy-dt-needed-entries.
This option also has an effect on the resolution of symbols in dynamic libraries. With --copy-dt-needed-entries dynamic libraries mentioned on the command line will be recursively
searched, following their DT_NEEDED tags to other libraries, in order to resolve symbols required by the output binary. With the default setting however the searching of dynamic
libraries that follow it will stop with the dynamic library itself. No DT_NEEDED links will be traversed to resolve symbols.
This roughly means that libraries that follow --no-copy-dt-needed-entries
do not traverse their dependencies, and the opposite is true for --no-copy-dt-needed-entries
. That is, using the following command to compile the main.cpp
can avoid this problem.
$ gcc main.cpp -L./ -Wl,--copy-dt-needed-entries -lA
Alternatively, you can use the option -Wl,--copy-dt-needed-entries
to allow a more permissive view of symbols.
Common ways to inject this into a build are to export LDFLAGS
before running configure
:
export LDFLAGS="-Wl,--copy-dt-needed-entries"
Code language: JavaScript (javascript)
We hope that the information above is useful and helped you successfully fix the DSO missing from command line
error message.
We’ve also written a few other guides on C programming, such as unistd.h on Windows and How to automatically indent your code in Visual Studio Code.
If you have any questions, then please feel free to ask in the comments below.