19

我有一个生成 .so 库的现有 cmake 文件。我想修改它,这样它就会复制 .so 命名的其他东西。这大致是我所拥有的:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8.7)
PROJECT(test1)

SET(TEST_SOURCES f1.c)
ADD_LIBRARY(test SHARED ${TEST_SOURCES})
ADD_CUSTOM_COMMAND(
    OUTPUT custom1
    COMMAND cp libtest.so custom1
    DEPENDS libtest.so)

我意识到有比硬编码库名称更好的方法,我只是在尝试弄清楚如何让它工作的同时这样做。我缺少什么会导致我的复制/重命名自定义命令运行?注意:这不是安装时的事情。谢谢

4

3 回答 3

23

我会坚持你原来使用add_custom_command. 但是,我建议您使用add_custom_command(TARGET ...)表单而不是add_custom_command(OUTPUT ...).

OUTPUT版本旨在将输出文件用作同一 CMakeLists.txt 中不同 CMake 目标中的源文件。构建此目标时(就在开始时)调用自定义命令,因为目标需要该文件在该点存在。

在您的情况下,没有目标取决于您的文件 - 它是构建过程的产物。

如果使用add_custom_command(TARGET ...),则可以保证每次重建目标时都会执行该命令。如果原始目标(在这种情况下)被更新,使用add_custom_target要求您记住构建它。test它还不必要地添加到您的目标列表中——对于一个小项目来说可能不是问题,但对于更大的项目来说可能是这样。

这是我设置命令的方式:

SET(COPY_TO_PATH custom1)
ADD_CUSTOM_COMMAND(TARGET test POST_BUILD
                   COMMAND ${CMAKE_COMMAND} -E copy
                       $<TARGET_FILE:test>
                       ${COPY_TO_PATH}
                   COMMENT "Copying 'test' library to '${COPY_TO_PATH}'")

test这会将命令添加为's的构建后事件。正如您正确识别的那样,硬编码库名称并不好。因此 CMake 提供了“生成器表达式”来处理这个问题。生成器表达式$<TARGET_FILE:test>解析为由 创建的库的完整路径test,无论平台或编译器如何。请注意,生成器表达式只能在COMMAND参数中使用;例如,您不能在COMMENT零件中使用它们。

实际的命令是调用 CMake 本身 ( ${CMAKE_COMMAND}) 及其-E命令行选项。这提供了一种跨平台的方式来实现复制,因为cp它不是 Windows 命令。要查看所有-E选项,请运行cmake -E help.

于 2013-09-03T22:28:16.450 回答
12
add_custom_target(CopyAndRename
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/test.so ${CMAKE_BINARY_DIR}/SomeThingElse.so
)

add_custom_target 引入了一个名为 CopyAndRename 的新目标。您可以使用以下命令运行它:

make CopyAndRename
于 2013-09-03T11:16:12.263 回答
8

您可以考虑使用configure_file

configure_file("path-to-your-so-file.so" "new-path-to-your-so-file.so" COPYONLY)
于 2019-06-28T03:22:02.687 回答