I have a simple project to link a static library .a. I tried to put the library and header in a specified location but two different CMakeLists.txt with no success. Can any one help to point out what I missed? Is it because there are multiple headers?
1. File structure
├── build ├── include │ ├── ftd2xx.h │ ├── libft4222.h │ └── WinTypes.h ├── lib │ └── libft4222.a ├── CMakeLists.txt └── src ├── get-version.c ├── i2cm.c ├── spim.c └── spis.c 2. CMakelist.txt
1st version
cmake_minimum_required(VERSION 3.10) project(MyApps) find_library(FT4222LIB NAME ft4222 HINTS ${CMAKE_CURRENT_SOURCE_DIR}/lib) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/) add_executable(i2cm src/i2cm.c) target_link_libraries(i2cm PRIVATE ${FT4222LIB}) 2nd version
cmake_minimum_required(VERSION 3.10) project(MyApps LANGUAGES C) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/) add_executable(i2cm src/i2cm.c) target_link_libraries(i2cm PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/lib/libft4222.a) 3. Output Both leads to the following error. Obviously, the compile command is incorrect.
root@af476bc2f052:/workdir# (cd build && make) /usr/bin/cmake -S/workdir -B/workdir/build --check-build-system CMakeFiles/Makefile.cmake 0 /usr/bin/cmake -E cmake_progress_start /workdir/build/CMakeFiles /workdir/build//CMakeFiles/progress.marks make -f CMakeFiles/Makefile2 all make[1]: Entering directory '/workdir/build' make -f CMakeFiles/i2cm.dir/build.make CMakeFiles/i2cm.dir/depend make[2]: Entering directory '/workdir/build' cd /workdir/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /workdir /workdir /workdir/build /workdir/b uild /workdir/build/CMakeFiles/i2cm.dir/DependInfo.cmake --color= make[2]: Leaving directory '/workdir/build' make -f CMakeFiles/i2cm.dir/build.make CMakeFiles/i2cm.dir/build make[2]: Entering directory '/workdir/build' [ 50%] Building C object CMakeFiles/i2cm.dir/src/i2cm.c.o /usr/bin/cc -I/workdir/include -MD -MT CMakeFiles/i2cm.dir/src/i2cm.c.o -MF CMakeFiles/i2cm.dir/src/i2cm.c.o.d -o CMakeFiles/i2cm.dir/src/i2cm.c.o -c /workdir/src/i2cm.c [100%] Linking C executable i2cm /usr/bin/cmake -E cmake_link_script CMakeFiles/i2cm.dir/link.txt --verbose=1 /usr/bin/cc CMakeFiles/i2cm.dir/src/i2cm.c.o -o i2cm ../lib/libft4222.a /usr/bin/ld: ../lib/libft4222.a(I2c.obj): in function `boost::system::(anonymous namespace)::generic_error_catego ry::message(int) const': I2c.cpp:(.text+0x63): undefined reference to `__cxa_guard_acquire' /usr/bin/ld: I2c.cpp:(.text+0x7e): undefined reference to `std::allocator<char>::allocator()' /usr/bin/ld: I2c.cpp:(.text+0x98): undefined reference to `std::basic_string<char, std::char_traits<char>, std::a llocator<char> >::basic_string(char const*, std::allocator<char> const&)' /usr/bin/ld: I2c.cpp:(.text+0xa4): undefined reference to `__cxa_guard_release' /usr/bin/ld: I2c.cpp:(.text+0xb9): undefined reference to `std::basic_string<char, std::char_traits<char>, std::a llocator<char> >::~basic_string()' For the same code, if I place the lib and headers in default system path under /usr/local/lib and /usr/local/include
❯ ls /usr/local/include ftd2xx.h libft4222.h WinTypes.h ❯ ls /usr/local/lib libft4222.a libft4222.so libft4222.so.1.4.4.232 python3.10 CMAKE build info*
make -f CMakeFiles/i2cm.dir/build.make CMakeFiles/i2cm.dir/build make[2]: Entering directory '/home/craigyang/workplace/fdt4222_test/fdt4222_test_util/build' [ 37%] Building C object CMakeFiles/i2cm.dir/src/i2cm.c.o /usr/bin/cc -MD -MT CMakeFiles/i2cm.dir/src/i2cm.c.o -MF CMakeFiles/i2cm.dir/src/i2cm.c.o.d -o CMakeFiles/i2cm .dir/src/i2cm.c.o -c /home/craigyang/workplace/fdt4222_test/fdt4222_test_util/src/i2cm.c [ 50%] Linking C executable bin/i2cm /usr/bin/cmake -E cmake_link_script CMakeFiles/i2cm.dir/link.txt --verbose=1 /usr/bin/cc CMakeFiles/i2cm.dir/src/i2cm.c.o -o bin/i2cm -lft4222 make[2]: Leaving directory '/home/craigyang/workplace/fdt4222_test/fdt4222_test_util/build' [ 50%] Built target i2cm The following CMakeList works.
cmake_minimum_required(VERSION 3.10) project(MyApps) add_executable(i2cm src/i2cm.c) target_link_libraries(i2cm ft4222)
libft4222.a) into C program. While it is possible to make that work, the simplest way is to convert your program into C++ one.project()command you just make languages available for programs. CMake selects program's langauge based on files and libraries used by that program, but CMake doesn't know thatlibft4222.acontains C++ library. You may explicitely specify language for your program via LINKER_LANGUAGE property:set_target_properties(i2cm PROPERTIES LINKER_LANGUAGE CXX)(that command should be issued afteradd_executable).libft4222.so. That code asks a linker to search the library by name (ft42222) when 2 libraries with such name exist. And the linker prefers to link with the shared library..sofile is not a CMake preference but a linker one. See description of-llibraryoption here: gcc.gnu.org/onlinedocs/gcc/Link-Options.html