it-swarm-es.tech

Directorio de salida/compilación CMake

Soy bastante nuevo en cmake y leí algunos tutoriales sobre cómo usarlo, y escribí algunos scripts complicados de 50 líneas de CMake para hacer un programa para 3 compiladores diferentes. Esto probablemente concluye todo mi conocimiento en cmake.

Ahora mi problema es que tengo un código fuente, cuya carpeta no quiero tocar/desordenar cuando hago el programa. Quiero que todos los archivos y carpetas de cmake y make se incluyan en ../Compile/, así que cambié algunas variables en mi script de cmake para eso, y funcionó en algún momento cuando hice algo como esto en mi computadora portátil:

Compile$ cmake ../src
Compile$ make

Donde con eso tuve una salida limpia en la carpeta en la que estoy ahora, que es exactamente lo que estoy buscando.

Ahora me moví a otra computadora, y recompilé CMake 2.8.11.2, ¡y casi he vuelto al punto uno! Siempre compila la cosa en la carpeta src donde se encuentra mi CMakeLists.txt.

La parte en la que elijo el directorio en mi script cmake es esta:

set(dir ${CMAKE_CURRENT_SOURCE_DIR}/../Compile/)
set(EXECUTABLE_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(LIBRARY_OUTPUT_PATH ${dir} CACHE PATH "Build directory" FORCE)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dir})
set(CMAKE_BUILD_FILES_DIRECTORY ${dir})
set(CMAKE_BUILD_DIRECTORY ${dir})
set(CMAKE_BINARY_DIR  ${dir})
SET(EXECUTABLE_OUTPUT_PATH ${dir})
SET(LIBRARY_OUTPUT_PATH ${dir}lib)
SET(CMAKE_CACHEFILE_DIR ${dir})

Y ahora siempre termina con:

-- Build files have been written to: /.../src

¿Me estoy perdiendo de algo?

87

Hay poca necesidad de establecer todas las variables que está configurando. CMake los establece en valores predeterminados razonables. Definitivamente deberías no modificar CMAKE_BINARY_DIR o CMAKE_CACHEFILE_DIR. Trátelos como de sólo lectura.

Primero elimine el archivo de caché problemático existente del directorio src:

cd src
rm CMakeCache.txt
cd ..

Luego elimine todos los comandos set() y haga:

cd Compile
rm -rf *
cmake ../src

Mientras esté fuera del directorio de origen cuando ejecute CMake, no modificará el directorio de origen a menos que su CMakeList se lo indique explícitamente.

Una vez que esté trabajando, puede ver dónde CMake pone las cosas de manera predeterminada, y solo si no está satisfecho con las ubicaciones predeterminadas (como el valor predeterminado de EXECUTABLE_OUTPUT_PATH), modifique solo las que necesite. Y trata de expresarlos en relación con CMAKE_BINARY_DIR, CMAKE_CURRENT_BINARY_DIR, PROJECT_BINARY_DIR etc.

Si observa la documentación de CMake, verá variables particionadas en secciones semánticas. A excepción de muy circunstancias especiales, debe tratar a todas las enumeradas en "Variables que proporcionan información" como de solo lectura dentro de CMakeLists.

50
Angew

Parece que quieres una fuera de la compilación de origen . Hay un par de formas en que puede crear una compilación fuera de la fuente.

  1. Haz lo que estabas haciendo, corre

    cd /path/to/my/build/folder
    cmake /path/to/my/source/folder
    

    lo que hará que cmake genere un árbol de construcción en /path/to/my/build/folder para el árbol de origen en /path/to/my/source/folder.

    Una vez que lo haya creado, cmake recuerda dónde está la carpeta de origen, de modo que puede volver a ejecutar cmake en el árbol de compilación con

    cmake /path/to/my/build/folder
    

    o incluso

    cmake .
    

    si su directorio actual ya es la carpeta de compilación.

  2. Use algunas opciones no documentadas para configurar las carpetas de origen y compilación :

    cmake -B/path/to/my/build/folder -H/path/to/my/source/folder
    

    que hará exactamente lo mismo que (1), pero sin depender del directorio de trabajo actual.

CMake coloca todas sus salidas en el árbol de construcción de forma predeterminada, así que, a menos que esté utilizando generosamente ${CMAKE_SOURCE_DIR} o ${CMAKE_CURRENT_SOURCE_DIR} en sus archivos cmake, no debe tocar su árbol de origen.

Lo más importante que puede salir mal es si previamente generó un árbol de compilación en su árbol de fuentes (es decir, tiene una en la fuente compilación). Una vez que haya hecho esto, la segunda parte de (1) se inicia y cmake no realiza ningún cambio en las ubicaciones de origen o de compilación. Por lo tanto, no puede crear una compilación fuera de la fuente para un directorio de origen con una compilación en la fuente . Puede solucionar este problema con bastante facilidad eliminando (como mínimo) CMakeCache.txt del directorio de origen. Hay algunos otros archivos (en su mayoría en el directorio CMakeFiles) que CMake genera que también debe eliminar, pero estos no harán que cmake trate el árbol de origen como un árbol de compilación.

Dado que las compilaciones fuera de la fuente son a menudo más deseables que las compilaciones en la fuente, es posible que desee modificar su cmake para requerir compilaciones fuera de la fuente:

# Ensures that we do an out of source build

MACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD MSG)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${CMAKE_BINARY_DIR}" insource)
     GET_FILENAME_COMPONENT(PARENTDIR ${CMAKE_SOURCE_DIR} PATH)
     STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}"
     "${PARENTDIR}" insourcesubdir)
    IF(insource OR insourcesubdir)
        MESSAGE(FATAL_ERROR "${MSG}")
    ENDIF(insource OR insourcesubdir)
ENDMACRO(MACRO_ENSURE_OUT_OF_SOURCE_BUILD)

MACRO_ENSURE_OUT_OF_SOURCE_BUILD(
    "${CMAKE_PROJECT_NAME} requires an out of source build."
)

La macro anterior proviene de un módulo de uso común llamado MacroOutOfSourceBuild. Existen numerosas fuentes para MacroOutOfSourceBuild.cmake en google pero parece que no puedo encontrar el original y es lo suficientemente corto como para incluirlo aquí en su totalidad.

Lamentablemente, cmake normalmente ha escrito algunos archivos para cuando se invoca la macro, por lo que aunque no le permita realizar la compilación, todavía deberá eliminar CMakeCache.txt y CMakeFiles.

Puede que le resulte útil configurar las rutas en las que se escriben las bibliotecas estáticas y las binarias, en cuyo caso vea ¿cómo hago que cmake se genere en un directorio 'bin'? (descargo de responsabilidad, tengo la respuesta más votada sobre esa pregunta ... pero así es como lo sé).

89
Adam Bowen

A partir de CMake Wiki :

CMAKE_BINARY_DIR si está compilando en la fuente, es lo mismo que CMAKE_SOURCE_DIR, de lo contrario, este es el directorio de nivel superior de su árbol de compilación

Compare estas dos variables para determinar si se inició la compilación fuera de la fuente

6
damkrat

Convirtiendo mi comentario en una respuesta:

En caso de que alguien hiciera lo que yo hice, esto fue al comenzar poniendo todos los archivos de compilación en el directorio de origen:

cd src
cmake .

cmake colocará un montón de archivos de compilación y archivos de caché (CMakeCache.txt, CMakeFiles, cmake_install.cmake, etc) en el src dir.

Para cambiar a una compilación fuera de origen, tuve que eliminar todos esos archivos. Entonces podría hacer lo que @Agnew recomendó en su respuesta:

mkdir -p src/build
cd src/build
cmake ..
5
Avi Tevet

En primer lugar, no debe transmitir el nombre del directorio de compilación en su script. la línea con ../Compile debe ser cambiada.

Es porque depende del usuario dónde compilar.

En lugar de eso, use una de las variables predefinidas: http://www.cmake.org/Wiki/CMake_Useful_Variables (busque CMAKE_BINARY_DIR y CMAKE_CURRENT_BINARY_DIR)

4
Michał Walenciak