In the CMake I have:
target_link_libraries(${TESTNAME} ${CMAKE_DL_LIBS})
I think libdl.so is found because the linker does not complain that: " cannot find -lld".
Still, I get the error:
[ 50%] Linking CXX executable test1
/opt/poky/2.7.3/sysroots/x86_64-pokysdk-linux/usr/libexec/aarch64-poky-linux/gcc/aarch64-poky-linux/8.3.0/real-ld: /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libport.so: undefined reference to `dlopen'
/opt/poky/2.7.3/sysroots/x86_64-pokysdk-linux/usr/libexec/aarch64-poky-linux/gcc/aarch64-poky-linux/8.3.0/real-ld: /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libport.so: undefined reference to `dlclose'
/opt/poky/2.7.3/sysroots/x86_64-pokysdk-linux/usr/libexec/aarch64-poky-linux/gcc/aarch64-poky-linux/8.3.0/real-ld: /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libport.so: undefined reference to `dlerror'
Because I am cross-compiling, I think it might have linked the wrong file or the libdl.so might be broken.
How can I find out which file was linked by target_link_libraries? I need a full path to the file.
EDIT:
Output of make VERBOSE=1:
/opt/poky/2.7.3/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-g++ -march=armv8-a+crc --sysroot=/opt/poky/2.7.3/sysroots/aarch64-poky-linux --sysroot=/opt/poky/2.7.3/sysroots/aarch64-poky-linux -O2 -pipe -g -feliminate-unused-debug-types -O3 -DNDEBUG -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed CMakeFiles/test1.dir/test1.cpp.o CMakeFiles/test1.dir/__/animateEyes.cpp.o CMakeFiles/test1.dir/__/lcd_graphics.cpp.o CMakeFiles/test1.dir/__/trajGen.cpp.o CMakeFiles/test1.dir/lcd.cpp.o -o test1 -Wl,-rpath,/usr/lib/collar/engine -ldl /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/collar/engine/libuobject.so ../../../lib/libgtest.a ../../../lib/libgmock.a ../../../lib/libgtest_main.a /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libsched.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libserialize.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libport.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libboost_regex-mt.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libboost_signals-mt.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libboost_filesystem-mt.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libboost_thread-mt.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libboost_date_time-mt.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libboost_chrono-mt.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libboost_system-mt.so /opt/poky/2.7.3/sysroots/aarch64-poky-linux/usr/lib/libboost_atomic-mt.so ../../../lib/libgtest.a -lpthread
Related
I am trying to incorporate yaml-cpp into my project.
I have a "Demes" class where I need to parse a YAML file.
This is the relevant method in Demes.cpp:
#include "Demes.hpp"
void Demes::parse(const std::string& fileName)
{
YAML::Node test = YAML::LoadFile(fileName);
}
where Demes.hpp includes the yaml-cpp headers and declares the 'parse' method.
Building with make -VERBOSE=1 (as suggested by #Tsyvarev) gives:
[100%] Linking CXX executable momentspp
cd /home/gvbarroso/Devel/momentspp/build/src && /usr/bin/cmake -E cmake_link_script CMakeFiles/momentspp.dir/link.txt --verbose=1
/usr/bin/c++ -std=c++20 -Weffc++ -Wshadow -Wall -Wextra -ffast-math -O3 -march=native CMakeFiles/momentspp.dir/Log.cpp.o CMakeFiles/momentspp.dir/PolymorphismData.cpp.o CMakeFiles/momentspp.dir/SumStatsLibrary.cpp.o CMakeFiles/momentspp.dir/Drift.cpp.o CMakeFiles/momentspp.dir/Migration.cpp.o CMakeFiles/momentspp.dir/Mutation.cpp.o CMakeFiles/momentspp.dir/Recombination.cpp.o CMakeFiles/momentspp.dir/Epoch.cpp.o CMakeFiles/momentspp.dir/Model.cpp.o CMakeFiles/momentspp.dir/OptimizationWrapper.cpp.o CMakeFiles/momentspp.dir/Demes.cpp.o CMakeFiles/momentspp.dir/main.cpp.o -o momentspp -Wl,-rpath,/home/gvbarroso/.local/lib: /home/gvbarroso/.local/lib/libbpp-phyl3.so.1.0.0 /usr/lib/x86_64-linux-gnu/libboost_iostreams.so.1.74.0 /home/gvbarroso/.local/lib/libbpp-seq3.so.1.0.0 /home/gvbarroso/.local/lib/libbpp-core3.so.1.0.0
/usr/bin/ld: CMakeFiles/momentspp.dir/Demes.cpp.o: in function Demes::parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': Demes.cpp:(.text+0x4c): undefined reference to YAML::LoadFile(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&)'
/usr/bin/ld: Demes.cpp:(.text+0x12c): undefined reference to `YAML::operator<<(std::ostream&, YAML::Node const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/momentspp.dir/build.make:277: src/momentspp] Error 1
make[2]: Leaving directory '/home/gvbarroso/Devel/momentspp/build'
make[1]: *** [CMakeFiles/Makefile2:125: src/CMakeFiles/momentspp.dir/all] Error 2
make[1]: Leaving directory '/home/gvbarroso/Devel/momentspp/build'
make: *** [Makefile:156: all] Error 2
I am using CMake to build my project, but I am still fairly unfamiliar with it.
EDIT: I forgot to mention that I have two CMakeLists.txt files, one inside src and the other inside the external build.
The start of my CMakeLists.txt file in the external build is:
cmake_minimum_required (VERSION 3.5.0)
project (momentspp CXX)
SET(CMAKE_CXX_FLAGS "-std=c++20 -Weffc++ -Wshadow -Wall -Wextra -ffast-math -O3 -march=native")
And the part of it where I look for yaml-cpp is:
FIND_PACKAGE(yaml-cpp REQUIRED)
IF(yaml-cpp_FOUND)
INCLUDE_DIRECTORIES(${yaml-cpp_INCLUDE_DIRS})
SET(LIBS {yaml-cpp_LIBRARIES})
MESSAGE("-- yaml-cpp libraries found here:")
MESSAGE(" includes: ${yaml-cpp_INCLUDE_DIRS}")
ENDIF()
My full CMakeLists.txt file inside src is:
SET(momentspp_CPP
Log.cpp
PolymorphismData.cpp
SumStatsLibrary.cpp
Drift.cpp
Migration.cpp
Mutation.cpp
Recombination.cpp
Epoch.cpp
Model.cpp
OptimizationWrapper.cpp
Demes.cpp
main.cpp
)
ADD_EXECUTABLE (momentspp ${momentspp_CPP})
SET(momentspp-targets momentspp)
FOREACH (target ${momentspp-targets})
TARGET_LINK_LIBRARIES(${target} ${BPP_LIBS_SHARED} ${BOOST_LIBS_SHARED} ${EIGEN3_LIBS_SHARED} ${yaml-cpp_LIBS_SHARED})
TARGET_LINK_LIBRARIES (${target} ${LIBS})
ENDFOREACH (target)
INSTALL(TARGETS ${momentspp-targets} DESTINATION ${CMAKE_INSTALL_BINDIR})
and this was working prior to the inclusion of yaml-cpp.
This feels like a rather complicated CMake set-up, but I am copying and editing it from a previous project where someone else helped me with it.
How can I fix the linking issue?
I tried looking similar questions around here, but couldn't get their solutions to work for me (apparently those people where not using CMake to build their projects).
Thank you,
Gustavo
I cant get working my blas library with cmake. I have arch-linxux, both blas and cmake are installed with pacman. Cant understand where is problem :-(. I made cmake to print out the output of macro CHECK_FORTRAN_FUNCTION_EXISTS, because it fails there. Maybe I dont have proper configuration of ld?
My simple testing CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(Test C Fortran)
find_package(BLAS)
Error part from output:
-- Looking for Fortran sgemm
-- Change Dir: /home/jiri/test_lapack/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_486fc/fast"
/usr/bin/make -f CMakeFiles/cmTC_486fc.dir/build.make CMakeFiles/cmTC_486fc.dir/build
make[1]: Entering directory '/home/jiri/test_lapack/CMakeFiles/CMakeTmp'
Building Fortran object CMakeFiles/cmTC_486fc.dir/testFortranCompiler.f.o
/usr/bin/gfortran -c /home/jiri/test_lapack/CMakeFiles/CMakeTmp/testFortranCompiler.f -o CMakeFiles/cmTC_486fc.dir/testFortranCompiler.f.o
Linking Fortran executable cmTC_486fc
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_486fc.dir/link.txt --verbose=1
/usr/bin/gfortran CMakeFiles/cmTC_486fc.dir/testFortranCompiler.f.o -o cmTC_486fc /usr/local/lib64/libblas.a
/usr/bin/ld: /usr/local/lib64/libblas.a(sgemm.f.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: /usr/local/lib64/libblas.a(xerbla.f.o): relocation R_X86_64_32S against `.rodata' can not be used when making a PIE object; recompile with -fPIC
/usr/bin/ld: final link failed: Nonrepresentable section on output
collect2: error: ld returned 1 exit status
make[1]: *** [CMakeFiles/cmTC_486fc.dir/build.make:99: cmTC_486fc] Error 1
make[1]: Leaving directory '/home/jiri/test_lapack/CMakeFiles/CMakeTmp'
make: *** [Makefile:126: cmTC_486fc/fast] Error 2
-- Looking for Fortran sgemm - not found
I'm building a shared library and an application using that lib on Cygwin. With GCC CMake creates a .dll.a to use when linking. Switching to clang I get
[ 34%] Built target xxx_shared
make[2]: *** No rule to make target 'src/libxxx.dll.a', needed by 'xxx.exe'. Stop.
Is this a bug in the clang CMake extension?
I'm using cmake --version 3.3.2
Yes, it seems to be a bug in CMake. Running make VERBOSE=1 reveals that with GCC:
/usr/bin/c++.exe -g -shared -Wl,--enable-auto-import -o XXX -Wl,-Bstatic -lm -Wl,-Bdynamic -lstdc++ -lcygwin -ladvapi32 -lshell32 -luser32 -lkernel32
while with clang:
/usr/bin/clang++ -fPIC -g -shared -o XXX -Wl,-Bstatic -lm -Wl,-Bdynamic -lstdc++ -lcygwin -ladvapi32 -lshell32 -luser32 -lkernel32
So it seems that somehow clang++ does not get the -Wl,--enable-auto-import flag. Manually running the corrected clang++ command correctly creates the expected .dll.a allowing the rest of the build to proceed as expected.
Haven't figured out why this happens yet, though. At this point I can't decipher CMakes platform extensions, which seems to set this for GCC.
Update: I've reported this here.
The correct link command is
g++ file1.o file2.o xxx.0 -o target -I./ -I/usr/local/libmylibone/
-L./ -L/usr/local/testlib/ ../lib/special_lib/static_lib.a
-lasn1c++ -lmysqlclient -lnsl -lm -lz -lc -ldl -lpthread -lrt -ljson
Please focus on ../lib/special_lib/static_lib.a, this is a static library and not named with libxxx.a. And I don't know how to write a CMake command to get this correct link command.
I've tried TARGET_LINK_LIBRARIES(../lib/special_lib/static_lib.a) and it will be translated to -l../lib/special_lib/static_lib.a. I've also tried TARGET_LINK_LIBRARIES(static_lib) but got -lstatic_lib and failed.
If you put the absolute path to your library it should work:
TARGET_LINK_LIBRARIES(your_binary /usr/local/lib/static_lib.a)
Second option:
ADD_LIBRARY(staticlib STATIC IMPORTED)
SET_TARGET_PROPERTIES(staticlib PROPERTIES IMPORTED_LOCATION /usr/local/lib/static_lib.a)
TARGET_LINK_LIBRARIES(your_binary staticlib)
The official CMake documentation for importing/exporting targets is here.
I'm trying to link a really simple GLES2 & EGL program using g++ 4.9.1, on a Ubuntu Trusty system. I'm using the mesa libraries.
I'm getting linker errors for EGL functions:
test.cpp:(.text+0x342): undefined reference to `eglGetDisplay'
test.cpp:(.text+0x389): undefined reference to `eglInitialize'
test.cpp:(.text+0x40f): undefined reference to `eglCreateContext'
test.cpp:(.text+0x458): undefined reference to `eglCreatePbufferSurface'
test.cpp:(.text+0x49e): undefined reference to `eglMakeCurrent'
I am compiling test.cpp with
g++ -std=c++0x -Wall -Werror -lEGL -lGLESv2 -o test test.cpp
I've tried switching the order of libraries, which sometimes matters, but I get the same problem. Is there a library I'm missing here?
I've run readelf -Ws /usr/lib/x86_64-linux-gnu/mesa-egl/libEGL.so and all of the required functions are defined.
You should put libraries to the end of a command line
g++ -std=c++0x -Wall -Werror -o test test.cpp -lEGL -lGLESv2
I managed to fix this by compiling the C++ file to an object file, and then linking as a separate step. I'm not sure why this works, when the one-line compilation doesn't.
g++ -std=c++0x -Wall -Werror -c -o test.o test.cpp
g++ -o test test.o -lGLESv2 -lEGL
I've put the question to the community to try to figure out why: Single-command compile and link fails, separate steps work