c++ - tutorial - descarga cmake
ejemplo cmake más simple pero completo (2)
El ejemplo más básico pero completo se puede encontrar en el tutorial de cmake :
cmake_minimum_required (VERSION 2.6)
project (Tutorial)
add_executable(Tutorial tutorial.cxx)
Para su ejemplo de proyecto, puede tener:
cmake_minimum_required (VERSION 2.6)
project (MyProject)
add_executable(myexec src/module1/module1.cpp src/module2/module2.cpp src/main.cpp)
add_executable(mytest test1.cpp)
Para su pregunta adicional, una forma de hacerlo es nuevamente en el tutorial: crear un archivo de encabezado configurable que incluya en su código. Para esto, crea un archivo configuration.h.in
con los siguientes contenidos:
#define RESOURCES_PATH "@RESOURCES_PATH@"
Luego en su CMakeLists.txt
agregue:
set(RESOURCES_PATH "${PROJECT_SOURCE_DIR}/resources/"
# configure a header file to pass some of the CMake settings
# to the source code
configure_file (
"${PROJECT_SOURCE_DIR}/configuration.h.in"
"${PROJECT_BINARY_DIR}/configuration.h"
)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
include_directories("${PROJECT_BINARY_DIR}")
Finalmente, donde necesita la ruta en su código, puede hacer:
#include "configuration.h"
...
string resourcePath = string(RESOURCE_PATH) + "file.png";
De alguna manera, estoy totalmente confundido por el funcionamiento de CMake. Cada vez que pienso que me estoy acercando para entender cómo debe escribirse CMake, desaparece en el siguiente ejemplo que leo. Todo lo que quiero saber es cómo debería estructurar mi proyecto, de modo que mi CMake requiera la menor cantidad de mantenimiento en el futuro. Por ejemplo, no quiero actualizar mi CMakeList.txt cuando estoy agregando una nueva carpeta en mi árbol src, que funciona exactamente como todas las otras carpetas src.
Así es como me imagino la estructura de mi proyecto, pero por favor, esto es solo un ejemplo. Si la forma recomendada es diferente, 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 saber la forma recomendada de administrar los recursos. No quiero acceder a mis recursos con "../resources/file.png"
después de algunas investigaciones, ahora tengo mi propia versión del ejemplo de cmake más simple pero completo. Aquí está, y trata de cubrir la mayoría de los conceptos básicos, incluidos los recursos y el embalaje.
Una cosa que no es 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 comprender los comandos de cmake es la siguiente sintaxis: <function-name>(<arg1> [<arg2> ...])
sin coma o semicolor. Cada argumento es una cadena. foobar(3.0)
y foobar("3.0")
es lo mismo. puede establecer listas / variables con set(args arg1 arg2)
. Con esta variable, set foobar(${args})
y foobar(arg1 arg2)
son efectivamente lo mismo. Una variable no existente es equivalente 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 el boxeo. Las variables son globales. Las funciones incorporadas ofrecen alguna forma de argumentos nombrados por el hecho de que esperan algunos identificadores como PUBLIC
o DESTINATION
en su lista de argumentos, para agrupar los argumentos. Pero esa no es una función de idioma, esos identificadores también son solo cadenas y analizados por la implementación de la función.
puedes clonar todo, desde github
cmake_minimum_required(VERSION 3.0)
project(example_project)
###############################################################################
## file globbing ##############################################################
###############################################################################
# these instructions search the directory tree when cmake is
# invoked and put all files that match the pattern in the variables
# `sources` and `data`
file(GLOB_RECURSE sources src/main/*.cpp src/main/*.h)
file(GLOB_RECURSE sources_test src/test/*.cpp)
file(GLOB_RECURSE data resources/*)
# you can use set(sources src/main.cpp) etc if you don''t want to
# use globing to find files automatically
###############################################################################
## target definitions #########################################################
###############################################################################
# add the data to the target, so it becomes visible in some IDE
add_executable(example ${sources} ${data})
# just for example add some compiler flags
target_compile_options(example PUBLIC -std=c++1y -Wall -Wfloat-conversion)
# this lets me include files relative to the root src dir with a <> pair
target_include_directories(example PUBLIC src/main)
# this copies all resource files in the build directory
# we need this, because we want to work with paths relative to the executable
file(COPY ${data} DESTINATION resources)
###############################################################################
## dependencies ###############################################################
###############################################################################
# this defines the variables Boost_LIBRARIES that contain all library names
# that we need to link to
find_package(Boost 1.36.0 COMPONENTS filesystem system REQUIRED)
target_link_libraries(example PUBLIC
${Boost_LIBRARIES}
# here you can add any library dependencies
)
###############################################################################
## testing ####################################################################
###############################################################################
# this is for our testing framework
# we don''t add REQUIRED because it''s just for testing
find_package(GTest)
if(GTEST_FOUND)
add_executable(unit_tests ${sources_test} ${sources})
# we add this define to prevent collision with the main
# this might be better solved by not adding the source with the main to the
# testing target
target_compile_definitions(unit_tests PUBLIC UNIT_TESTS)
# this allows us to use our executable as a link library
# therefore we can inherit all compiler options and library dependencies
set_target_properties(example PROPERTIES ENABLE_EXPORTS on)
target_link_libraries(unit_tests PUBLIC
${GTEST_BOTH_LIBRARIES}
example
)
target_include_directories(unit_tests PUBLIC
${GTEST_INCLUDE_DIRS} # doesn''t do anything on Linux
)
endif()
###############################################################################
## packaging ##################################################################
###############################################################################
# all install commands get the same destination. this allows us to use paths
# relative to the executable.
install(TARGETS example DESTINATION example_destination)
# this is basically a repeat of the file copy instruction that copies the
# resources in the build directory, but here we tell cmake that we want it
# in the package
install(DIRECTORY resources DESTINATION example_destination)
# now comes everything we need, to create a package
# there are a lot more variables you can set, and some
# you need to set for some package types, but we want to
# be minimal here
set(CPACK_PACKAGE_NAME "MyExample")
set(CPACK_PACKAGE_VERSION "1.0.0")
# we don''t want to split our program up into several things
set(CPACK_MONOLITHIC_INSTALL 1)
# This must be last
include(CPack)