CMake是否不抱怨不存在的文件?

时间:2018-07-04 18:51:18

标签: cmake

我知道可能没有解决方法,但是我需要为model.dll生成源文件dllmain.c。这是与可执行文件一起完成的,该可执行文件为我提取了一些基本信息,所以我当前的CMakeLists看起来像这样

add_executable(main ${SOURCE} otherListSourcesGoHere)

add_custom_command(
    TARGET main
    POST_BUILD
    COMMAND main.exe <--- Main built from above
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/jtox.py
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/dllgen.py <--- Python script generating a 
                                                       sourcefile for my DLL
    COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_DIR}/build/dllmain.c ${PROJECT_DIR}
)

add_library(
    ${CMAKE_PROJECT_NAME}
    SHARED
    ${PROJECT_DIR}/dllmain.c
    otherListSoucrsGoHereAswell
)

但是,当然,由于在exe完成并运行之前dllmain.c文件不存在,所以我无法使用它,因为它将返回错误。是否可以以某种方式执行此操作而不必运行两个CMakeList?

编辑1 在@Angew的帮助下,我发现您可以在add_custom_command中指定文件的输出,所以目前我有

add_executable(main ${SOURCE} otherListSourcesGoHere)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dllmain.c
    COMMAND main
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/jtox.py
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/dllgen.py -o ${CMAKE_CURRENT_BINARY_DIR}/dllmain.c
)

add_library(
    ${CMAKE_PROJECT_NAME}
    SHARED
    ${CMAKE_CURRENT_BINARY_DIR}/dllmain.c
    otherListSoucrsGoHereAswell
)

但是我有错误

CMakeFiles\bil.dir\build.make:60: recipe for target '../dllmain.c' failed
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/bil.dir/all' failed
makefile:82: recipe for target 'all' failed

我似乎没有找到解决方案。我该如何调试该问题?

编辑2

我通过在add_custom_command上添加DEPENDS main来解决此问题

add_custom_command(
    OUTPUT ${PROJECT_DIR}/dllmain.c
    DEPENDS main
    COMMAND echo "Executing main.exe"
    COMMAND main.exe
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND echo "JSON to XML with Python"
    COMMAND python ${PYTHON_SOURCE_DIR}/jtox.py
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/dllgen.py -o ${PROJECT_DIR}

1 个答案:

答案 0 :(得分:2)

执行此操作的正确方法是告诉CMake如何生成文件,而不是“手动”生成文件并将其与CMake保密。为此,请像这样更改您的CMakeList:

add_executable(main ${SOURCE} otherListSourcesGoHere)

add_custom_command(
    OUTPUT ${PROJECT_DIR}/dllmain.c
    COMMAND main
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/jtox.py
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/dllgen.py
    COMMAND ${CMAKE_COMMAND} -E copy ${PROJECT_DIR}/build/dllmain.c ${PROJECT_DIR}
)

add_library(
    ${CMAKE_PROJECT_NAME}
    SHARED
    ${PROJECT_DIR}/dllmain.c
    otherListSoucrsGoHereAswell
)

这样,CMake将知道文件${PROJECT_DIR}/dllmain.c已生成,以及如何生成它。它将用目标main构建的可执行文件正确替换main,并引入适当的构建依赖关系。


旁注:您应该考虑修改dllgen.py,以便它能够在您选择的目录中生成文件,并将其生成到二进制目录中。这样,您就不会因为构建伪影而污染源树,这是一个非常理想的属性:它允许您仅通过删除二进制目录即可恢复到原始状态。经过这一更改,CMakeList可能如下所示:

add_executable(main ${SOURCE} otherListSourcesGoHere)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/dllmain.c
    COMMAND main
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/jtox.py
    COMMAND ${CMAKE_COMMAND} -E sleep 1
    COMMAND python ${PYTHON_SOURCE_DIR}/dllgen.py -o ${CMAKE_CURRENT_BINARY_DIR}/dllmain.c
)

add_library(
    ${CMAKE_PROJECT_NAME}
    SHARED
    ${CMAKE_CURRENT_BINARY_DIR}/dllmain.c
    otherListSoucrsGoHereAswell
)