如何使用 CMake 从一个主 CMake 项目构建多个平台而不会出现缓存问题
How to use CMake to build multiple platforms from one master CMake project without cache problems
我有两个名为 A
和 B
的项目,它们具有完整的工作 CMakeLists.txt 项目,并且每个项目都可以完全无错误地构建。我想在 CMake 中定义一个 master
项目,它将构建 A
和 B
(最终可能还有一百个其他东西)。
我的顶级CMakeLists.txt
项目看起来像
add_subdirectory(A build-A)
add_subdirectory(B build-B)
CMake 可以解析所有文件,make 可以开始构建。
问题是项目 A
是针对一种架构 (x86_64
) 而 B
是针对另一种架构 (k1om
) 并且当 CMake 调用各种功能时喜欢
find_package(Boost ....)
它为第一个架构缓存库路径的结果,并为所有后续架构重用它们(错误地!)。我们为 x86_64
和 k1om
.
编译了 Boost
有没有办法让 CMake 做我想做的事情,完全使两个项目之间的缓存失效?像这样就可以了:
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()
...
我完全知道我可以制作一个 shell 脚本来执行此操作,并在不同的输出目录中多次运行 cmake
,但是如果有一个统一的 "entry" 为所有用 CMake 编写的项目加分。
我建议使用 "super-build" 设置,其中每个子项目都通过 ExternalProject_Add
而不是 add_subdirectory
包含。这在子项目的构建之间提供了非常清晰的分离。我认为你会通过尝试修补生成的 CMakeCache.txt!
来非常努力地与 CMake 作斗争
但是,我从未尝试过在子项目之间的体系结构不同的情况下实际执行此操作。所以我所能做的就是建议你尝试一下 - 我认为它应该有效。
(This article 可能有帮助)。
我认为使用 ExternalProject,正如 Fraser 所建议的,是您设置的最佳实践,但我认为它不会解决您遇到的问题。如果我错了请纠正我,但听起来您在两个平台上都使用相同的构建树。那是对的吗?如果是这样,我看不出能从中得到什么。
如果我错了,而你只是想阻止某些项目在某些架构上进行配置,那么你应该查看 CMake 的架构块,比如 if(WIN32) ... if (CMAKE_SIZEOF_VOID_P 8) ...还有许多其他方法可以根据编译器限制代码公开,32 位与 64 位 Windows、*nix、MAC 等...
如果我还是不明白,那么我很抱歉,也许你可以试着解释清楚。也许您只需要 unset 命令来处理由于不同架构而在缓存中错误设置的缓存变量。参见:http://www.cmake.org/cmake/help/v3.0/command/unset.html
如果是这种情况,您真的应该重新考虑项目的设计,因为这种方法听起来像是无法维护的一团糟。对不起。
我让它与 ExternalProject_Add
一起工作(谢谢 )。这是它的样子:
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 ""
)
我有两个名为 A
和 B
的项目,它们具有完整的工作 CMakeLists.txt 项目,并且每个项目都可以完全无错误地构建。我想在 CMake 中定义一个 master
项目,它将构建 A
和 B
(最终可能还有一百个其他东西)。
我的顶级CMakeLists.txt
项目看起来像
add_subdirectory(A build-A)
add_subdirectory(B build-B)
CMake 可以解析所有文件,make 可以开始构建。
问题是项目 A
是针对一种架构 (x86_64
) 而 B
是针对另一种架构 (k1om
) 并且当 CMake 调用各种功能时喜欢
find_package(Boost ....)
它为第一个架构缓存库路径的结果,并为所有后续架构重用它们(错误地!)。我们为 x86_64
和 k1om
.
有没有办法让 CMake 做我想做的事情,完全使两个项目之间的缓存失效?像这样就可以了:
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()
...
我完全知道我可以制作一个 shell 脚本来执行此操作,并在不同的输出目录中多次运行 cmake
,但是如果有一个统一的 "entry" 为所有用 CMake 编写的项目加分。
我建议使用 "super-build" 设置,其中每个子项目都通过 ExternalProject_Add
而不是 add_subdirectory
包含。这在子项目的构建之间提供了非常清晰的分离。我认为你会通过尝试修补生成的 CMakeCache.txt!
但是,我从未尝试过在子项目之间的体系结构不同的情况下实际执行此操作。所以我所能做的就是建议你尝试一下 - 我认为它应该有效。
(This article 可能有帮助)。
我认为使用 ExternalProject,正如 Fraser 所建议的,是您设置的最佳实践,但我认为它不会解决您遇到的问题。如果我错了请纠正我,但听起来您在两个平台上都使用相同的构建树。那是对的吗?如果是这样,我看不出能从中得到什么。
如果我错了,而你只是想阻止某些项目在某些架构上进行配置,那么你应该查看 CMake 的架构块,比如 if(WIN32) ... if (CMAKE_SIZEOF_VOID_P 8) ...还有许多其他方法可以根据编译器限制代码公开,32 位与 64 位 Windows、*nix、MAC 等...
如果我还是不明白,那么我很抱歉,也许你可以试着解释清楚。也许您只需要 unset 命令来处理由于不同架构而在缓存中错误设置的缓存变量。参见:http://www.cmake.org/cmake/help/v3.0/command/unset.html
如果是这种情况,您真的应该重新考虑项目的设计,因为这种方法听起来像是无法维护的一团糟。对不起。
我让它与 ExternalProject_Add
一起工作(谢谢
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 ""
)