首先,这是我第一次编写cmake文件,所以我需要婴儿解释,感谢您的考虑。
基本上我正在编写一个静态库(例如“MyLib”)。发布库名称为“mylib.lib”,调试库名称为“mylib-d.lib”。此时,我正在尝试为库用户编写 FindMyLib.cmake 文件,但我不知道如何让 CMake 根据库用户的构建配置选择正确的文件。
环境是 Windows/MSVC,未来还会有 Linux 版本。
这就是我的文件现在的样子 -
find_library(MYLIB_LIBRARY
NAMES
"mylib" "libmylib"
PATHS
${LOCAL_LIB_PATH}
${PROJECT_SOURCE_DIR}
/usr/
/usr/bin/
/usr/include/
/usr/lib/
/usr/local/
/usr/local/bin/
/opt/)
find_path(MYLIB_INCLUDE_DIR
NAMES
mylib.h
PATHS
${LOCAL_INCLUDE_PATH}/mylib/
/usr/
/usr/bin/
/usr/include/
/usr/lib/
/usr/local/
/usr/local/bin/
/opt/)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(MySQL DEFAULT_MSG MYLIB_LIBRARY MYLIB_INCLUDE_DIR)
message(STATUS "MYLIB_FOUND: ${MYLIB_FOUND}")
message(STATUS "MYLIB_LIBRARY: ${MYLIB_LIBRARY}")
message(STATUS "MYLIB_INCLUDE_DIR: ${MYLIB_INCLUDE_DIR}")
if (${MYLIB_FOUND})
link_libraries(${MYLIB_LIBRARY})
include_directories(${MYLIB_INCLUDE_DIR})
include_directories(${MYLIB_INCLUDE_DIR}/../)
endif()
谢谢你。
此时我正在尝试编写 FindMyLib.cmake 文件 库的用户,我不知道如何让 CMake 选择 根据库用户的构建配置更正一个。
Find<lib>.cmake
模块旨在与本身不提供 CMake 配置文件的库一起使用。查找库的首选方式是通过 CMake 配置文件,CMake 可以非常直接地生成该文件。
安装库目标时,您首先需要添加导出集名称:
include(GNUInstallDirs) # makes the CMAKE_INSTALL_<dir> variables available
install(
TARGETS MyLib
EXPORT MyLib_Targets # this is an arbitrary identifier later used
# for the creation of the config files
RUNTIME
DESTINATION ${CMAKE_INSTALL_BINDIR} # where to install DLLs on Windows
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR} # where to install the .lib file on
# Windows and the .so files on Linux
ARCHIVE
DESTINATION ${CMAKE_INSTALL_LIBDIR} # where to install .a / .lib files
# for static builds
INCLUDES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # where the headers for the
# library will be installed
)
请注意,上面
INCLUDES
命令中的 install
选项实际上并不安装任何东西,它仅用于在生成的 CMake 配置文件中正确设置导入目标的 INTERFACE_INCLUDE_DIRECTORIES
属性。您必须手动安装所有标头,例如通过做
install(
DIRECTORIES ${PROJECT_SOURCE_DIR}/include
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
如果您有一个名为
include
的专用顶级文件夹,其中包含所有公共标头。
到目前为止,您可能已经为您的库实现了所有步骤(除了在安装库目标时设置
EXPORT
选项)。
配置文件本身可以通过
生成install(
EXPORT MyLib_Targets # refers to the identifier specified in
# the previous `install` command
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyLib # there are a few different
# directories in which CMake
# will search for config files,
# this is one of the more common ones
NAMESPACE MyLib:: # Users will consume your library via `MyLib::MyLib`
FILE MyLib-Targets.cmake
)
在非常简单的情况下,您的库本身没有外部依赖项,您可以将
MyLib-Targets.cmake
替换为 MyLibConfig.cmake
,一切都会正常工作。
如果您确实有外部依赖项,则必须创建一个单独的配置文件,该文件首先搜索这些依赖项,然后包含生成的配置文件。例如,如果您的库依赖于
libz
,您将在 cmake
目录中拥有一个配置文件模板“MyLibConfig.cmake.in”,其中包含内容
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)
find_dependencies(ZLIB)
include(${CMAKE_CURRENT_LIST_DIR}/MyLib-Targets.cmake)
并使用
include(CMakePackageConfigHelpers)
configure_package_config_file(
${PROJECT_SOURCE_DIR}/cmake/MyLibConfig.cmake.in # path to the template file
${CMAKE_CURRENT_BINARY_DIR}/MyLibConfig.cmake # path where the generated config file
# will be located
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyLib # where you'll later install
# the generated MyLibConfig.cmake
# file
INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
)
在您的
CMakeLists.txt
中填写模板。
最后一步,您需要将此文件安装在生成的
MyLibConfig.cmake
文件旁边:
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/MyLibConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyLib
)
如果您现在将发布版本和调试版本安装到同一前缀中,当使用者构建发布版本时,它将自动选择发布二进制文件,否则将选择调试库。
如果您愿意,您还可以将版本信息添加到配置文件中,以便消费者可以指定他们需要兼容的版本。为此,请使用
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/MyLibConfigVersion.cmake
VERSION ${PROJECT_VERSION} # assumes you set a version in the `project` call.
# you can also just hard-code a version number here
COMPATIBILITY SameMajorVersion # assuming you follow SemVer. Alternatives are
# AnyNewerVersion, SameMinorVersion and ExactVersion
)
并通过调用安装文件
install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/MyLibConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyLib
)