例如,我怎么知道我的可执行目标E是否依赖于我的库目标L?
让我们的图像E取决于L1和L2,但我不知道它们是否依赖于L.
target_link_libraries(E L1 L2)
我想在调用target_link_libraries之前从cmake本身获取列表,这样如果我检测到E依赖于两个不兼容的库,我可以做一些技巧.我玩了一些GetPrerequisites,但是这找到了对磁盘上现有库的依赖性,而不是正在构建的目标库.
谢谢
也许这是不可能的,我误读了cmake 3.2文档,但我创建一个自定义命令会在Makefile中创建一个自定义"目标",这样我就可以通过调用输出文件的名称来构建目标.CMake文档说:
在makefile术语中,这将以下列形式创建一个新目标:
Run Code Online (Sandbox Code Playgroud)OUTPUT: MAIN_DEPENDENCY DEPENDS COMMAND
所以我想我可以跑了make OUTPUT.也许文档将CMake目标与Makefile目标混淆了?
例如,
add_custom_command(OUTPUT foo_out
COMMAND post_process foo_in > foo_out
DEPENDS foo_in
)
Run Code Online (Sandbox Code Playgroud)
我想要做
make foo_out
Run Code Online (Sandbox Code Playgroud)
它会使foo_out.但是,如果我这样做,我明白了
make: **** No rule to make target `foo_out`. Stop.
Run Code Online (Sandbox Code Playgroud)
果然,cmake二进制输出目录中的任何文件中都不存在"foo_out"这个词.如果我把它改成这个
add_custom_target(bar DEPENDS foo_out)
add_custom_command(OUTPUT foo_out COMMAND post_process foo_in > foo_out)
Run Code Online (Sandbox Code Playgroud)
然后我就能做到
make bar
Run Code Online (Sandbox Code Playgroud)
我能做到
make foo_in
Run Code Online (Sandbox Code Playgroud)
但我还是做不到
make foo_out
Run Code Online (Sandbox Code Playgroud)
问题make bar是它不直观,因为实际的文件输出foo_out不是bar.
我该怎么做呢?
在我的例子中,我需要对标准可执行目标运行一个特殊的处理步骤,该目标将可选资源插入到ELF文件中.我希望能够将两个可执行文件作为Makefile目标,因此我可以构建裸ELF可执行文件以及注入资源的ELF可执行文件.
如果我正在编写自定义Makefile,这很简单!
foo_in: foo.c
$(CC) $< -o $@
foo_out: foo_in
post_process $< …Run Code Online (Sandbox Code Playgroud) 是否有一种合理的方法来获取包含构建命令的CMake变量或CMake将与目标关联的所有编译器标志?
尝试收集和维护可以添加标志的所有属性的列表似乎不切实际.此外,CMake必须在某处拥有此信息,因为它必须最终生成构建系统.
从CMake文档看起来这个功能曾经存在并且是通过调用提供的,build_command()但是它被替换了:
注意在3.0之前的CMake版本中,此命令返回一个命令行,该命令行直接调用当前生成器的本机构建工具.
是否有一个新命令可以提供旧的行为build_command()?
我试图获取链接到CMake中特定目标的所有库的绝对路径列表,以便在调用时使用add_custom_command.但是,get_target_property(_LINK_LIBRARIES ${TARGET} LINK_LIBRARIES仅包括直接依赖项(即target_link_libraries(${TARGET} ...)调用中使用的任何内容).
因此,如果我链接另一个CMake目标,例如mylibrary,列表将包括mylibrary,但仅作为名称并且没有可传递链接的库.由于此列表还可以包含任意复杂的生成器表达式,因此检查每个项目是否为目标并LINK_LIBRARIES递归检索它是不可行的.此外,目标可以在稍后的时间点指定,CMakeLists.txt并且if(TARGET mylibrary)将被跳过.
对于INCLUDE_DIRECTORIES和COMPILE_DEFINITIONS这是很容易解决的,因为虽然两者的行为类似时get_target_property被使用(不同之处在于所链接的目标显然不能在列表中),则形式的发电机表达$<TARGET_PROPERTY:${TARGET},INCLUDE_DIRECTORIES>产生的递归需要包括和定义所需的列表.但是,$<TARGET_PROPERTY:${TARGET},LINK_LIBRARIES>生成与get_target_property变体相同的列表.
如何检索所需的绝对路径列表?
示范:
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
file(WRITE a.cpp "void foo() {};\n")
file(WRITE b.cpp "int main(int, char**) { return 0; }\n")
find_package(Boost REQUIRED COMPONENTS filesystem system)
add_library(A STATIC a.cpp)
target_include_directories(A PUBLIC ${Boost_INCLUDE_DIRS})
target_link_libraries(A PUBLIC ${Boost_LIBRARIES})
# demonstrates (at configure time) that the LINK_LIBRARIES property can contain
# …Run Code Online (Sandbox Code Playgroud) 我需要在我的 CMake 脚本中支持自定义可执行链接命令,即 Synopsys VCS。VCS 是 GCC 的包装器,但它使用特殊语法来传递 LD 选项:
vcs -LDFLAGS "<LINK_FLAGS>" <LINK_LIBRARIES> <OBJECTS>
Run Code Online (Sandbox Code Playgroud)
链接可执行文件的规则存在于CMAKE_CXX_LINK_EXECUTABLE变量中,所以我尝试使用它:
set(CMAKE_CXX_LINK_EXECUTABLE "echo CXXFLAGS: <CMAKE_CXX_LINK_FLAGS> LINK_FLAGS: <LINKER_FLAGS> LINK_LIBRARIES: <LINK_LIBRARIES> OBJECTS: <OBJECTS> ")
Run Code Online (Sandbox Code Playgroud)
当我构建项目时,我得到:
CXXFLAGS:
LINK_FLAGS:
LINK_LIBRARIES: -rdynamic ../slib/libslib.a ../dlib/libdlib.so -Wl,-rpath,/home/ripopov/proj_cmake/build/dlib
OBJECTS: CMakeFiles/sim.dir/sc_main.cpp.o
Run Code Online (Sandbox Code Playgroud)
所以所有链接器标志和库都在 LINK_LIBRARIES
如何从中提取链接器标志LINK_LIBRARIES?