Frage

Ich mag die Leute unseren Quellbaum von Poltern mit generierten CMake Dateien nicht zulassen ... und, was noch wichtiger ist, nicht zulassen sie auf bestehenden Makefiles von Schritt, die nicht Teil des gleichen Build-Prozesses sind wir verwenden CMake für. (Am besten nicht zu fragen)

So wie ich mit gekommen sind, dies zu tun ist, ein paar Zeilen an der Spitze meiner CMakeLists.txt haben, wie folgt:

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}")

Es ist jedoch diese Art und Weise zu tun scheint zu ausführlich. Außerdem, wenn ich versuche, eine In-Quelle baut es noch schafft das das CMakeFiles/ Verzeichnis und die CMakeCache.txt Datei im Quellbaum, bevor der Fehler ausgelöst wird.

Fehle ich einen besseren Weg, dies zu tun?

War es hilfreich?

Lösung

Ich glaube, ich dich mag. Die Cmake Mailing-Liste macht einen guten Job bei dieser Art von Fragen zu beantworten.

Als Randbemerkung: Sie könnten eine „cmake“ ausführbare Datei im Verzeichnis erstellen, die fehlschlägt. Je nachdem, ob oder nicht „“ in ihrem Weg ist (auf Linux). Sie könnten sogar Symlink / bin / false.

In Fenstern, bin ich nicht sicher, ob eine Datei im aktuellen Verzeichnis wird zuerst gefunden oder nicht.

Andere Tipps

CMake hat zwei undokumentierte Optionen: CMAKE_DISABLE_SOURCE_CHANGES und 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;
}

Fügen Sie eine Funktion wie diese ein . Es ist ähnlich zu dem, was man mit diesen Unterschieden zu tun:

  1. Es ist in einer Funktion gekapselt, die aufgerufen wird, wenn Sie das PreventInSourceBuilds.cmake Modul enthalten. Ihr Haupt CMakeLists.txt muss enthalten:

    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/CMake)
    include(PreventInSourceBuilds)
    
  2. Es verwendet get_filename_component () mit realpath Parameter dass löst Symlinks bevor die Pfade zu vergleichen.

Bei den Github Link Änderungen, hier ist das Modul Quellcode (die in einem PreventInSouceBuilds.cmake platziert werden sollen, in einem Verzeichnis namens CMake, in dem obigen Beispiel):

#
# 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()

Ich habe eine cmake() Shell-Funktion in meinem .bashrc / .zshrc ähnlich wie diese:

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
}

Ich ziehe diese niedrige Zeremonie Lösung. Es losgeworden meine Kollegen größten Beschwerde, wenn wir CMake geschaltet, aber nicht verhindern, dass Menschen, die wirklich will von einem in-Source / top-of-Baum zu tun, baut so sie tun nur aufrufen /usr/bin/cmake direkt (oder nicht die Wrapper-Funktion überhaupt verwenden). Und es ist dumm einfach.

Sie können Ihre Datei .bashrc wie dieses

konfigurieren

Schauen Sie sich die Funktionen cmakekde und kdebuild . Stellen Sie BUILD und SRC env. Variablen und diese Funktionen nach Ihren Bedürfnissen bearbeiten. Dies wird bauen nur in builddir statt srcdir

Für die auf Linux:

in dem Top-Level-CMakeLists.txt:

set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)

Erstellen Sie eine Datei 'dotme' in Ihrem Top-Level oder fügen Sie zu Ihrem Bashrc (global):

#!/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

Jetzt laufen:

. ./dotme

Wenn Sie versuchen, cmake in dem Top-Level-Source-Tree zu laufen:

$ cmake .
CMAKE_DISABLE_IN_SOURCE_BUILD ON

Keine CMakeFiles / oder CMakeCache.txt wird erzeugt.

Wenn out-of-Quelle zu tun zu bauen und führen Sie anrufen müssen erstmals cmake nur die eigentliche ausführbare Datei:

$ cd build
$ /usr/bin/cmake ..

Sie einfach das Verzeichnis machen schreibgeschützt von den Menschen / Prozesse machen die Builds. Haben Sie einen separaten Prozess, der aus der Quellcodeverwaltung in das Verzeichnis auscheckt (Sie verwenden Quellcodeverwaltung, nicht wahr?), Dann macht es schreibgeschützt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top