首页 > 解决方案 > CMake 导出包未按预期工作

问题描述

我正在学习 CMake 的安装命令。对于可执行文件,我已经很清楚了。对于库,构建和安装所需的 CMake 脚本的额外步骤很少,因此该库可用于以下场景。

  1. 从当前 CMake 项目生成的本地构建中查找并链接库。
  2. 从通用安装位置查找并链接库。这是不构建库的 3rd 方 CMake 项目所必需的。

我想建立一个名为FooBar. FooBar链接到一个名为 的可执行文件App,该可执行文件与 . 在同一个 CMake 项目中定义FooBar

这是我的 CMake 文件和项目结构。

<project-root>
    |-app
    |   |-src
    |   |   |-main.cpp
    |   |
    |   |-CMakeLists.txt
    |
    |-lib
    |   |-include
    |   |   |-FooBar.h
    |   |
    |   |-src
    |   |   |-FooBar.cpp
    |   |
    |   |-CMakeLists.txt
    |
    |-CMakeLists.txt

# File: <project-root>/CMakeLists.txt

cmake_minimum_required(VERSION 3.8 FATAL_ERROR)

project(SampleProject VERSION 0.0.1 LANGUAGES CXX)

add_subdirectory(lib)
add_subdirectory(app)

# File: <project-root>/app/CMakeLists.txt

cmake_minimum_required(VERSION 3.8 FATAL_ERROR)

set(TARGET_NAME "App")

find_package(FooBar REQUIRED)

set(IMPL_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp
)

add_executable(
    ${TARGET_NAME}
        ${IMPL_FILES}
)

target_link_libraries(
    ${TARGET_NAME} 
        PRIVATE
            FooBar
)

install(
    TARGETS
        ${TARGET_NAME}
    DESTINATION
        bin
)

# File: <project-root>/lib/CMakeLists.txt

set(LIB_NAME FooBar)
set(CMAKE_CXX_VERSION 11)

set(IMPL_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/src/Lib.cpp
)

set(PUBLIC_DEFI_FILES
    ${CMAKE_CURRENT_SOURCE_DIR}/include/Lib.h
)

add_library(
    ${LIB_NAME}
        STATIC
            ${IMPL_FILES}
)

target_include_directories(
    ${LIB_NAME}
        PUBLIC
            $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
            $<INSTALL_INTERFACE:include>
)

set_target_properties(
    ${LIB_NAME}
        PROPERTIES 
            PUBLIC_HEADER
                ${PUBLIC_DEFI_FILES}
)

install(
    TARGETS
        ${LIB_NAME}
    EXPORT
        ${LIB_NAME}Targets
    PUBLIC_HEADER DESTINATION include
    ARCHIVE DESTINATION lib
)

install(
    EXPORT 
        ${LIB_NAME}Targets 
    FILE 
        ${LIB_NAME}Config.cmake 
    DESTINATION
        lib/cmake/${LIB_NAME}
)

# I am under the impression these are needed for other targets in the
# current project to be able to use "find_package(FooBar)". I also
# think that "CMAKE_EXPORT_NO_PACKAGE_REGISTRY" needs to not be set.
message(STATUS "CMAKE_EXPORT_NO_PACKAGE_REGISTRY: ${CMAKE_EXPORT_NO_PACKAGE_REGISTRY}")
export(
    EXPORT
        ${LIB_NAME}Targets
    FILE 
        ${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}Config.cmake
)
export(PACKAGE ${LIB_NAME})

要生成我运行的构建文件

# Clean project directory.
mkdir _build
cd _build
cmake .. -DCMAKE_INSTALL_PREFIX=<project-root>/_dist

我收到以下错误。

-- CMAKE_EXPORT_NO_PACKAGE_REGISTRY: 
CMake Error at app/CMakeLists.txt:5 (find_package):
  By not providing "FindFooBar.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "FooBar", but
  CMake did not find one.

  Could not find a package configuration file provided by "FooBar" with any
  of the following names:

    FooBarConfig.cmake
    foobar-config.cmake

  Add the installation prefix of "FooBar" to CMAKE_PREFIX_PATH or set
  "FooBar_DIR" to a directory containing one of the above files.  If "FooBar"
  provides a separate development package or SDK, be sure it has been
  installed.


-- Configuring incomplete, errors occurred!

再次运行上述命令会产生相同的错误消息。我不应该看到该消息,因为这两行

export(
    EXPORT
        ${LIB_NAME}Targets
    FILE 
        ${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}Config.cmake
)
export(PACKAGE ${LIB_NAME})

应该生成_build/FooBar/FooBarConfig.cmake并将其添加到App.

如果我删除app子目录,构建并安装FooBar_dist,然后重新添加app,我不会收到错误消息。即使我清除_build并从头开始生成构建文件,我也不会收到错误消息。CMake 如何找到我的本地安装配置脚本,而不是构建目录中的那个?我做错了什么还是有人知道为什么这可能不起作用?

标签: cmake

解决方案


推荐阅读