【问题标题】:Is it possible to create CMake targets and file globs after compile time?编译后是否可以创建 CMake 目标和文件 glob?
【发布时间】:2019-06-17 23:49:19
【问题描述】:

我正在使用 CMake 通过ExternalProject_Add 编译一个外部项目。项目编译完美,但我需要根据项目构建的二进制文件创建 其他 目标。

基本上,外部二进制文件是我要创建的目标的依赖项。

这意味着我无法为不存在的文件创建目标(还),因此 CMake 会抱怨。由于这个确切原因,我无法创建一组文件 (file(GLOB files $external_build/bin)) 或使用任何其他 CMake 规则,因为它们是在配置时进行评估的。

有没有办法在编译后评估 CMake 规则?

用例

我正在使用 LLVM,并且我已经修改了 llc,将自定义通行证集成到其中。我需要在现实世界的项目中测试我修改后的llc 可执行文件,例如,这是我直接从源代码树编译 GNU 的 binutils 的方法:

set(BINUTILS_URL "https://ftp.gnu.org/gnu/binutils/binutils-2.32.tar.xz")
set(BINUTILS_SHA256 "0ab6c55dd86a92ed561972ba15b9b70a8b9f75557f896446c82e8b36e473ee04")
set(BINUTILS_PREFIX ${CMAKE_BINARY_DIR}/binutils)
set(BINUTILS_BINARY_DIR ${BINUTILS_PREFIX}/bin)

find_program(MAKE_BIN NAMES gmake nmake make)
ExternalProject_Add(binutils
        URL ${BINUTILS_URL}
        URL_HASH SHA256=${BINUTILS_SHA256}

        BUILD_IN_SOURCE On
        GIT_PROGRESS On
        CONFIGURE_COMMAND ${WLLVM_CONFIGURE_FLAGS} ./configure --prefix ${BINUTILS_PREFIX}
        BUILD_COMMAND ${WLLVM_COMPILE_FLAGS} ${MAKE_BIN} -j${JOBS}
        )

ExternalProject_Add_Step(binutils
        extract-bitcode
        COMMENT "Extracting binutils' bitcode..."
        DEPENDEES install
        WORKING_DIRECTORY ${BINUTILS_BINARY_DIR}
        COMMAND ${EXTRACT_BC_EXE} ${BINUTILS_BINARY_DIR}
        )

为了测试llc,我需要处理LLVM 的位码,所以我使用wllvm 来编译LLVM 的位码并将其直接嵌入到binutils 的已编译二进制文件中。

从现在开始,我需要二进制文件列表(设置输出二进制目录后非常简单)通过add_executable 创建 CMake 目标。

我已经使用add_custom_command() 用我的自定义工具链编译.c 文件:这种情况不会有什么不同,但这次我没有可用的位码文件(与.c 文件相反),因为它们是由extract-bitcode 步骤。

编辑: 我遵循了 cmets 中的建议,并提出了这个CMakeLists.txt。我已经手动插入了构建的二进制文件列表,我想用自动化的东西替换它,然后我添加了指令以从ExternalProject_Add 的步骤之一生成的.bc 文件中创建新的可执行文件。

不幸的是,CMake 抱怨循环依赖。我想我必须找到一种方法让 CMake 了解 .bc 文件。

这是我的CMakeLists.txt

set(BINUTILS_URL "https://ftp.gnu.org/gnu/binutils/binutils-2.32.tar.xz")
set(BINUTILS_SHA256 "0ab6c55dd86a92ed561972ba15b9b70a8b9f75557f896446c82e8b36e473ee04")
set(BINUTILS_PREFIX ${CMAKE_BINARY_DIR}/binutils)
set(BINUTILS_BINARY_DIR ${BINUTILS_PREFIX}/bin)
set(BINUTILS_BINARY_NAMES
        addr2line
        ar
        as
        c++filt
        elfedit
        gprof
        ld
        ld.bfd
        nm
        objcopy
        objdump
        ranlib
        readelf
        size
        strings
        strip
        )

find_program(MAKE_BIN NAMES gmake nmake make)

# This step will compile GNU's binutils
ExternalProject_Add(binutils
        URL ${BINUTILS_URL}
        URL_HASH SHA256=${BINUTILS_SHA256}

        BUILD_IN_SOURCE On
        GIT_PROGRESS On
        CONFIGURE_COMMAND ${WLLVM_CONFIGURE_FLAGS} ./configure --prefix ${BINUTILS_PREFIX}
        BUILD_COMMAND ${WLLVM_COMPILE_FLAGS} ${MAKE_BIN} -j${JOBS}
        )

# This step will create the ${binutil-exec}.bc files needed in the next step
ExternalProject_Add_Step(binutils
        extract-bitcode
        COMMENT "Extracting binutils' bitcode..."
        DEPENDEES install
        WORKING_DIRECTORY ${BINUTILS_BINARY_DIR}
        COMMAND ${EXTRACT_BC_EXE} ${BINUTILS_BINARY_DIR}
        )

# use llc on the ${binutils-exec}.bc files
foreach (exec_name ${BINUTILS_BINARY_NAMES})
    set(llc_exec_name "${exec_name}-llc")

    add_dependencies(binutils ${llc_exec_name})

    add_executable(${llc_exec_name} ${llc_exec_name}.s)
    target_link_libraries(${llc_exec_name} c)

    add_custom_command(
            OUTPUT
            ${llc_exec_name}.s
            DEPENDS
            binutils llc
            COMMAND
            $<TARGET_FILE:llc>
            ARGS
            ${BINUTILS_BINARY_DIR}/${llc_exec_name}.bc -o ${llc_exec_name}.s
    )
endforeach ()


这是运行cmake时的CMake错误:

CMake Error: The inter-target dependency graph contains the following strongly connected component (cycle):
  "objcopy-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "elfedit-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "addr2line-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "strip-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "nm-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "as-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "c++filt-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "binutils" of type UTILITY
    depends on "objcopy-llc" (strong)
    depends on "elfedit-llc" (strong)
    depends on "addr2line-llc" (strong)
    depends on "strip-llc" (strong)
    depends on "nm-llc" (strong)
    depends on "as-llc" (strong)
    depends on "c++filt-llc" (strong)
    depends on "ar-llc" (strong)
    depends on "ld.bfd-llc" (strong)
    depends on "objdump-llc" (strong)
    depends on "ld-llc" (strong)
    depends on "gprof-llc" (strong)
    depends on "readelf-llc" (strong)
    depends on "size-llc" (strong)
    depends on "ranlib-llc" (strong)
    depends on "strings-llc" (strong)
  "ar-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "ld.bfd-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "objdump-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "ld-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "gprof-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "readelf-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "size-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "ranlib-llc" of type EXECUTABLE
    depends on "binutils" (strong)
  "strings-llc" of type EXECUTABLE
    depends on "binutils" (strong)
At least one of these targets is not a STATIC_LIBRARY.  Cyclic dependencies are allowed only among static libraries.

【问题讨论】:

  • 你不知道要构建哪些二进制文件吗?
  • 您能否在此处提供有关您的用例的更多背景信息?如果 cmake 以您希望的方式工作,您会使用什么流程?
  • 您可以将ExternalProject_Add创建的目标添加为依赖项。不过,这不会注入包含或链接路径,这可能需要更多的工作。
  • @VTT:是的,我已经考虑过了。我正在尝试自动获取二进制文件列表,因为这是一个我会为几个外部项目重复的过程,我希望它尽可能地即插即用。如果存在,我会优先考虑自动方法。
  • @MilesBudnek:我没想到,谢谢。这应该可以解决我的部分问题。

标签: c++ cmake


【解决方案1】:

这可以通过 DEPENDS 关键字来完成

ADD_CUSTOM_COMMAND(
  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/eLut.h
  COMMAND $<TARGET_FILE:eLut> ARGS > ${CMAKE_CURRENT_BINARY_DIR}/eLut.h
  DEPENDS eLut)

例如见here

还举了一个例子here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 2012-10-25
    • 2020-07-26
    • 2021-10-20
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多