gpt4 book ai didi

c++ - 带有未知输出文件的 CMake ADD_CUSTOM_COMMAND

转载 作者:行者123 更新时间:2023-12-01 11:55:53 27 4
gpt4 key购买 nike

我有一个工具可以生成一些 cpp 和头文件,并想用 ADD_CUSTOM_COMMAND 添加它在构建期间自动执行它并将文件添加到项目中。问题是(大部分)输出文件的名称事先不知道。我如何添加这些文件?

最佳答案

简介
我假设您的目标不是使用 ADD_CUSTOM_COMMAND ,而是:

  • cmake 识别您生成的文件依赖于生成脚本 .这意味着:当你的生成脚本发生变化时,当你执行 cmake --build 时,文件会自动重新生成不同的文件名。下一次。
  • cmake 识别出您的可执行文件/库依赖于生成的文件,一旦这些文件重新生成,其文件名就会更改 .这意味着:由于 cmake --build 的相同调用,您的可执行文件/库被重建并使用重新生成的文件。

  • 主要问题是文件名必须在 configuration time 处知道。 ,以便在 build time 处知道依赖关系.这意味着您需要将文件的生成移动到 configuration时间。
    您要么需要获取文件名作为生成脚本的输出,要么使用文件通配符。通常我这样做 不推荐 的用法文件通配 ,因为它在适当的依赖关系方面有一些缺点。在您的情况下,通配符增加了实际值(value),但必须弥补劣势。
    下面我编译了一个完整的示例项目,它展示了它是如何工作的。我不是说这是标准的做法,但我认为它很好地满足了要求。
    示例设置
    我创建了一个最小设置,使所有这些工作:
    myProject
    |- CMakeLists.txt
    |- main.cpp
    |- myClass.h
    |- generate.sh
    myClass.h
    #ifndef MY_CLASS_H
    #define MY_CLASS_H
    int do_something_a();
    int do_something_b();
    #endif // MY_CLASS_H
    main.cpp
    #include "myClass.h"
    #include <iostream>

    int main(const int argc, const char **argv)
    {
    int a = do_something_a();
    int b = do_something_b();

    std::cout << "A:" << a << ", B:" << b << std::endl;

    return 0;
    }
    generate.sh
    只需创建 2 个 cpp 文件来实现 do_something_a()do_something_b() .生成的文件名包含一个随机数,也由 do_something_*() 返回。功能。文件被放入子目录 generated .
    #!/usr/bin/env bash

    # just creating a new subfolder; remove its contents if already existing
    dir1="generated"
    if [ ! -d ${dir1} ]; then mkdir ${dir1}; fi
    rm -rf ${dir1}/*

    # just create a cpp file with random name and implement do_something_a()
    var1=`date +%N`
    file1=${dir1}/myClass.${var1}.cpp
    echo '#include "myClass.h"' > ${file1}
    echo 'int do_something_a() { return '${var1}'; }' >> ${file1}

    # just create a cpp file with random name and implement do_something_b()
    var2=`date +%N`
    file2=${dir1}/myClass.${var2}.cpp
    echo '#include "myClass.h"' > ${file2}
    echo 'int do_something_b() { return '${var2}'; }' >> ${file2}
    CMakeLists.txt
    cmake_minimum_required (VERSION 3.10.2)

    project(useGenerateSourcesAtBuildStepProj
    VERSION 0.0.0.1
    DESCRIPTION "Minimum Example: Use Generated Files as dependency"
    LANGUAGES CXX
    )

    # just needed to force re-configuration, if generate.sh has changed.
    # that's the tweak to overcome glob disadvantage
    configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/generate.sh
    ${CMAKE_CURRENT_BINARY_DIR}/generate.sh
    )

    # regeneration command executed at configuration time
    # note: cannot call ${CMAKE_CURRENT_BINARY_DIR}/generate.sh, because not yet existing
    execute_process(
    COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/generate.sh
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
    )

    # globbing all generated files in sub directory `generated` at configuration time after execute_process
    FILE(GLOB GENERATED_SRC_FILES ${CMAKE_CURRENT_BINARY_DIR}/generated/*)

    # use generated files to build your executable
    add_executable(useGenerateSourcesAtBuildStep main.cpp ${GENERATED_SRC_FILES})
    target_include_directories(useGenerateSourcesAtBuildStep PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
    build
    配置:
    ../bin/Release$ cmake -G"Unix Makefiles" ../..
    输出:
    -- The CXX compiler identification is GNU 7.5.0
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: <dir>/bin/Release
    内部版本:
    ../bin/Release$ make
    输出:
    Scanning dependencies of target useGenerateSourcesAtBuildStep
    [ 25%] Building CXX object CMakeFiles/useGenerateSourcesAtBuildStep.dir/main.cpp.o
    [ 50%] Building CXX object CMakeFiles/useGenerateSourcesAtBuildStep.dir/generated/myClass.488106246.cpp.o
    [ 75%] Building CXX object CMakeFiles/useGenerateSourcesAtBuildStep.dir/generated/myClass.490335510.cpp.o
    [100%] Linking CXX executable useGenerateSourcesAtBuildStep
    [100%] Built target useGenerateSourcesAtBuildStep
    生成的文件:
    |- bin
    |- Release
    |- src
    |- generate.sh (due to configure_file)
    |- generated (directory containing all generated files)
    | |- myClass.488106246.cpp
    | |- myClass.490335510.cpp
    |- useGenerateSourcesAtBuildStep (your exectuable)
    更改 generate.sh 并使用 make 重建:
    ../bin/Release$ make
    输出:
    您可以看到配置步骤再次完成并且生成的文件更改了它们的名称,但在将它们全部链接到您的可执行文件之前重建:
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/tangoal/Documents/data/300_Projects/_software/CPP/lib/test/bin/Release
    Scanning dependencies of target useGenerateSourcesAtBuildStep
    [ 25%] Building CXX object CMakeFiles/useGenerateSourcesAtBuildStep.dir/generated/myClass.565834060.cpp.o
    [ 50%] Building CXX object CMakeFiles/useGenerateSourcesAtBuildStep.dir/generated/myClass.567160574.cpp.o

    [ 75%] Linking CXX executable useGenerateSourcesAtBuildStep
    [100%] Built target useGenerateSourcesAtBuildStep
    执行程序:
    ../Release/src$ ./useGenerateSourcesAtBuildStep
    输出:
    A:565834060, B:567160574

    关于c++ - 带有未知输出文件的 CMake ADD_CUSTOM_COMMAND,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32949430/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com