cmake - CMake 导出包未按预期工作
问题描述
我正在学习 CMake 的安装命令。对于可执行文件,我已经很清楚了。对于库,构建和安装所需的 CMake 脚本的额外步骤很少,因此该库可用于以下场景。
- 从当前 CMake 项目生成的本地构建中查找并链接库。
- 从通用安装位置查找并链接库。这是不构建库的 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 如何找到我的本地安装配置脚本,而不是构建目录中的那个?我做错了什么还是有人知道为什么这可能不起作用?
解决方案
推荐阅读
- ruby-on-rails - 使用 PostgreSQL 函数和 Materialistic 视图将嵌套 JSON 转换为关系表
- php - 如何实时动态修改php站点上的文本文件
- python-3.x - mod_wsgi (pid=*): 目标 WSGI 脚本 '/root/project/wsgi.py' 不能作为 Python 加载
- python - 将 SRTM hgt 文件从 WGS84 转换为另一个 CRS
- ruby - 在ruby方法块中,如何获取分配给方法返回值的变量名
- java - 通过 pdfbox 从 pdf 文档中提取文本时没有 Unicode 映射错误,因为字体字典中缺少 ToUnicode CMap 条目
- javascript - Soundcloud JavaScript API 发表评论不起作用
- javascript - 如何使用 firebase 函数发送和获取数据?
- angular - 如何避免 Observable 中超出最大调用堆栈大小?
- javascript - 搜索功能(JAVASCRIPT)