tutorial c++ header makefile cmake project-structure

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.