How to use CMake to build multiple platforms from one master CMake project without cache problems

别说谁变了你拦得住时间么 提交于 2021-01-28 22:41:15

问题


I have two projects called A and B that have complete working CMakeLists.txt projects, and each project can be built completely without errors. I would like to have a master project defined in CMake that will build both A and B (and maybe a hundred other things eventually).

My top level CMakeLists.txt project looks like

add_subdirectory(A build-A)
add_subdirectory(B build-B)

and CMake can parse all the files and make can start building just fine.

The problem is that project A is for one architecture (x86_64) and B is for a different architecture (k1om) and when CMake invokes various features like

 find_package(Boost ....)

it caches the results of the library paths for the first architecture and reuses them (incorrectly!) for all subsequent architectures. We have Boost compiled for both x86_64 and k1om.

Is there a way to have CMake do what I want to do, by entirely invalidating the cache between the two projects? Something like this would be ok:

add_subdirectory(A build-A)
cmake_invalidate_cache_and_forget_everthing_that_just_happened()
add_subdirectory(B build-B)
cmake_invalidate_cache_and_forget_everthing_that_just_happened()
...

I am fully aware that I can just make a shell script that does this and just runs cmake multiple times in different output directories, but it would be really nice to have a uniform "entry" point for all projects written in CMake.


回答1:


I'd recommend using a "super-build" setup whereby each subproject is included via ExternalProject_Add rather than add_subdirectory. This gives very clean separation between the subprojects' builds. I think you'd be fighting CMake very hard by trying to tinker with the generated CMakeCache.txt!

However, I've never tried actually doing this where the architecture differs between subprojects. So all I can do is suggest you try it - I think it should work.

(This article may help).




回答2:


I think using ExternalProject, as Fraser suggests is the best practice for your setup, but I don't think it's going to solve the issue your having. Correct me if I'm wrong, but it sounds like you're using the same build tree for both platforms. Is that correct? If so, I can't see what can be gained from that.

If I'm wrong and you're just trying to prevent certain projects from configuring on certain architectures, then you should look into CMake's architecture blocks, like if(WIN32) ... if (CMAKE_SIZEOF_VOID_P 8) ... there are many other ways to limit code exposure base on compiler, 32 vs 64 Windows, *nix, MAC, etc ...

If I'm still not understanding, then my apologies, perhaps you can attempt a clear explanation. Perhaps all you need it the unset command for your cache variables that are incorrectly set in cache because of a different architecture. See: http://www.cmake.org/cmake/help/v3.0/command/unset.html

If that's the case though, you really should reconsider the design of your project because that approach sounds like an unmaintainable mess. Sorry.




回答3:


I got it to work with ExternalProject_Add (Thank You Fraser). Here is what it looks like:

cmake_minimum_required(VERSION 2.8.4)
project(Demo1)
include(ExternalProject)

ExternalProject_Add(
  A-build 
  SOURCE_DIR ${CMAKE_SOURCE_DIR}/A
  INSTALL_COMMAND ""
)

ExternalProject_Add( 
  B-build   
  SOURCE_DIR ${CMAKE_SOURCE_DIR}/B
  INSTALL_COMMAND ""
)


来源:https://stackoverflow.com/questions/29111252/how-to-use-cmake-to-build-multiple-platforms-from-one-master-cmake-project-witho

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!