tutorial make descarga course cmake

descarga - cmake vs make



Buscando un comando ''cmake clean'' para borrar la salida de CMake (18)

Busqué en Google durante media hora y lo único útil que se me ocurrió fue invocar la utilidad de find :

# Find and then delete all files under current directory (.) that: # 1. contains "cmake" (case-&insensitive) in its path (wholename) # 2. name is not CMakeLists.txt find . -iwholename ''*cmake*'' -not -name CMakeLists.txt -delete

Además, asegúrese de invocar make clean (o cualquier generador CMake que esté usando) antes de eso.

:)

Del mismo modo que make clean elimina todos los archivos que ha producido un makefile, me gustaría hacer lo mismo con CMake. Muy a menudo me encuentro recorriendo directorios manualmente eliminando archivos como cmake_install.cmake y CMakeCache.txt , y las carpetas CMakeFiles .

¿Hay un comando como cmake clean para eliminar todos estos archivos automáticamente? Idealmente, esto debería seguir la estructura recursiva definida dentro del archivo CMakeLists.txt del directorio actual.


Cree un directorio de compilación temporal, por ejemplo, build_cmake . Por lo tanto, todos sus archivos de compilación estarán dentro de esta carpeta.

Luego, en su archivo principal CMake agregue el siguiente comando.

add_custom_target(clean-all rm -rf * )

Por lo tanto, mientras compilamos

cmake ..

Y para limpiar hacer:

make clean-all


En el caso de que pase los parámetros -D a CMake al generar los archivos de compilación y no desea eliminar todo el directorio de compilación:

Simplemente elimine el directorio CMakeFiles / dentro de su directorio de compilación.

rm -rf CMakeFiles/ cmake --build .

Esto hace que CMake se vuelva a ejecutar, y los archivos del sistema de compilación se regeneran. Su construcción también comenzará desde cero.


En estos días de Git en todas partes, puede olvidarse de CMake y usar git clean -d -f -x , que eliminará todos los archivos que no estén bajo el control de código fuente.


Estoy de acuerdo en que la construcción fuera de la fuente es la mejor respuesta. Pero para los momentos en que solo debes hacer una compilación en la fuente, he escrito un script de Python disponible here , que:

  1. Corre "hacer limpio"
  2. Elimina archivos específicos generados por CMake en el directorio de nivel superior, como CMakeCache.txt
  3. Para cada subdirectorio que contiene un directorio CMakeFiles, elimina CMakeFiles, Makefile, cmake_install.cmake.
  4. Elimina todos los subdirectorios vacíos.

No hay cmake clean .

Por lo general construyo el proyecto en una sola carpeta como "construir". Por lo tanto, si quiero make clean , solo puedo rm -rf build .

La carpeta "build" en el mismo directorio que la raíz "CMakeLists.txt" suele ser una buena opción. Para construir su proyecto, simplemente dé a cmake la ubicación de CMakeLists.txt como un argumento. Por ejemplo: cd <location-of-cmakelists>/build && cmake .. (De @ComicSansMS)


Para simplificar la limpieza cuando se usa la compilación "fuera de la fuente" (es decir, la compilación en el directorio de build ), uso el siguiente script:

$ cat ~/bin/cmake-clean-build #!/bin/bash if [ -d ../build ]; then cd .. rm -rf build mkdir build cd build else echo "build directory DOES NOT exist" fi

Cada vez que necesite limpiar, debe obtener esta secuencia de comandos desde el directorio de build :

. cmake-clean-build


Por supuesto, las compilaciones fuera de la fuente son el método a seguir para los archivos Makefile de Unix, pero si estás usando otro generador como Eclipse CDT, prefieres que lo hagas en la fuente. En cuyo caso, deberá purgar los archivos de CMake manualmente. Prueba esto:

find . -name ''CMakeCache.txt'' -o -name ''*.cmake'' -o -name ''Makefile'' -o -name ''CMakeFiles'' -exec rm -rf {} +

O si ha habilitado globstar con shopt -s globstar , pruebe este enfoque menos asqueroso:

rm -rf **/CMakeCache.txt **/*.cmake **/Makefile **/CMakeFiles


Puedes usar algo como:

add_custom_target(clean-cmake-files COMMAND ${CMAKE_COMMAND} -P clean-all.cmake ) // clean-all.cmake set(cmake_generated ${CMAKE_BINARY_DIR}/CMakeCache.txt ${CMAKE_BINARY_DIR}/cmake_install.cmake ${CMAKE_BINARY_DIR}/Makefile ${CMAKE_BINARY_DIR}/CMakeFiles ) foreach(file ${cmake_generated}) if (EXISTS ${file}) file(REMOVE_RECURSE ${file}) endif() endforeach(file)

Por lo general, creo un comando "make clean-all" agregando una llamada a "make clean" en el ejemplo anterior:

add_custom_target(clean-all COMMAND ${CMAKE_BUILD_TOOL} clean COMMAND ${CMAKE_COMMAND} -P clean-all.cmake )

No intente agregar el objetivo "limpio" como una dependencia:

add_custom_target(clean-all COMMAND ${CMAKE_COMMAND} -P clean-all.cmake DEPENDS clean )

Porque "limpio" no es un objetivo real en CMake y esto no funciona.

Por otra parte, no debes usar estos "archivos limpios de cmake" como dependencia de nada:

add_custom_target(clean-all COMMAND ${CMAKE_BUILD_TOOL} clean DEPENDS clean-cmake-files )

Porque, si lo hace, todos los archivos de CMake se borrarán antes de que se complete el proceso de limpieza de todo, y se producirá un error al buscar "CMakeFiles / clean-all.dir / build.make". En consecuencia, no puede utilizar el comando clean-all antes de "nada" en cualquier contexto:

add_custom_target(clean-all COMMAND ${CMAKE_BUILD_TOOL} clean COMMAND ${CMAKE_COMMAND} -P clean-all.cmake )

Eso tampoco funciona.


Si tiene definiciones personalizadas y desea guardarlas antes de limpiarlas, ejecute lo siguiente en su directorio de compilación:

sed -ne ''/variable specified on the command line/{n;s/.*/-D /0 ///;p}'' CMakeCache.txt

Luego cree un nuevo directorio de compilación (o elimine el directorio de compilación anterior y cmake a cmake ) y finalmente ejecute cmake con los argumentos que obtendrá con el script anterior.


Si tu corres

cmake .

se regenerarán los archivos de CMake. Lo cual es necesario si agrega un nuevo archivo a una carpeta de origen que está seleccionada por * .cc, por ejemplo.

Si bien esto no es un proceso "limpio", sí "limpia" los archivos CMake al regenerar los cachés.


Simplemente emitir rm CMakeCache.txt funciona para mí.


Tal vez esté un poco desactualizado, pero como este es el primer éxito cuando cmake clean Google cmake clean Google, cmake clean esto:

Ya que puede iniciar una compilación en el directorio de compilación con un objetivo específico con

cmake --build . --target xyz

puedes por supuesto correr

cmake --build . --target clean

para ejecutar el destino clean en los archivos de compilación generados.


Tengo esto en mi archivo shell rc ( .bashrc , .zshrc ):

t-cmake-clean() { local BUILD=$(basename $(pwd)) cd .. rm -rf $BUILD mkdir $BUILD && cd $BUILD }

Se supone que debes usarlo solo para compilaciones fuera de la fuente. Digamos que tienes un directorio llamado build/ para este propósito. Entonces solo tienes que ejecutar t-cmake-clean desde dentro.


Una solución que encontré recientemente es combinar el concepto de compilación fuera de la fuente con un envoltorio Makefile.

En mi archivo CMakeLists.txt de nivel superior, incluyo lo siguiente para evitar compilaciones en origen:

if ( ${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR} ) message( FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt." ) endif()

Luego, creo un Makefile de nivel superior e incluyo lo siguiente:

# ----------------------------------------------------------------------------- # CMake project wrapper Makefile ---------------------------------------------- # ----------------------------------------------------------------------------- SHELL := /bin/bash RM := rm -rf MKDIR := mkdir -p all: ./build/Makefile @ $(MAKE) -C build ./build/Makefile: @ ($(MKDIR) build > /dev/null) @ (cd build > /dev/null 2>&1 && cmake ..) distclean: @ ($(MKDIR) build > /dev/null) @ (cd build > /dev/null 2>&1 && cmake .. > /dev/null 2>&1) @- $(MAKE) --silent -C build clean || true @- $(RM) ./build/Makefile @- $(RM) ./build/src @- $(RM) ./build/test @- $(RM) ./build/CMake* @- $(RM) ./build/cmake.* @- $(RM) ./build/*.cmake @- $(RM) ./build/*.txt ifeq ($(findstring distclean,$(MAKECMDGOALS)),) $(MAKECMDGOALS): ./build/Makefile @ $(MAKE) -C build $(MAKECMDGOALS) endif

El destino predeterminado se llama a todo al escribir make e invoca el destino ./build/Makefile .

Lo primero que hace el destino ./build/Makefile es crear el directorio de build usando $(MKDIR) , que es una variable para mkdir -p . La build directorio es donde realizaremos nuestra compilación fuera de la fuente. Proporcionamos el argumento -p para garantizar que mkdir no nos grite por intentar crear un directorio que ya exista.

Lo segundo que hace el destino ./build/Makefile es cambiar los directorios al directorio de build e invocar a cmake .

De vuelta a all destinos, invocamos $(MAKE) -C build , donde $(MAKE) es una variable de Makefile generada automáticamente para make . make -C cambia el directorio antes de hacer nada. Por lo tanto, usar $(MAKE) -C build es equivalente a hacer cd build; make cd build; make

Para resumir, llamar a este contenedor Makefile con make all o make es equivalente a hacer:

mkdir build cd build cmake .. make

El destino distclean invoca a cmake .. , luego make -C build clean , y finalmente, elimina todos los contenidos del directorio de build . Creo que esto es exactamente lo que pidió en su pregunta.

La última parte de Makefile evalúa si el objetivo proporcionado por el usuario está o no está distclean . Si no, cambiará los directorios para build antes de invocarlo. Esto es muy poderoso porque el usuario puede escribir, por ejemplo, make clean , y el Makefile transformará eso en un equivalente de cd build; make clean de cd build; make clean cd build; make clean

En conclusión, este envoltorio Makefile, en combinación con una configuración obligatoria CMake de compilación fuera de la fuente, hace que el usuario nunca tenga que interactuar con el comando cmake . Esta solución también proporciona un método elegante para eliminar todos los archivos de salida de CMake del directorio de build .

PS En el Makefile, usamos el prefijo @ para suprimir la salida de un comando de shell, y el prefijo @- para ignorar los errores de un comando de shell. Cuando se usa rm como parte del destino distclean , el comando devolverá un error si los archivos no existen (es posible que ya se hayan eliminado utilizando la línea de comandos con rm -rf build , o nunca se generaron en primer lugar). Este error de retorno obligará a nuestro Makefile a salir. Usamos el prefijo @- para evitar eso. Es aceptable si un archivo ya fue eliminado; Queremos que nuestro Makefile continúe y elimine el resto.

Otra cosa a tener en cuenta: este Makefile puede no funcionar si usa un número variable de variables CMake para construir su proyecto, por ejemplo, cmake .. -DSOMEBUILDSUSETHIS:STRING="foo" -DSOMEOTHERBUILDSUSETHISTOO:STRING="bar" . Este Makefile asume que invoca CMake de una manera consistente, ya sea escribiendo cmake .. o proporcionando cmake un número consistente de argumentos (que puede incluir en su Makefile).

Finalmente, crédito donde el crédito es debido. Esta envoltura de Makefile se adaptó del Makefile proporcionado por la Plantilla de Proyecto de Aplicación de C ++ .


Yo uso el siguiente script de shell para tales fines:

#!/bin/bash for fld in $(find -name "CMakeLists.txt" -printf ''%h '') do for cmakefile in CMakeCache.txt cmake_install.cmake CTestTestfile.cmake CMakeFiles Makefile do rm -rfv $fld/$cmakefile done done

Si está utilizando Windows, use Cygwin para este script.


Usé la respuesta de zsxwing exitosamente para resolver el siguiente problema:

Tengo una fuente que construyo en varios hosts (en una placa Raspberry Pi Linux, en una máquina virtual VMware Linux, etc.)

Tengo una secuencia de comandos Bash que crea directorios temporales basados ​​en el nombre de host de la máquina como este:

# Get hostname to use as part of directory names HOST_NAME=`uname -n` # Create a temporary directory for cmake files so they don''t # end up all mixed up with the source. TMP_DIR="cmake.tmp.$HOSTNAME" if [ ! -e $TMP_DIR ] ; then echo "Creating directory for cmake tmp files : $TMP_DIR" mkdir $TMP_DIR else echo "Reusing cmake tmp dir : $TMP_DIR" fi # Create makefiles with CMake # # Note: switch to the temporary dir and build parent # which is a way of making cmake tmp files stay # out of the way. # # Note 2: to clean up cmake files, it is OK to # "rm -rf" the temporary directories echo echo Creating Makefiles with cmake ... cd $TMP_DIR cmake .. # Run makefile (in temporary directory) echo echo Starting build ... make


Las preguntas oficiales oficiales de CMake dicen :

Algunos árboles de compilación creados con los autotools de GNU tienen un objetivo "make distclean" que limpia la compilación y también elimina Makefiles y otras partes del sistema de compilación generado. CMake no genera un destino "make distclean" porque los archivos CMakeLists.txt pueden ejecutar scripts y comandos arbitrarios; CMake no tiene forma de rastrear exactamente qué archivos se generan como parte de ejecutar CMake. Proporcionar un objetivo distclean daría a los usuarios la falsa impresión de que funcionaría como se esperaba. (CMake genera un objetivo de "limpieza" para eliminar los archivos generados por el compilador y el enlazador).

Un objetivo "make distclean" solo es necesario si el usuario realiza una compilación en origen. CMake admite compilaciones en la fuente, pero recomendamos encarecidamente a los usuarios que adopten la noción de una compilación fuera de la fuente. El uso de un árbol de compilación que esté separado del árbol de origen evitará que CMake genere cualquier archivo en el árbol de origen. Debido a que CMake no cambia el árbol de origen, no es necesario un destino distclean. Uno puede comenzar una compilación nueva eliminando el árbol de compilación o creando un árbol de compilación separado.