tutorial script running descarga create course cant build cmake

build - script - Con cmake, ¿cómo inhabilitarías las compilaciones in-source?



descarga cmake (7)

Quiero evitar que las personas abarroten nuestro árbol fuente con los archivos CMake generados ... y, lo que es más importante, no les permita pisar los Makefiles existentes que no forman parte del mismo proceso de compilación para el que estamos utilizando CMake. (mejor no preguntar)

La forma en que se me ocurrió hacer esto es tener algunas líneas en la parte superior de mi CMakeLists.txt , de la siguiente manera:

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

Sin embargo, hacerlo de esta manera parece demasiado detallado. Además, si intento una compilación in-source, aún crea el directorio CMakeFiles/ y el archivo CMakeCache.txt en el árbol de fuentes antes de que se CMakeCache.txt el error.

¿Me estoy perdiendo una mejor manera de hacer esto?


CMake tiene dos opciones no documentadas: CMAKE_DISABLE_SOURCE_CHANGES y 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; }


Creo que me gusta tu camino. La lista de correo de cmake hace un buen trabajo respondiendo este tipo de preguntas.

Como nota al margen: puede crear un archivo ejecutable "cmake" en el directorio que falla. Dependiendo de si "o no". está en su camino (en Linux). Incluso puedes hacer un enlace simbólico / bin / falso.

En Windows, no estoy seguro de si se encuentra primero un archivo en su directorio actual o no.


Incluye una función como esta . Es similar a lo que haces con estas diferencias:

  1. Se encapsula en una función, que se PreventInSourceBuilds.cmake cuando se incluye el módulo PreventInSourceBuilds.cmake . Su principal CMakeLists.txt debe incluirlo:

    set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/CMake) include(PreventInSourceBuilds)

  2. Utiliza get_filename_component() con el parámetro REALPATH que resuelve los enlaces simbólicos antes de comparar las rutas.

En caso de que el enlace github cambie, aquí está el código fuente del módulo (que debe colocarse en un PreventInSouceBuilds.cmake , en un directorio llamado CMake , en el ejemplo anterior):

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


Para aquellos en Linux:

agregar al nivel superior CMakeLists.txt:

set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)

crea un archivo ''dotme'' en tu nivel superior o agrégalo a .bashrc (globalmente):

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

ahora corre:

. ./dotme

cuando intenta ejecutar cmake en el árbol de código fuente de nivel superior:

$ cmake . CMAKE_DISABLE_IN_SOURCE_BUILD ON

No se generan CMakeFiles / o CMakeCache.txt.

Al realizar compilación fuera de la fuente y necesita ejecutar cmake por primera vez, simplemente llame al ejecutable real:

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


Puede configurar su archivo .bashrc como este

Mire las funciones cmakekde y kdebuild . Establecer BUILD y SRC env. variables y edite estas funciones de acuerdo a sus necesidades. Esto se compilará solo en buildDir en lugar de srcDir


Simplemente haga que el directorio sea de solo lectura para las personas / procesos que realizan las compilaciones. Tenga un proceso por separado que verifique el directorio desde el control de origen (está usando el control de código fuente, ¿verdad?), Luego haga que sea de solo lectura.


Tengo una función de shell cmake() en mi .bashrc / .zshrc similar a este:

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 }

Prefiero esta solución de baja ceremonia. Me deshice de la mayor queja de mis colegas cuando cambiamos a CMake, pero no impide que las personas que realmente quieren hacer una compilación in-source / top-of-tree lo hagan; pueden invocar /usr/bin/cmake directamente (o no usa la función de envoltura en absoluto). Y es estúpido simple.