根据生成生成文件时不可用的源文件在CMake中创建库

时间:2018-08-31 13:47:03

标签: cmake

我有一个构建两个库的CMake配置文件:

  1. 第三方库(在这里称为ThirdPartyLib),其中包含来自供应商的实时OS /板支持包。它是使用自动工具工具链在CMake外部构建的。
  2. 以前的库的扩展版本(在这里称为ExtendedThirdPartyLib)

不幸的是,我所需的某些源代码(各种工具)没有在(1)的普通构建脚本中构建。由于我不想弄乱供应商的构建脚本,因此我想添加另一个库(2),构建丢失的文件,从而从供应商处扩展该库。

我希望能够在CMakeFiles.txt中做类似的事情:

cmake_minimum_required(VERSION 3.2)
project(bsp)
include(ExternalProject)

ExternalProject_Add(
  ThirdPartyLib
  URL <http://some.url/bsp.tar.bz2
  BUILD_COMMAND make -C ../external/ThirdPartyLib/src
)
set_target_properties(ThirdPartyLib PROPERTIES EXCLUDE_FROM_ALL TRUE)

add_library(ExtendedThirdPartyLib
  ${CMAKE_CURRENT_BINARY_DIR}/some/path/missing_file1.c
  ${CMAKE_CURRENT_BINARY_DIR}/some/path/missing_file2.c
)
add_dependencies(ExtendedThirdPartyLib ThirdPartyLib)
target_include_directories(ExtendedThirdPartyLib PUBLIC
  ${CMAKE_CURRENT_BINARY_DIR}/some/path/include
)
target_link_libraries(ExtendedThirdPartyLib ThirdPartyLib)

这里的问题是,当CMake生成构建文件(它们是从供应商的压缩包中提取的)时,指向missing_file1.cmissing_file2.c的路径无效。 CMake退出并显示错误消息:“找不到源文件”。

是否有一种巧妙的方法可以完成这项工作?是否可以说服CMake在开始构建库时某些不存在的输入文件存在?还是有其他建议的方法可以解决此问题?

(我已经从供应商的tarball临时制作了我需要构建的文件的本地副本,但这当然不是一个好的解决方案。如果这些文件在供应商软件包的将来版本中被更改,我会忘记覆盖我的本地副本可能是一团糟...

另一个“解决方案”是在CMake外部创建一个小的makefile,并以某种方式在CMakeFiles.txt中使用另一个ExternalProject_Add。但这也不是一个好的解决方案,例如如果修改了编译器和链接器标志,我还需要记住更改makefile。)

1 个答案:

答案 0 :(得分:1)

我个人不喜欢ExternalProject_Add命令,因为它的确满足了我的口味,但是我离题了。

如果您执行类似的操作,bar在模拟ExtendedThirdPartyLib目标,该方法取决于生成的文件,该怎么办

cmake_minimum_required(VERSION 3.11)

project(lol C)

set(SOURCES lol.c) # only this file exists

add_library(lol ${SOURCES})

set(FOO_FILES "foo1.c" "foo2.c")

add_custom_command(OUTPUT ${FOO_FILES}
  COMMAND ${CMAKE_COMMAND} -E touch ${FOO_FILES}
  WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
  COMMENT "Creating ${FOO_FILES}"
  VERBATIM)

add_custom_target(foo DEPENDS ${FOO_FILES})

add_library(bar ${FOO_FILES})

add_dependencies(bar foo)

target_link_libraries(lol bar)

整个方法取决于以下事实:通过定制命令和相关的定制目标明确定义了采购生成/生成的文件的方法。

您应该修改自定义命令,以从tarball(可能需要使用curl或类似工具下载)中提取所需文件(例如,甚至可以调用某些外部脚本)。