library is linked but reference is undefined
From the gcc
man page:
-llibrary
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o
-lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified
precisely by name.
So try to specify the -lOpenCL
after the file argument in your compile command.
You also search for symbols in libOpenCL.so, which is a shared library file. With your command you link your program agains a static library, in the format libOpenCL.a
.
`ld` undefined reference error, but libraries are linked to by CMake and symbols exist
Fix /h3>
The cause of the linker errors was this statement:
if(LINUX)
The fix was to replace it with this:
if(UNIX AND NOT APPLE)
This commit fixes the problem:
Reference: https://stackoverflow.com/a/40152725/3405291
Strangely, CMake wasn't complaining about anything and just throwing random linker errors.
Linking C++ to static library; undefined reference errors
The library libEAPI.a
contains object files compiled in C
, not C++
.
The symbols therefore have not been name-mangled and cannot serve to
resolve the name-mangled function references generated by your C++
code.
Run:
nm libEAPI.a | grep EApiFanDisable
and you will see no change.
Run:
nm main.o | grep EApiFanDisable
and you will see the mangled symbol, which is neither EApiFanDisable
nor EApiFanDisable()
but something more like _Z14EApiFanDisablev
, that the linker is actually trying
to resolve.
To avoid these linkage errors you must inform your C++ compiler, when it
compiles the header file(s) of libEAPI
, that the declarations therein have
external C linkage, so it will emit unmangled references to the symbols declared: like so:
main.cpp
...
extern "C" {
#include "EAPI.h" // or whatever
}
...
BTW, this commandline:
g++ -o secoTest -lpthread main.o libEAPI.a
will fail to link libpthread
on a Debian-based distro (Ubuntu et al)
more recent than Debian 6, as all libraries must be linked in dependency order since then:
g++ -o secoTest main.o libEAPI.a -lpthread
Even better, do not use the non-portable -lpthread
and pass the portable
option -pthread
for both compilation and linkage. It means: Do whatever
is right to compile/link with Posix Threads support
How is linking failing: Undefined reference to library
You need to link the libraries in the right order - it sounds like Utilities.a needs to be linked last. I don't know how you do that in Qt but that's what you need to achieve.
Undefined references even though library is linking and it contains correct symbols
The fact that linker reports unresolved external symbols as ptp_usb_sendreq(_PTPParams*, _PTPContainer*)
means that those symbols are mangled in C++ way (otherwise, function arguments would not be visible).
At the same time, nm
reports the symbol as ptp_usb_sendreq
, which means, it is not mangled.
Most likely solution: check and make sure your function signature (likely in a header file) is wrapped in extern "C"
specifier.
Undefined reference to functions while linking to static library
do I need to include X.a only or do I need to include both libaries to my code?
You don't "include" libraries in your code, you link them in.
When you link against X.a
, the linker copies used parts of the library into your executable.
When you link against a.so
, the linker makes a note that a.so
is required at runtime, and (if you are using versioned symbols) which versions of symbols from a.so
must be present at runtime, but doesn't copy any code from a.so
into your executable. However, a.so
is still required on the link time.
There are ways to link an executable without a.so
, but they are best left to experts (there are too many possible gotcha's with that approach).
Undefined reference in transitive library linking
CMake has no issue with circular dependencies between static libraries. Just declare the actual dependencies and CMake will take care of the rest. Here is my revised CMakeLists.txt:
cmake_minimum_required(VERSION 3.22)
project(config)
set(CMAKE_CXX_STANDARD 11)
add_library(A STATIC A/A.cpp)
target_include_directories(A PUBLIC "${CMAKE_CURRENT_LIST_DIR}/A")
target_link_libraries(A PRIVATE B)
add_library(B STATIC B/B.cpp)
target_include_directories(B PUBLIC "${CMAKE_CURRENT_LIST_DIR}/B")
target_link_libraries(B PRIVATE A)
add_library(C STATIC C/C.cpp)
target_include_directories(C PUBLIC "${CMAKE_CURRENT_LIST_DIR}/C")
target_link_libraries(C PRIVATE B)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE C)
Using your exact sources, I can build and run like so:
$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release
...
$ cmake --build build --verbose
[1/8] /usr/bin/c++ -I/path/to/B -I/path/to/A -O3 -DNDEBUG -std=gnu++11 -MD -MT CMakeFiles/B.dir/B/B.cpp.o -MF CMakeFiles/B.dir/B/B.cpp.o.d -o CMakeFiles/B.dir/B/B.cpp.o -c /path/to/B/B.cpp
[2/8] /usr/bin/c++ -I/path/to/A -I/path/to/B -O3 -DNDEBUG -std=gnu++11 -MD -MT CMakeFiles/A.dir/A/A.cpp.o -MF CMakeFiles/A.dir/A/A.cpp.o.d -o CMakeFiles/A.dir/A/A.cpp.o -c /path/to/A/A.cpp
[3/8] : && /usr/bin/cmake -E rm -f libB.a && /usr/bin/ar qc libB.a CMakeFiles/B.dir/B/B.cpp.o && /usr/bin/ranlib libB.a && :
[4/8] : && /usr/bin/cmake -E rm -f libA.a && /usr/bin/ar qc libA.a CMakeFiles/A.dir/A/A.cpp.o && /usr/bin/ranlib libA.a && :
[5/8] /usr/bin/c++ -I/path/to/C -O3 -DNDEBUG -std=gnu++11 -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /path/to/main.cpp
[6/8] /usr/bin/c++ -I/path/to/C -I/path/to/B -O3 -DNDEBUG -std=gnu++11 -MD -MT CMakeFiles/C.dir/C/C.cpp.o -MF CMakeFiles/C.dir/C/C.cpp.o.d -o CMakeFiles/C.dir/C/C.cpp.o -c /path/to/C/C.cpp
[7/8] : && /usr/bin/cmake -E rm -f libC.a && /usr/bin/ar qc libC.a CMakeFiles/C.dir/C/C.cpp.o && /usr/bin/ranlib libC.a && :
[8/8] : && /usr/bin/c++ -O3 -DNDEBUG CMakeFiles/main.dir/main.cpp.o -o main libC.a libB.a libA.a libB.a libA.a && :
$ ./build/main
Config ID: 2
As you can see, the final link line produces C B A B A
. The latter two don't hurt anything since they'll never actually be searched.
If you want to break the cycle, you can break off the part of B that A needs into another library and make both of them depend on it.
Now I have the following files:
// A/A.cpp
#include "common.hpp"
Config MY_CONFIG = {
.id=2
};
// common/common.hpp
typedef struct Config {
int id;
} Config;
// B/B.cpp
#include "B.hpp"
#include "common.hpp"
extern Config MY_CONFIG;
int get_config_id () {
Config work = MY_CONFIG;
return work.id;
}
// B/B.hpp
int get_config_id ();
The build is then adjusted like so:
cmake_minimum_required(VERSION 3.22)
project(config)
set(CMAKE_CXX_STANDARD 11)
add_library(common INTERFACE)
target_include_directories(common INTERFACE "${CMAKE_CURRENT_LIST_DIR}/common")
add_library(A STATIC A/A.cpp)
target_include_directories(A PUBLIC "${CMAKE_CURRENT_LIST_DIR}/A")
target_link_libraries(A PRIVATE common)
add_library(B STATIC B/B.cpp)
target_include_directories(B PUBLIC "${CMAKE_CURRENT_LIST_DIR}/B")
target_link_libraries(B PRIVATE common A)
add_library(C STATIC C/C.cpp)
target_include_directories(C PUBLIC "${CMAKE_CURRENT_LIST_DIR}/C")
target_link_libraries(C PRIVATE B)
add_executable(main main.cpp)
target_link_libraries(main PRIVATE C)
and when we build, we see that the link order is correct and the duplicated libraries have disappeared:
$ cmake --build build --verbose
[1/8] /usr/bin/c++ -I/path/to/A -I/path/to/common -O3 -DNDEBUG -std=gnu++11 -MD -MT CMakeFiles/A.dir/A/A.cpp.o -MF CMakeFiles/A.dir/A/A.cpp.o.d -o CMakeFiles/A.dir/A/A.cpp.o -c /path/to/A/A.cpp
[2/8] /usr/bin/c++ -I/path/to/B -I/path/to/common -I/path/to/A -O3 -DNDEBUG -std=gnu++11 -MD -MT CMakeFiles/B.dir/B/B.cpp.o -MF CMakeFiles/B.dir/B/B.cpp.o.d -o CMakeFiles/B.dir/B/B.cpp.o -c /path/to/B/B.cpp
[3/8] : && /usr/bin/cmake -E rm -f libA.a && /usr/bin/ar qc libA.a CMakeFiles/A.dir/A/A.cpp.o && /usr/bin/ranlib libA.a && :
[4/8] : && /usr/bin/cmake -E rm -f libB.a && /usr/bin/ar qc libB.a CMakeFiles/B.dir/B/B.cpp.o && /usr/bin/ranlib libB.a && :
[5/8] /usr/bin/c++ -I/path/to/C -O3 -DNDEBUG -std=gnu++11 -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /path/to/main.cpp
[6/8] /usr/bin/c++ -I/path/to/C -I/path/to/B -O3 -DNDEBUG -std=gnu++11 -MD -MT CMakeFiles/C.dir/C/C.cpp.o -MF CMakeFiles/C.dir/C/C.cpp.o.d -o CMakeFiles/C.dir/C/C.cpp.o -c /path/to/C/C.cpp
[7/8] : && /usr/bin/cmake -E rm -f libC.a && /usr/bin/ar qc libC.a CMakeFiles/C.dir/C/C.cpp.o && /usr/bin/ranlib libC.a && :
[8/8] : && /usr/bin/c++ -O3 -DNDEBUG CMakeFiles/main.dir/main.cpp.o -o main libC.a libB.a libA.a && :
**Undefined reference** error while linking two libraries referring to one-another
Libraries must be listed in the order their symbols are needed.
The command cc $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LIBDIRS) -lfunc2 -lfunc1
tells the linker to first use the func2
library to resolve any pending references in the executable it is building and then to use the func1
library.
Since the linker processes func2
first, and, at the time it does so, there is no pending reference to print2
, the linker does not include the module with print2
in the executable.
Later, when the linker is processing func1
, it includes the module with print1
in the executable because main
uses it. That module print1
uses print2
, so including that module adds a new reference to print2
. Then, when the linker is done processing func1
, it has an unresolved reference. The linker does not go back to func2
to check it again.
Since the func1
library depends on func2
, change the link command to cc $(CFLAGS) -o $(TARGET) $(OBJFILES) $(LIBDIRS) -lfunc1 -lfunc2
.
(If the func2
library also depends on func1
, that is a bad design and should be reconsidered. If it is not changed, asking the linker to reconsider the libraries multiple times, as with -lfunc1 -lfunc2 -lfunc1
, might fix the immediate problem, but others can arise.)
Related Topics
Creating Library with Backward Compatible Abi That Uses Boost
Error::Make_Unique Is Not a Member of 'Std'
Calling a Constructor to Re-Initialize Object
How to Make the Map::Find Operation Case Insensitive
Does an R Compiler to C/C++ Exist
How to Build Boost Version 1.58.0 Using Visual Studio 2015 (Enterprise)
Is 1.0 a Valid Output from Std::Generate_Canonical
Static VS Non-Static Variables in Namespace
Conversion from Boost::Shared_Ptr to Std::Shared_Ptr
C++ Template Class; Function with Arbitrary Container Type, How to Define It
C++ Metafunction to Determine Whether a Type Is Callable
Switch "Transfer of Control Bypasses Initialization Of:" When Calling a Function
Template Parameter Packs Access Nth Type and Nth Element
List of C++ Name Resolution (And Overloading) Rules
What Is the Branch in the Destructor Reported by Gcov
Static and Dynamic/Shared Linking with Mingw
Why the Libc++ Std::Vector Internally Keeps Three Pointers Instead of One Pointer and Two Sizes