shell - 使用 shell 命令作为 INSTALL_COMMAND 到 ExternalProject_Add

标签 shell cmake external-project

cmake的ExternalProject_AddINSTALL_COMMAND阶段是否可以使用任何shell命令?例如

ExternalProject_Add(leveldb 
    GIT_REPOSITORY git@github.com:google/leveldb.git 
    GIT_TAG v1.18
    CONFIGURE_COMMAND ./build_detect_platform build.settings .
    BUILD_COMMAND make -j 8 
    BUILD_IN_SOURCE 1        
    INSTALL_COMMAND ""
)

# INSTALL_COMMAND "mkdir -p ${CMAKE_BINARY_DIR}/lib/ \
#     && find . \( -name \"*${CMAKE_SHARED_LIBRARY_SUFFIX}\" -or -name \"*${CMAKE_STATIC_LIBRARY_SUFFIX}\" \
#     -exec cp {} ${CMAKE_BINARY_DIR}/lib/\;\) \
#     && cp -r ./include ${CMAKE_BINARY_DIR}")

我注释掉了我要使用的INSTALL_COMMAND,find和cp似乎不允许,“没有这样的文件或目录,错误127”是使用这个的结果。

最佳答案

直接回答:

install(CODE "execute_process(...)")

The SCRIPT and CODE signature:

install([[SCRIPT <file>] [CODE <code>]] [...])

The SCRIPT form will invoke the given CMake script files during installation. If the script file name is a relative path it will be interpreted with respect to the current source directory. The CODE form will invoke the given CMake code during installation. Code is specified as a single argument inside a double-quoted string. For example, the code

install(CODE "MESSAGE(\"Sample install message.\")")

will print a message during installation.

深思:

您可能急于快速完成某件事。如果您有时间,请考虑这一点,或者您可以回到它并修复它。

人们喜欢 cmake 的主要原因之一是它的跨平台特性。考虑到这一方面的正确编码的任何项目都可以在 Linux 或 Windows 或任何其他操作系统支持的系统上运行。如果开发人员考虑到这一点,各种生成器将可以正常工作。我的建议是将shell命令以跨平台的方式转换成cmake,放在一个单独的*.cmake文件中,并使用cmake -E选项执行。

这是我过去从事的一个工作项目的摘录。

project_build_steps.cmake

message(VAR1=${VAR1}) # These variables can be passed from the invocation place
message(VAR2=${VAR2}) # You can use them in the build steps

if("${BUILD_STEP}" STREQUAL "patch")
    message("BUILD_STEP: patch")
    # Put your patch steps using cmake
endif()
if("${BUILD_STEP}" STREQUAL "configure")
    message("BUILD_STEP: configure")
    # Put your configure steps using cmake
endif()

if("${BUILD_STEP}" STREQUAL "build")
    message("BUILD_STEP: build")
    # Put your build steps using cmake
endif()

if("${BUILD_STEP}" STREQUAL "install")
    message("BUILD_STEP: install")
    # Put your install steps using cmake
endif()

CMakeLists.txt(选项 1)

set(CMAKE_COMMAND /usr/bin/cmake)
set(PROJECT_BUILD_STEPS_FILE project_build_steps.cmake)

ExternalProject_Add(
    project_name
    SOURCE_DIR /path/to/project/source
    PATCH_COMMAND ${CMAKE_COMMAND} -DBUILD_STEP=patch -P ${PROJECT_BUILD_STEPS_FILE}
    CONFIGURE_COMMAND ${CMAKE_COMMAND} -DBUILD_STEP=configure -P ${PROJECT_BUILD_STEPS_FILE}
    BUILD_COMMAND ${CMAKE_COMMAND} -DBUILD_STEP=build -P ${PROJECT_BUILD_STEPS_FILE}
    INSTALL_COMMAND ${CMAKE_COMMAND} -DBUILD_STEP=install -P ${PROJECT_BUILD_STEPS_FILE}
)

如果您不想使用 ExternalProject_Add,您可以使用以下内容。这还将为您提供单独的构建目标,例如 make project_patch、make project_configure、make project_build、make project_install。

CMakeLists.txt(选项 2)

set(CMAKE_COMMAND /usr/bin/cmake)
set(PROJECT_BUILD_STEPS_FILE project_build_steps.cmake)

set(STAMP_FILE_PROJECT_PATCH .project_patch_done)
add_custom_command(
    OUTPUT ${STAMP_FILE_PROJECT_PATCH}
    COMMAND ${CMAKE_COMMAND} -DVAR1=value1 -DSTEP=patch -P ${PROJECT_BUILD_STEPS_FILE}
    COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_FILE_PROJECT_PATCH}
)

add_custom_target(project_patch DEPENDS ${STAMP_FILE_PROJECT_PATCH})

set(STAMP_FILE_PROJECT_CONFIGURE .project_configure_done)
add_custom_command(
    OUTPUT ${STAMP_FILE_PROJECT_CONFIGURE}
    COMMAND ${CMAKE_COMMAND} -DSTEP=configure -P ${PROJECT_BUILD_STEPS_FILE}
    COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_FILE_PROJECT_CONFIGURE}
)

add_custom_target(project_configure DEPENDS project_patch ${STAMP_FILE_PROJECT_CONFIGURE})


set(STAMP_FILE_PROJECT_BUILD .project_build_done)
add_custom_command(
    OUTPUT ${STAMP_FILE_PROJECT_BUILD}
    COMMAND ${CMAKE_COMMAND} -DSTEP=build -P ${PROJECT_BUILD_STEPS_FILE}
    COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_FILE_PROJECT_BUILD}
    VERBATIM
)

add_custom_target(project_build DEPENDS project_configure ${STAMP_FILE_PROJECT_BUILD})
set(STAMP_FILE_PROJECT_INSTALL .project_install_done)
add_custom_command(
    OUTPUT ${STAMP_FILE_PROJECT_INSTALL}
    COMMAND ${CMAKE_COMMAND} -DSTEP=install -P ${PROJECT_INSTALL_STEPS_FILE}
    COMMAND ${CMAKE_COMMAND} -E touch ${STAMP_FILE_PROJECT_INSTALL}
    VERBATIM
)

add_custom_target(project_install DEPENDS project_build ${STAMP_FILE_PROJECT_INSTALL})

关于shell - 使用 shell 命令作为 INSTALL_COMMAND 到 ExternalProject_Add,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30205379/

相关文章:

cmake - MSBuild:错误 MSB3073 命令 'setlocal VCEnd' 已退出,代码为 1

xcode - CMake:如何在 *nix 系统上使用所有内核构建外部项目?

c++ - 如何将使用 ExternalProject_Add 安装的库添加到目标包括

linux - 按时间排序访问日志

linux - sort -c 输出被重定向到文件 : Linux command

linux - 在 shell 中解析 ps 和 grep 输出

cmake - 如何测试CMake是否使用find_library找到了一个库

c++ - 在 Mac OS X Mojave 上使用 AppleClang 编译和链接 OpenMP

c++ - 使用包含空格的命令时 ExternalProject_Add 的奇怪行为

linux - 在ubuntu的.bashrc文件中调用一个隐藏的shell脚本文件