De alguna manera, estoy totalmente confundido por cómo funciona CMake. Cada vez que pienso que me estoy acercando a entender cómo se debe escribir CMake, desaparece en el siguiente ejemplo que leo. Todo lo que quiero saber es cómo debería estructurar mi proyecto para que mi CMake requiera la menor cantidad de mantenimiento en el futuro. Por ejemplo, no quiero actualizar mi CMakeList.txt cuando agrego una nueva carpeta en mi árbol src, que funciona exactamente como todas las demás carpetas src.
Así es como imagino la estructura de mi proyecto, pero por favor, esto es solo un ejemplo. Si la forma recomendada difiere, por favor dígame y dígame cómo hacerlo.
myProject
src/
module1/
module1.h
module1.cpp
module2/
[...]
main.cpp
test/
test1.cpp
resources/
file.png
bin
[execute cmake ..]
Por cierto, es importante que mi programa sepa dónde están los recursos. Me gustaría conocer la forma recomendada de gestionar los recursos. No quiero acceder a mis recursos con "../resources/file.png"
fuente
For example I don't want to update my CMakeList.txt when I am adding a new folder in my src tree
¿Puede dar un ejemplo de IDE que recopila fuentes automáticamente?Respuestas:
Después de algunas investigaciones, ahora tengo mi propia versión del ejemplo de cmake más simple pero completo. Aquí está e intenta cubrir la mayoría de los conceptos básicos, incluidos los recursos y el empaque.
una cosa que hace de manera no estándar es el manejo de recursos. Por defecto, cmake quiere ponerlos en / usr / share /, / usr / local / share / y algo equivalente en Windows. Quería tener un zip / tar.gz simple que puedas extraer en cualquier lugar y ejecutar. Por lo tanto, los recursos se cargan en relación con el ejecutable.
la regla básica para entender los comandos de cmake es la siguiente sintaxis:
<function-name>(<arg1> [<arg2> ...])
sin coma o semicolor. Cada argumento es una cadena.foobar(3.0)
yfoobar("3.0")
es lo mismo. puede configurar listas / variables conset(args arg1 arg2)
. Con este conjunto de variablesfoobar(${args})
yfoobar(arg1 arg2)
son efectivamente iguales. Una variable inexistente equivale a una lista vacía. Una lista es internamente solo una cadena con punto y coma para separar los elementos. Por lo tanto, una lista con un solo elemento es, por definición, solo ese elemento, no tiene lugar ningún boxeo. Las variables son globales. Las funciones integradas ofrecen alguna forma de argumentos con nombre por el hecho de que esperan algunos identificadores comoPUBLIC
oDESTINATION
en su lista de argumentos, para agrupar los argumentos. Pero esa no es una característica del lenguaje, esos identificadores también son solo cadenas y se analizan mediante la implementación de la función.puedes clonar todo desde github
fuente
set(sources src/main.cpp)
.CMakeLists.txt
, entonces un make normal (o ninja) desencadenará la reinvocación de cmake, por lo que no puedes olvidarlo. También es un poco más amigable para el equipo, porque los miembros del equipo tampoco pueden olvidarse de ejecutar cmake. Pero creo que un archivo MAKE no debería necesitar ser tocado, solo porque alguien agregó un archivo. Escríbalo una vez, y nadie debería tener que pensar en ello nunca más.El ejemplo más básico pero completo se puede encontrar en el tutorial de CMake :
Para su ejemplo de proyecto, puede tener:
Para su pregunta adicional, una forma de hacerlo es nuevamente en el tutorial: cree un archivo de encabezado configurable que incluya en su código. Para ello, haga un archivo
configuration.h.in
con el siguiente contenido:Luego, en tu
CMakeLists.txt
complemento:Finalmente, donde necesite la ruta en su código, puede hacer:
fuente
string resourcePath = string(RESOURCE_PATH) + "file.png"
mi humilde opinión, es una mala idea codificar la ruta absoluta al directorio de origen. ¿Qué pasa si necesita instalar su proyecto?Aquí escribo una muestra de archivos CMakeLists.txt más simple pero completa.
Código fuente
Después de eso, ofrecí un documento para los detalles.
Si tiene alguna pregunta, puede contactarme y me gustaría explicárselo.
fuente