几天来,我在 CMake 的配置阶段尝试使用 FMT 作为外部库来构建 FMT 和 SPDLOG。
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(只是为了有一个包括 FMT)
#include<fmt/format.h>
int main() {
return 0;
}
构建没问题,但是当我这样做时
ldd
我看到系统的FMT已链接:
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)
我不确定我做错了什么。如果我将依赖 SPDLOG 添加到 main,在
make
期间,我会看到 SPDLOG 正在重建,并且它链接到正确的 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)
我对 CMake 的了解非常基础,所以我可能正在尝试做一些非常愚蠢的事情。我也尝试过ExternalProject,但没有成功。
经过另一轮尝试和放置痕迹后,我最终添加了:
-DCMAKE_INSTALL_PREFIX=${PROJECT_SOURCE_DIR}/deps -DCMAKE_PREFIX_PATH=${PROJECT_SOURCE_DIR}/deps/lib64/cmake
构建 SPDLOG 时。另外,我已将
make
命令更改为 make install
。
@Tsyvarev 的建议给我一个提示。