CPack:如何使用导出创建库包?缺少*Targets-noconfig.cmake文件
更新 这看起来像是Windows cpack版本的错误——在Linux(Ubuntu)下,cpack命令会删除丢失的文件。当我有更多的时间时,我会做更多的研究并发布结果CPack:如何使用导出创建库包?缺少*Targets-noconfig.cmake文件,cmake,cpack,Cmake,Cpack,更新 这看起来像是Windows cpack版本的错误——在Linux(Ubuntu)下,cpack命令会删除丢失的文件。当我有更多的时间时,我会做更多的研究并发布结果 注意:我完全改变了这个问题,因为我能够简化它并创建新的、更短的示例。然而,核心问题丝毫没有改变 问题描述 我有一个库项目,我们称之为Foo,我使用cpack命令打包它。此包包含FooConfig.cmake和FooTargets.cmake文件(第二个由cmake机制导出)。问题是,这不足以让cmake使用它find_pack
注意:我完全改变了这个问题,因为我能够简化它并创建新的、更短的示例。然而,核心问题丝毫没有改变 问题描述 我有一个库项目,我们称之为Foo,我使用
cpack
命令打包它。此包包含FooConfig.cmake
和FooTargets.cmake
文件(第二个由cmake机制导出)。问题是,这不足以让cmake使用它find_package()
找到它,但是当链接到foo
时,没有规则使目标foo未找到',bar.exe需要它。停止。
出现错误
但是如果我用make install DESTDIR=./out\u dir
安装它,它会工作,并且它还包含一个文件:FooTargets noconfig.cmake
。此文件包含foo库文件的路径
那么,我需要做什么来解决这个问题?是否有描述此行为的文档?
附加问题:我看到*-noconfig*
文件包含库的路径,但不包含头目录的路径。有没有办法配置库项目,使生成的文件也自动包含它
更多信息,请注意:
- Foo/ (Experimental library)
- CMakeLists.txt (XyzLib configuration)
- foo.cpp (Function implementation - just prints something)
- foo.h (Contains just single function)
- FooConfig.cmake (Configuration so the find_package find the
library)
- Bar/ (Testing executable)
- CMakeLists.txt (Executable configuration)
- bar.cpp (Main function printing something and
calling the Foo library function)
- 我的操作系统:Windows7,64位
- 编译器:mingw4.4.0(32位)。(注意:是,我使用
命令代替mingw32 make
make
- CMake版本:CMake 2.8.12.2
- 我尝试使用
的结果和makeinstall
错误消失,编译的所有内容和结果exe都按预期工作。看起来noconfig文件就是所需的全部内容No规则使Index.exe需要的目标xyznotfound'。停止。
- Foo/ (Experimental library)
- CMakeLists.txt (XyzLib configuration)
- foo.cpp (Function implementation - just prints something)
- foo.h (Contains just single function)
- FooConfig.cmake (Configuration so the find_package find the
library)
- Bar/ (Testing executable)
- CMakeLists.txt (Executable configuration)
- bar.cpp (Main function printing something and
calling the Foo library function)
- 创建代码后(见下文):
创建生成目录(库项目)(配置,然后生成)cmakegui
在生成目录中mingw32 make
- 变体a)
安装库mingw32使install DESTDIR=./out\u dir
- 变量b)
获取库中的包cpack-C CpackConfig.cmake-G ZIP
- 使用上一步中的文件,并将其移动到环境变量
CMAKE\u PREFIX\u PATH中的特殊目录,以便CMAKE可以找到它(注意“移动”,而不是“复制”,以便删除原始文件)
用于可执行项目(再次配置,然后生成)cmakegui
在生成目录中mingw32 make
没有规则使Index.exe需要的目标xyz“未找到”。停止。
显示,没有更多信息
我的示例代码:
- Foo/ (Experimental library)
- CMakeLists.txt (XyzLib configuration)
- foo.cpp (Function implementation - just prints something)
- foo.h (Contains just single function)
- FooConfig.cmake (Configuration so the find_package find the
library)
- Bar/ (Testing executable)
- CMakeLists.txt (Executable configuration)
- bar.cpp (Main function printing something and
calling the Foo library function)
Foo/CMakeLists.txt:
cmake_minimum_required(VERSION 2.6.3)
project("Foo")
add_library(foo STATIC foo.h foo.cpp)
set_target_properties(foo PROPERTIES PUBLIC_HEADER foo.h)
install(TARGETS foo EXPORT fooTargets
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include
INCLUDES DESTINATION include)
install(FILES FooConfig.cmake DESTINATION lib/foo)
install(EXPORT fooTargets FILE "FooTargets.cmake" DESTINATION lib/foo)
include(CPack)
cmake_minimum_required(VERSION 2.6.3)
project("Bar")
add_executable(bar bar.cpp)
find_package(Foo REQUIRED)
include_directories(${Foo_INCLUDE_DIRS})
target_link_libraries(bar ${Foo_LIBRARIES})
Foo/Foo.cpp:
#include <iostream>
#include "foo.h"
void FooCall()
{
::std::cout << "Hello from Foo!" << ::std::endl;
}
Foo/FooConfig.cmake:
# - Config file for the Foo library package
# This module defines the following variables:
# Foo_FOUND - true if this module was found, false otherwise
# Foo_INCLUDE_DIRS - include directories
# Foo_LIBRARIES - libraries to link against
get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
# Import targets
include("${SELF_DIR}/FooTargets.cmake")
# Foo_INCLUDE_DIRS
get_filename_component(Foo_INCLUDE_DIRS "${SELF_DIR}/../../include" ABSOLUTE)
# Foo_LIBRARIES
set(Foo_LIBRARIES foo)
Bar/CMakeLists.txt:
cmake_minimum_required(VERSION 2.6.3)
project("Foo")
add_library(foo STATIC foo.h foo.cpp)
set_target_properties(foo PROPERTIES PUBLIC_HEADER foo.h)
install(TARGETS foo EXPORT fooTargets
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
PUBLIC_HEADER DESTINATION include
INCLUDES DESTINATION include)
install(FILES FooConfig.cmake DESTINATION lib/foo)
install(EXPORT fooTargets FILE "FooTargets.cmake" DESTINATION lib/foo)
include(CPack)
cmake_minimum_required(VERSION 2.6.3)
project("Bar")
add_executable(bar bar.cpp)
find_package(Foo REQUIRED)
include_directories(${Foo_INCLUDE_DIRS})
target_link_libraries(bar ${Foo_LIBRARIES})
Bar/Bar.cpp
#include <iostream>
#include "foo.h"
int main(int argc, char *argv[])
{
::std::cout << "Hello from bar!" << ::std::endl;
FooCall();
return 0;
}
lib/foo/FooTargets.cmake
# Generated by CMake 2.8.12.2
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget foo)
list(APPEND _expectedTargets ${_expectedTarget})
if(NOT TARGET ${_expectedTarget})
list(APPEND _targetsNotDefined ${_expectedTarget})
endif()
if(TARGET ${_expectedTarget})
list(APPEND _targetsDefined ${_expectedTarget})
endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
# Create imported target foo
add_library(foo STATIC IMPORTED)
set_target_properties(foo PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/FooTargets-*.cmake")
foreach(f ${CONFIG_FILES})
include(${f})
endforeach()
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
if(NOT EXISTS "${file}" )
message(FATAL_ERROR "The imported target \"${target}\" references the file
\"${file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
使用export命令从生成目录创建要使用的导出目标:
CMake 2.8.12不支持导出(导出),但支持导出(目标)。谢谢您的回答,但我不知道,您的意思是我应该如何使用它。我添加了
导出(目标foo文件“${CMAKE\u CURRENT\u BINARY\u DIR}/foo/FooTargets.CMAKE”)
(从您提供的链接复制和更新),没有任何更改-没有帮助。AFAK,这将为构建树创建*Targets.cmake
文件,如果我将构建目录添加到前缀变量,或者如果我将添加export(PACKAGE Foo)
行,它将工作-但仅在本地工作。我应该如何使用它为便携式软件包创建文件?如何使用它以使目标文件不包含硬编码的绝对路径?export()的结果故意不可移植。CMake生成目录不可移植。如果您想要便携,可以使用install(EXPORT)和install。如果您想避免安装,您可能可以这样做,但这是您自己的事情。您可能因为不喜欢答案而对其投了反对票,但这并不是错误的:)。如果我投了反对票而冒犯了您,那么很抱歉-我投了反对票,因为弹出文本是“此答案不有用”,而您的答案并没有完全回答我的问题(您的答案是“如何使我的构建目录能够在find_package()中使用”)
在“本地项目”中,这与实际项目有所不同)。但如果我要求的是不可能的,只需编辑你的答案,在开头加上“不可能,但你可以这样做”,我将取消否决票——因为这将是我问题的答案,尽管我不喜欢。无论如何,关于您的最后一个答案-如果我的问题中的文字听起来像是我想使export()
的生成目录或结果可移植,那么我很抱歉,这是误解。我不。我想让cpack-gzip的结果可以移植到自动生成的配置文件(不是手写的)中,我目前正试图通过install(导出fooTargets文件“fooTargets.cmake”DESTINATION lib/foo)
(但我对其他解决方案持开放态度),但这些配置文件不起作用(有关详细信息,请参阅我的主要问题),对不起,我想我当时不明白这个问题,我也不知道答案,所以我将保留我的答案。