Print library full-path found with target_link_libraries - cmake

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

Linking problems with yaml-cpp

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

cmake 3.10 cant internally test the blas library

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

CMake on Cygwin with clang not creating expected dll.a

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.

cmake how to link static library not named with libxxx.a?

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.

EGL linker errors

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