问题
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