【问题标题】:How to reload cmake targets如何重新加载 cmake 目标
【发布时间】:2016-09-15 08:01:32
【问题描述】:

以下是我的场景。我有一个顶级 CMakeList.txt 和另外 2 个内部 CMakeList.txt。在顶级 cmake 中,我有 3 个自定义目标,它们是 copybuildcopyandbuild。正如名称所指定的 make copy 将源目录(即 dir1、dir2)复制到 ${CMAKE_SOURCE_DIR}。 make build 创建库和可执行文件。 make copyandbuild(复制+构建)。

从构建目录运行cmake .. 成功完成。

如果我运行 make copyandbuild 它正在复制到 ${CMAKE_SOURCE_DIR} 但在构建时它显示错误

No rule to make target `dir1/libmylib.so', needed by `CMaketargetdbuild'.  Stop
  • 我的项目
    • 目录1
      • CMakeLists.txt
    • 目录2
      • CMakeLists.txt
    • CMakeLists.txt

如果我按以下顺序执行命令,它就可以工作。

  • cmake ..
  • 进行复制和构建
  • cmake ..
  • 进行构建

我的要求是它应该在不运行 cmake 的情况下工作并再次进行构建,因为 copyandbuild 做同样的工作。

顶级 CMakeLists.txt:

  cmake_minimum_required(VERSION 2.6)

  cmake_minimum_required(VERSION 2.6)
  set(RE_BUILD make rebuild_cache)
  set(OUTPUT_DIR ${CMAKE_SOURCE_DIR}/../)


  if(EXISTS ${CMAKE_SOURCE_DIR}/dir1)
  message(WARNING "Found dir1 dir")
  add_subdirectory(dir1 EXCLUDE_FROM_ALL)
  else()
  message(WARNING "Couldn't find dir1 directory ")
  endif()


  if(EXISTS ${CMAKE_SOURCE_DIR}/dir2)
  add_subdirectory(dir2 EXCLUDE_FROM_ALL)
  else()
  message(WARNING "Couldn't find dir2 directory")
  endif()

  set(MOVE_LIB_COMMAND mv src/myapp . && mv dir1/mylib .)
  set(COPY_COMMAND cp -r ../sourceCode1 ../dir1 && cp -r ../sourceCode2 ../dir2)

  set(CLEAN_DIR1_COMMAND cmake -E remove_directory ${CMAKE_SOURCE_DIR}/dir1)
  set(CLEAN_DIR2_COMMAND cmake -E remove_directory ${CMAKE_SOURCE_DIR}/dir2)

  set(SET_SLEEP sync)

  #Copy command
  add_custom_target(
  copy ${COPY_COMMAND}
  COMMAND ${RE_BUILD} 
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
  )
  #Compilation
  add_custom_target(
  build
  COMMAND ${MOVE_LIB_COMMAND}
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
  DEPENDS mylib myapp
  )

  #copy and compile
  add_custom_target(
  copyandbuild  
  COMMAND ${MOVE_LIB_COMMAND} 
  WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
  DEPENDS copy mylib myapp
  )

  add_custom_command(TARGET copy POST_BUILD
               COMMAND ${SET_SLEEP} 
  )
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")

dir1 CMake 是:

cmake_minimum_required(VERSION 2.6)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")


include_directories(
${MY_APP_INCLUDE_DIRS}
)

link_directories(
${MY_APP_LIBDIR}
)

add_library(mylib
SHARED 
com/*.cpp
)
target_link_libraries(mylib myapp_lib)

dir2 CMake 是:

cmake_minimum_required(VERSION 2.6)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
include_directories(
${MY_APP_INCLUDE_DIRS}
)
link_directories(
${MY_APP_LIBDIR}
)

【问题讨论】:

  • 你能以精简的方式分享 CmakeLists.txt 的内容吗?
  • 请清理您的代码 sn-p:使变量一致(例如,您设置变量 RE_BUILD_COMMAND,但使用 RE_BUILD),删除未在 sn-p 中使用的变量定义.据我从代码中了解到,您希望 add_custom_target 的 DEPENDS 选项添加来自其他目标的依赖项。但它实际上添加了来自文件的依赖项。要添加目标之间的依赖关系,请使用命令add_dependencies

标签: cmake


【解决方案1】:

您使用 CMake 的方式妨碍了其正常功能。通过在许多地方显式调用 shell 命令,当您可以使用 CMake 内置功能时,您正在剥夺 CMake 可用于构建程序的任何上下文。此外,在 CMake 中使用像 *.cpp 这样的通配符被认为是不好的做法。而且你有许多重复的语句——你不需要cmake_minimum_required() 或设置除了顶层之外的编译器标志。

简而言之,您在顶层的CMakeLists.txt 应该看起来更像这样:

cmake_minimum_required(VERSION 2.6)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")

add_subdirectory(dir1 EXCLUDE_FROM_ALL)

您不需要复制源文件——只需从它们所在的位置构建它们即可,例如您的 dir1/CMakeLists.txt 可能是:

add_library(mylib
  SHARED
  sourceCode1/mylib.cpp
)

保持简单。让它工作。如果您需要添加缺少的功能,然后提出问题。

【讨论】:

  • 谢谢!给你的建议,实际上我在这里使用复制只是为了简单理解的目的,实时dir1和dir2将从一些外部应用程序生成。一旦生成完成,我的copyandbuild命令应该能够编译生成的代码。
  • @venkat2010:那么您应该将您的问题重新表述为一个完全有效但最小的示例。由于我们没有您的代码生成器,您可以使用一个简单的bash 脚​​本来编写一个 .cpp 文件或其他文件。
猜你喜欢
  • 1970-01-01
  • 2021-09-04
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 2020-08-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多