Jee*_*eet 1 install cmake target
我有一个作为项目一部分构建并链接到的库。我要提供的工具可以在系统范围内(或设置$ {CMAKE_INSTALL_PREFIX}的任何位置)安装该库。否则,默认情况下,项目的最终构建产品将静态链接到库,并且前者将被安装,但是库二进制文件保留在构建目录中。
换一种说法:
$ make
$ make install
Run Code Online (Sandbox Code Playgroud)
将构建和安装程序,但仅
$ make install.foo
Run Code Online (Sandbox Code Playgroud)
会将库安装到$ {CMAKE_INSTALL_PREFIX},并在需要时首先构建它。
到目前为止,我有类似这样的内容(从实际脚本中简化了,所以可能会有错误):
INCLUDE_DIRECTORIES( "${CMAKE_CURRENT_LIST_DIR}")
SET (FOO_LIBRARY "foo")
# Following builds library and makes it available to
# be linked other targets within project by:
# TARGET_LINK_LIBRARIES(${progname} ${FOO_LIBRARY})
ADD_LIBRARY(${FOO_LIBRARY}
foo/foo.cpp # and other sources ...
)
###########################################################
# Approach #1
# -----------
# Optionally allow users to install it by invoking:
#
# cmake .. -DINSTALL_FOO="yes"
#
# This works, but it means that users will have to run
# cmake again to switch back and forth between the libary
# installation and non-library installation.
#
OPTION(INSTALL_FOO "Install foo" OFF)
IF (INSTALL_FOO)
INSTALL(TARGETS ${FOO_LIBRARY} DESTINATION lib/foo)
SET(FOO_HEADERS foo/foo.h)
INSTALL(FILES ${FOO_HEADERS} DESTINATION include/foo)
UNSET(INSTALL_FOO CACHE)
ENDIF()
###########################################################
###########################################################
# Approach #2
# -----------
# Optionally allow users to install it by invoking:
#
# make install.foo
#
# Unfortunately, this gets installed by "make install",
# which I want to avoid
SET(FOO_INSTALL "install.foo")
ADD_CUSTOM_TARGET(${FOO_INSTALL}
COMMAND ${CMAKE_COMMAND}
-D COMPONENT=foo
-P cmake_install.cmake)
ADD_DEPENDENCIES(${FOO_INSTALL} ${FOO_LIBRARY})
INSTALL(TARGETS ${FOO_LIBRRARY}
DESTINATION lib/foo COMPONENT foo)
SET(FOO_HEADERS foo/foo.h)
INSTALL(FILES ${FOO_HEADERS}
DESTINATION include/foo COMPONENT foo)
###########################################################
Run Code Online (Sandbox Code Playgroud)
可以看出,方法#1可以完成一些工作,但是安装该库所需的步骤是:
$ cmake .. -DINSTALL_FOO="yes"
$ make && make install
Run Code Online (Sandbox Code Playgroud)
然后,要返回“正常”构建,用户必须记住要再次运行cmake,而不使用“ -DINSTALL_FOO”选项,否则该库将安装在下一个“ make install”中。
第二种方法在我运行“ make install.foo”时有效,但是如果我运行“ make install”,它也会安装该库。我想避免后者。
有人对如何实现这一目标有任何建议吗?
您在方法2的正确轨道上。您可以FOO通过使用install命令的OPTIONAL开关诱使CMake避免安装相关文件。
对于FOO库目标,必须按以下方式修改命令:
SET (FOO_LIBRARY "foo")
ADD_LIBRARY(${FOO_LIBRARY} EXCLUDE_FROM_ALL
foo/foo.cpp
)
INSTALL(TARGETS ${FOO_LIBRARY}
DESTINATION lib/foo COMPONENT foo OPTIONAL)
Run Code Online (Sandbox Code Playgroud)
将EXCLUDE_FROM_ALL被添加到ADD_LIBRARY以防止库从当你运行一个普通的建筑make。FOO_LIBRARY通过添加OPTIONAL开关,可以选择进行安装。
进行FOO_HEADERS可选安装需要进行以下更改:
SET(FOO_HEADERS foo/foo.h)
SET(BINARY_FOO_HEADERS "")
FOREACH (FOO_HEADER ${FOO_HEADERS})
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${FOO_HEADER}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${FOO_HEADER} ${CMAKE_CURRENT_BINARY_DIR}/${FOO_HEADER}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${FOO_HEADER})
LIST (APPEND BINARY_FOO_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/${FOO_HEADER})
ENDFOREACH()
INSTALL(FILES ${BINARY_FOO_HEADERS}
DESTINATION include/foo COMPONENT foo OPTIONAL)
Run Code Online (Sandbox Code Playgroud)
该FOREACH循环设置了自定义命令,这些命令将FOO_HEADERS逐字记录复制到相应的二进制目录。该INSTALL(FILES ...命令不是直接使用当前源目录中的标头,而是从二进制目录中拾取复制的标头。二进制目录中头文件的路径收集在变量中BINARY_FOO_HEADERS。
最后FOO_INSTALL,必须通过以下方式设置目标:
SET(FOO_INSTALL "install.foo")
ADD_CUSTOM_TARGET(${FOO_INSTALL}
COMMAND ${CMAKE_COMMAND}
-D COMPONENT=foo
-P cmake_install.cmake
DEPENDS ${BINARY_FOO_HEADERS})
ADD_DEPENDENCIES(${FOO_INSTALL} ${FOO_LIBRARY})
Run Code Online (Sandbox Code Playgroud)
该自定义FOO_INSTALL添加了一个依赖项,BINARY_FOO_HEADERS以触发头文件的复制。FOO_LIBRARY运行时,对目标级别的依赖会触发库的构建make install.foo。
但是,该解决方案具有以下缺点:
在配置CMake时将发出警告,Target "foo" has EXCLUDE_FROM_ALL set and will not be built by default but an install rule has been provided for it.但是CMake仍然会做正确的事情。
一旦运行make install.foo,随后的make install命令还将安装所有FOO相关文件,因为生成的FOO库和标头存在于二进制目录中。
| 归档时间: |
|
| 查看次数: |
6460 次 |
| 最近记录: |