我想塞满我们的源代码树生成CMake的文件...而且,更重要的是不允许的人,从加强对现有不让他们Makefiles
不在我们使用CMake的为同一构建过程的一部分。 (最好不要问)
我想出了这样做的方法是让我的前几行CMakeLists.txt
,具体如下:
if("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
message(SEND_ERROR "In-source builds are not allowed.")
endif("${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}")
但是,做这种方式似乎过于冗长。 另外,如果我尝试了在源构建它仍然创建了CMakeFiles/
目录中, CMakeCache.txt
源代码树中的文件之前抛出的错误。
我缺少一个更好的方式来做到这一点?
我觉得我喜欢你的方式。 CMake的邮件列表做得很好,在回答这些类型的问题。
作为一个方面说明:您可以创建在失败目录下的“cmake的”可执行文件。 根据与否“” 在他们的路径(在Linux上)。 你甚至可以符号链接/斌/假。
在Windows中,我不知道,如果你的当前目录中的文件是第一还是没找到。
CMake的有两个无证选项: CMAKE_DISABLE_SOURCE_CHANGES
和CMAKE_DISABLE_IN_SOURCE_BUILD
cmake_minimum_required (VERSION 2.8)
# add this options before PROJECT keyword
set(CMAKE_DISABLE_SOURCE_CHANGES ON)
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
project (HELLO)
add_executable (hello hello.cxx)
-
andrew@manchester:~/src% cmake .
CMake Error at /usr/local/share/cmake-2.8/Modules/CMakeDetermineSystem.cmake:160 (FILE):
file attempted to write a file: /home/andrew/src/CMakeFiles/CMakeOutput.log
into a source directory.
/home/selivanov/cmake-2.8.8/Source/cmMakefile.cxx
bool cmMakefile::CanIWriteThisFile(const char* fileName)
{
if ( !this->IsOn("CMAKE_DISABLE_SOURCE_CHANGES") )
{
return true;
}
// If we are doing an in-source build, than the test will always fail
if ( cmSystemTools::SameFile(this->GetHomeDirectory(),
this->GetHomeOutputDirectory()) )
{
if ( this->IsOn("CMAKE_DISABLE_IN_SOURCE_BUILD") )
{
return false;
}
return true;
}
// Check if this is subdirectory of the source tree but not a
// subdirectory of a build tree
if ( cmSystemTools::IsSubDirectory(fileName,
this->GetHomeDirectory()) &&
!cmSystemTools::IsSubDirectory(fileName,
this->GetHomeOutputDirectory()) )
{
return false;
}
return true;
}
包括像函数这个 。 它类似于你这些差异做什么:
它被封装在一个功能,当你包括被称为PreventInSourceBuilds.cmake
模块。 你的主要的CMakeLists.txt必须包括它:
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/CMake) include(PreventInSourceBuilds)
它使用get_filename_component()与该比较的路径之前解析的真实路径的符号链接参数。
在情况下,github上链路的变化,这里的模块的源代码(其应被放置在PreventInSouceBuilds.cmake
,在一个称为目录CMake
,在上面的例子):
#
# This function will prevent in-source builds
function(AssureOutOfSourceBuilds)
# make sure the user doesn't play dirty with symlinks
get_filename_component(srcdir "${CMAKE_SOURCE_DIR}" REALPATH)
get_filename_component(bindir "${CMAKE_BINARY_DIR}" REALPATH)
# disallow in-source builds
if("${srcdir}" STREQUAL "${bindir}")
message("######################################################")
message("# ITK should not be configured & built in the ITK source directory")
message("# You must run cmake in a build directory.")
message("# For example:")
message("# mkdir ITK-Sandbox ; cd ITK-sandbox")
message("# git clone http://itk.org/ITK.git # or download & unpack the source tarball")
message("# mkdir ITK-build")
message("# this will create the following directory structure")
message("#")
message("# ITK-Sandbox")
message("# +--ITK")
message("# +--ITK-build")
message("#")
message("# Then you can proceed to configure and build")
message("# by using the following commands")
message("#")
message("# cd ITK-build")
message("# cmake ../ITK # or ccmake, or cmake-gui ")
message("# make")
message("#")
message("# NOTE: Given that you already tried to make an in-source build")
message("# CMake have already created several files & directories")
message("# in your source tree. run 'git status' to find them and")
message("# remove them by doing:")
message("#")
message("# cd ITK-Sandbox/ITK")
message("# git clean -n -d")
message("# git clean -f -d")
message("# git checkout --")
message("#")
message("######################################################")
message(FATAL_ERROR "Quitting configuration")
endif()
endfunction()
AssureOutOfSourceBuilds()
我有一个cmake()
在我的壳功能.bashrc
/ .zshrc
与此类似:
function cmake() {
# Don't invoke cmake from the top-of-tree
if [ -e "CMakeLists.txt" ]
then
echo "CMakeLists.txt file present, cowardly refusing to invoke cmake..."
else
/usr/bin/cmake $*
fi
}
我喜欢这个小仪式的解决方案。 它摆脱了我的同事们最大的抱怨,当我们切换到CMake的,但它并不能阻止人们谁真正想要做一个在源/顶级的树从做建那么,他们可以调用/usr/bin/cmake
直接(或不使用包装功能的话)。 而且这是愚蠢的简单。
你可以配置你的.bashrc文件中像这样一个
看看功能cmakekde和kdebuild。 设置编译和SRC ENV。 根据您的需求变量和编辑这些功能。 这只会建立buildDir而非SRCDIR
对于那些在Linux上:
添加到顶级的CMakeLists.txt:
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
在顶层创建文件“dotme”或添加到您的.bashrc(全球):
#!/bin/bash
cmk() { if [ ! -e $1/CMakeLists.txt ] || ! grep -q "set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)" $1/CMakeLists.txt;then /usr/bin/cmake $*;else echo "CMAKE_DISABLE_IN_SOURCE_BUILD ON";fi }
alias cmake=cmk
现在运行:
. ./dotme
当您尝试在顶层源代码树运行cmake:
$ cmake .
CMAKE_DISABLE_IN_SOURCE_BUILD ON
没有CMakeFiles /或CMakeCache.txt获取生成。
在做外的源码编译,你需要运行CMake的第一次只需要调用实际的可执行:
$ cd build
$ /usr/bin/cmake ..
只是使目录中读取,只有用的人/进程做构建。 有一个单独的进程,检查出从源代码控制的目录(您使用的源代码控制,对吧?),然后使它只读。