Я использую 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.
С этого момента мне понадобится список двоичных файлов (который довольно прост после установки выходного двоичного каталога) для создания целей CMake через add_executable
.
Я уже использую add_custom_command()
для компиляции .c
файлов с помощью моего пользовательского набора инструментов: в этом случае ничего не изменится, но на этот раз у меня нет доступных файлов битового кода (наоборот, .c
файлов), так как они создаются extract-bitcode
шаг.
EDIT:
Я следовал предложениям в комментариях и придумал это CMakeLists.txt
. Я вручную вставил список встроенных двоичных файлов, которые я хотел бы заменить на что-то автоматическое, а затем я добавил директивы для создания новых исполняемых файлов из файлов .bc
, сгенерированных одним из шагов ExternalProject_Add
.
К сожалению, 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.