CMake build FMT and dependent libraries during configuration stage

139 views Asked by At

For couple of days I've tried to build FMT and SPDLOG with FMT as external library during configuration phase of CMake.

BuildFmt.cmake:

FetchContent_Declare(
  fmt
  OVERRIDE_FIND_PACKAGE
  URL "file://${PROJECT_SOURCE_DIR}/deps/fmt-10.1.1.tar.gz"
)

FetchContent_GetProperties(fmt)
if(NOT fmt_POPULATED)
  FetchContent_Populate(fmt)
endif()

execute_process(OUTPUT_QUIET
  COMMAND cmake -DBUILD_SHARED_LIBS=ON -DFMT_TEST=OFF ${fmt_SOURCE_DIR}
  WORKING_DIRECTORY "${fmt_BINARY_DIR}"
  RESULT_VARIABLE FMT_RESULT)

execute_process(OUTPUT_QUIET
  COMMAND make
  WORKING_DIRECTORY "${fmt_BINARY_DIR}"
  RESULT_VARIABLE FMT_RESULT)

set(FMT_BUILT ON CACHE BOOL "FMT is built" FORCE)
list(APPEND CMAKE_PREFIX_PATH "${fmt_BINARY_DIR}") 

BuildSpdLog.cmake:

FetchContent_Declare(
  spdlog
  OVERRIDE_FIND_PACKAGE
  URL "file://${PROJECT_SOURCE_DIR}/deps/spdlog-1.12.0.tar.gz"
)

FetchContent_GetProperties(spdlog)
if(NOT spdlog_POPULATED)
  FetchContent_Populate(spdlog)
endif()
  
execute_process(
  COMMAND cmake -DSPDLOG_BUILD_SHARED=ON -DSPDLOG_BUILD_PIC=ON -DSPDLOG_BUILD_EXAMPLE=OFF -DSPDLOG_FMT_EXTERNAL=ON ${spdlog_SOURCE_DIR}
  WORKING_DIRECTORY "${spdlog_BINARY_DIR}"
  RESULT_VARIABLE SPDLOG_RESULT)

execute_process(
  COMMAND make
  WORKING_DIRECTORY "${spdlog_BINARY_DIR}"
  RESULT_VARIABLE SPDLOG_RESULT)

set(SPDLOG_BUILT ON CACHE BOOL "SPDLOG is built" FORCE)
list(APPEND CMAKE_PREFIX_PATH "${spdlog_BINARY_DIR}")
add_subdirectory(${spdlog_SOURCE_DIR} ${spdlog_BINARY_DIR})

CMakeLists.txt

cmake_minimum_required(VERSION 3.14.7)

project("test")

add_compile_definitions(SPDLOG_FMT_EXTERNAL)

list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

include(BuildFmt)
include(BuildSpdLog)

find_package(fmt REQUIRED CONFIG)

add_executable(my_importer main.cpp)
target_link_libraries(my_importer fmt::fmt)

main.cpp (just to have one including FMT)

#include<fmt/format.h>

int main() {
    return 0;
}

Build is OK, but when I do ldd I see system's FMT is linked:

nikola@notebook ~/projects/2m/cmake_test/build $ ldd ./_deps/spdlog-build/libspdlog.so
linux-vdso.so.1 (0x00007fff1a948000)
libfmt.so.9 => /usr/lib64/libfmt.so.9 (0x00007f94489e2000)
libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/13/libstdc++.so.6 (0x00007f9448782000)
libm.so.6 => /lib64/libm.so.6 (0x00007f94486a2000)
libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/13/libgcc_s.so.1 (0x00007f944867e000)
libc.so.6 => /lib64/libc.so.6 (0x00007f94484ab000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9448ab7000)

I am not sure what am I doing wrong. In case I add dependenccy SPDLOG to main, during make, I see that SPDLOG is rebuild and it links to correct libfmt.so:

nikola@notebook ~/projects/cmake_test/build $ make
[ 11%] Building CXX object _deps/spdlog-build/CMakeFiles/spdlog.dir/src/spdlog.cpp.o
[ 22%] Building CXX object _deps/spdlog-build/CMakeFiles/spdlog.dir/src/stdout_sinks.cpp.o
[ 33%] Building CXX object _deps/spdlog-build/CMakeFiles/spdlog.dir/src/color_sinks.cpp.o
[ 44%] Building CXX object _deps/spdlog-build/CMakeFiles/spdlog.dir/src/file_sinks.cpp.o
[ 55%] Building CXX object _deps/spdlog-build/CMakeFiles/spdlog.dir/src/async.cpp.o
[ 66%] Building CXX object _deps/spdlog-build/CMakeFiles/spdlog.dir/src/cfg.cpp.o
[ 77%] Linking CXX shared library libspdlog.so
[ 77%] Built target spdlog
[ 88%] Building CXX object CMakeFiles/2m_importer.dir/main.cpp.o
[100%] Linking CXX executable 2m_importer
[100%] Built target 2m_importer
nikola@notebook ~/projects/2m/cmake_test/build $ ldd ./_deps/spdlog-build/libspdlog.so
    linux-vdso.so.1 (0x00007fffe279d000)
    libfmt.so.10 => /home/nikola/projects/2m/cmake_test/build/_deps/fmt-build/libfmt.so.10 (0x00007f882ee5c000)
    libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/13/libstdc++.so.6 (0x00007f882ebd7000)
    libm.so.6 => /lib64/libm.so.6 (0x00007f882eaf7000)
    libgcc_s.so.1 => /usr/lib/gcc/x86_64-pc-linux-gnu/13/libgcc_s.so.1 (0x00007f882ead3000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f882e900000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f882eef3000)

My knowledge of CMake is very basic, so it is possible I am trying to do something very stupid. I tried with ExternalProject's also but no luck.

1

There are 1 answers

0
nikoladsp On

After another round of trying and putting traces I have ended up with adding:

-DCMAKE_INSTALL_PREFIX=${PROJECT_SOURCE_DIR}/deps -DCMAKE_PREFIX_PATH=${PROJECT_SOURCE_DIR}/deps/lib64/cmake

when building SPDLOG. Also, I've altered make command to make install.

Suggestion from @Tsyvarev give me a hint.