CMake find 中静态库的调试和发布名称

问题描述 投票:0回答:1

首先,这是我第一次编写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()

谢谢你。

cmake
1个回答
2
投票

此时我正在尝试编写 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
)
© www.soinside.com 2019 - 2024. All rights reserved.