通过CMake,你会如何禁用源建立?(With cmake, how would you disab

2019-06-27 07:11发布

我想塞满我们的源代码树生成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源代码树中的文件之前抛出的错误。

我缺少一个更好的方式来做到这一点?

Answer 1:

我觉得我喜欢你的方式。 CMake的邮件列表做得很好,在回答这些类型的问题。

作为一个方面说明:您可以创建在失败目录下的“cmake的”可执行文件。 根据与否“” 在他们的路径(在Linux上)。 你甚至可以符号链接/斌/假。

在Windows中,我不知道,如果你的当前目录中的文件是第一还是没找到。



Answer 2:

CMake的有两个无证选项: CMAKE_DISABLE_SOURCE_CHANGESCMAKE_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;
}


Answer 3:

包括像函数这个 。 它类似于你这些差异做什么:

  1. 它被封装在一个功能,当你包括被称为PreventInSourceBuilds.cmake模块。 你的主要的CMakeLists.txt必须包括它:

     set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/CMake) include(PreventInSourceBuilds) 
  2. 它使用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()


Answer 4:

我有一个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直接(或不使用包装功能的话)。 而且这是愚蠢的简单。



Answer 5:

你可以配置你的.bashrc文件中像这样一个

看看功能cmakekdekdebuild。 设置编译和SRC ENV。 根据您的需求变量和编辑这些功能。 这只会建立buildDir而非SRCDIR



Answer 6:

对于那些在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 ..


Answer 7:

只是使目录中读取,只有用的人/进程做构建。 有一个单独的进程,检查出从源代码控制的目录(您使用的源代码控制,对吧?),然后使它只读。



文章来源: With cmake, how would you disable in-source builds?
标签: build cmake