c++ - tutorial - Se necesita ayuda al configurar el proyecto básico compatible con cmake multiplataforma
cmake tutorial (2)
tl; dr las preguntas están en la parte inferior.
Soy un desarrollador que intenta algo nuevo: mi último veneno es c ++. Como gasto la mitad de mi tiempo en mi computadora portátil Linux y la otra mitad en Win XP PC, traté de encontrar una manera de crear un proyecto básico, barebone, usando buenas prácticas de c ++ (bueno, no los conozco por experiencia, Acabo de leer sobre ellos). En este momento mi proyecto casi funciona mientras uso cmake . && make
cmake . && make
en linux (funciona cuando los archivos de cabecera y fuente están en la misma carpeta, falla cuando los separé para incluir carpetas / src). Estoy usando la distribución de nuwen de mingw en Windows (y sé que la cadena de herramientas está funcionando, compila proyectos desde dentro de Eclipse sin ningún problema).
Mi directorio de proyecto se ve así:
engine
|
|- main
|
|- include
|
|- App.h
|- CMakeLists.txt (2)
|- src
|
|- main.cc
|- App.cc
|- CMakeLists.txt (3)
|- CMakLists.txt (1)
El contenido de los archivos es muy simple (eliminaré los guardias de inclusión, etc. para mayor claridad)
App.h:
class App {
public:
App();
int onExecute();
};
App.cc:
#include <iostream>
#include "App.h"
App::App() {
}
int App::onExecute() {
std::cout << "inside app.." << ''/n'';
return 0;
}
main.cc:
#include <iostream>
#include "App.h"
using namespace std;
int main(int argc, char* argv[]) {
App a;
a.onExecute();
std::cout << "inside main.." << ''/n'';
}
CMakeLists.txt (1) - el principal:
cmake_minimum_required (VERSION 2.6)
set (CMAKE_CXX_COMPILER "g++")
project (gameengine)
add_definitions ( "-Wall -ansi -pedantic")
add_subdirectory (${CMAKE_SOURCE_DIR}/main/include)
add_subdirectory (${CMAKE_SOURCE_DIR}/main/src)
add_executable (engine ${CMAKE_SOURCE_DIR}/main/src/main.cc)
target_link_libraries (engine Application)
CMakeLists.txt (2) - dentro del directorio de inclusión
add_library (Application App)
set_target_properties (Application PROPERTIES LINKER_LANGUAGE CXX)
CMakeLists.txt (3) - dentro del directorio src
include_directories (../include)
Y esto es lo más lejos que tengo, con algunos cambios (es decir, mover App.cc al directorio de inclusión) todo se compila y funciona bien en Linux, pero no puedo hacer que el generador de mingw funcione en Win XP. Puse a punto el CMAKE_MAKE_PROGRAM en el archivo CMakeCache.txt para señalar el make.exe adecuado (sé que esto debería definirse como una variable del sistema, pero como estoy trabajando en muchas PC diferentes, no quiero dejar basura después de yo).
Mis preguntas son:
1) ¿Cuáles son las pautas para escribir el archivo multiplataforma CMakeLists.txt (que funcionará independientemente del sistema operativo y la ubicación de los archivos del proyecto), lo que preferiblemente me permitirá cambiar fácilmente la configuración de mi proyecto de uno a otro?
2) ¿Cómo puedo solucionar el error de no encontrar el archivo de cabecera (make da: (...) / engine / main / src / main.cc: 2: 17: error fatal: App.h: No existe dicho archivo o directorio )?
Gracias por su tiempo y ayuda.
1) ¿Cuáles son las pautas para escribir el archivo multiplataforma CMakeLists.txt (que funcionará independientemente del sistema operativo y la ubicación de los archivos del proyecto), lo que preferiblemente me permitirá cambiar fácilmente la configuración de mi proyecto de uno a otro?
Bueno, ciertamente no soy un experto, pero puedo compartir mi experiencia de 10 meses con un proyecto multiplataforma basado en cmake.
Desde el primer momento, creo que deberías estar usando compilaciones sin fuente . Esto significa que no ejecuta cmake en el mismo directorio donde está su código; en su lugar, creas una nueva carpeta, por ejemplo, engine/build
y ejecuta cmake ../main
desde allí. De esta forma, no bloqueará sus archivos fuente con cmake cosas, como CMakeCache.txt, etc. Incluso hay algunas macros que puede utilizar para prohibir a sus usuarios hacer compilaciones in-source.
También me parece útil crear un conjunto de archivos de macros para ayudar a establecer opciones de compilación para diferentes plataformas. Aquí en el trabajo tenemos macros como ADD_GCC_FLAG
o ADD_MSVC_FLAG
que verifican el compilador actual y agregan indicadores en consecuencia.
Creo que es una buena práctica tener un solo archivo .cmake
que concentre todas las configuraciones de su proyecto en un solo lugar. En el trabajo, todas nuestras CMakeLists.txt
comienzan con include( ../cmake/configs.cmake )
. Este archivo establece todo tipo de opciones, como directorios de inclusión estándar, banderas de compilación predeterminadas, etc.
Para mitigar su problema con los directorios include, le sugiero que use rutas absolutas en lugar de relativas en sus archivos fuente. Defina un directorio de inclusión estándar, por ejemplo engine/main/include
y siempre #include
archivos relativos a esa ruta. En su ejemplo, si desea incluir engine/main/include/somefolder/header.h
, debe escribir #include <somefolder/header.h>
(usar <>
lugar de comillas le dice al preprocesador de C ++ que se salte el directorio actual) cuando busca el archivo).
2) ¿Cómo puedo solucionar el error de no encontrar el archivo de cabecera (make da: (...) / engine / main / src / main.cc: 2: 17: error fatal: App.h: No existe dicho archivo o directorio )?
Hay una serie de problemas con su diseño de cmake, pero la razón por la que recibió ese error es porque también necesita llamar a include_directories
en CMakeLists.txt (1)
.
Además de eso, tus otros archivos CMakeLists.txt
tienen problemas. En CMakeLists.txt (2)
, los argumentos para add_library
son incorrectos; debe ser ../src/App.cc
; de lo contrario, solo está agregando una biblioteca vacía. Y tampoco necesita ese set_target_properties
, al menos no si tiene los argumentos add_library
correctos. También necesita una llamada include_directory
en ese mismo CMakeLists.txt
que está agregando la biblioteca; ponerlo en (3)
realmente no hace nada.
En realidad, no necesita un archivo CMakeLists.txt
en el directorio de include
, ya que no hay nada que compilar allí. Es mejor poner la llamada add_library
en CMakeLists.txt (3)
, justo después de llamar a include_directories
.
Espero que esto aclare algunas de tus dudas.
Probablemente esta no sea la respuesta que esperaba, pero como no indicó si desea soluciones alternativas, lo sugeriré de todos modos:
Para proyectos multiplataforma, recomendaría SConstruct
que es realmente una gran herramienta flexible. No sé bien CMake así que realmente puedo proporcionar una comparación detallada.
Sin embargo, aquí están las razones por las que amo esta herramienta:
- Es Python. Para que pueda hacer casi cualquier cosa que desee con respecto a la personalización y / o necesidades especiales
- Es muy fácil de aprender y para proyectos simples, solo se necesitan unas pocas líneas de código para comenzar.
- Depende únicamente de Python, por lo que en Linux ya está muy instalado y en Windows demora 5 minutos en descargarse e instalarse.
- Tiene una muy buena generación de árbol de dependencia automática y soporte de compilación paralela.