Cómo agregar correctamente directorios include con CMake


Hace aproximadamente un año pregunté acerca de dependencias de cabecera en CMake.

Recientemente me di cuenta de que el problema parecía ser que CMake consideraba que esos archivos de encabezado eran externos al proyecto. Al menos, cuando se genera un proyecto Code:: Blocks los archivos de cabecera no aparecen dentro del proyecto (los archivos fuente sí). Por lo tanto, me parece que CMake considera que esos encabezados son externos al proyecto, y no los rastrea en las dependencias.

A la búsqueda rápida en el tutorial de CMake solo apuntaba a include_directories que no parece hacer lo que deseo...

¿Cuál es la forma correcta de indicar a CMake que un directorio en particular contiene encabezados para ser incluidos, y que esos encabezados deben ser rastreados por el Makefile generado?

Author: Peter Mortensen, 2012-12-04

4 answers

Se deben hacer dos cosas.

Primero agregue el directorio a incluir:

target_include_directories(test PRIVATE ${YOUR_DIRECTORY})

En caso de que esté atascado con una versión muy antigua de CMake (2.8.10 o anterior) sin soporte para target_include_directories, también puede usar el legado include_directories en su lugar:

include_directories(${YOUR_DIRECTORY})

Luego también debe agregar los archivos de encabezado a la lista de sus archivos de origen para el destino actual, por ejemplo:

set(SOURCES file.cpp file2.cpp ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)
add_executable(test ${SOURCES})

De esta manera, los archivos de cabecera aparecerán como dependencias en el Makefile, y también por ejemplo en el generado Proyecto de Visual Studio, si genera uno.

Cómo usar esos archivos de encabezado para varios destinos:

set(HEADER_FILES ${YOUR_DIRECTORY}/file1.h ${YOUR_DIRECTORY}/file2.h)

add_library(mylib libsrc.cpp ${HEADER_FILES})
target_include_directories(mylib PRIVATE ${YOUR_DIRECTORY})
add_executable(myexec execfile.cpp ${HEADER_FILES})
target_include_directories(myexec PRIVATE ${YOUR_DIRECTORY})
 178
Author: SirDarius,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 23:07:05

Primero, usa include_directories() para decirle a CMake que agregue el directorio como -I a la línea de comandos de compilación. Segundo, lista los encabezados en su llamada add_executable() o add_library().

Como ejemplo, si las fuentes de tu proyecto están en src, y necesitas encabezados de include, puedes hacerlo así:

include_directories(include)

add_executable(MyExec
  src/main.c
  src/other_source.c
  include/header1.h
  include/header2.h
)
 48
Author: Angew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 23:07:46

CMake es más como un lenguaje de script si se compara con otras formas de crear Makefile (por ejemplo, make o qmake). No es muy genial como Python, pero aún así.

No hay tal cosa como un "manera apropiada" si se mira en varios proyectos de código abierto cómo las personas incluyen directorios. Pero hay dos maneras de hacerlo.

  1. Crude include_directories agregará un directorio al proyecto actual y a todos los demás proyectos descendientes que agregará a través de una serie de comandos add_subdirectory . A veces la gente dice que tal enfoque es legado.

  2. Una forma más elegante es con target_include_directories. Permite anexar un directorio para un proyecto/objetivo específico sin (tal vez) herencia innecesaria o colisión de varios directorios include. También permite realizar incluso una configuración sutil y añadir uno de los siguientes marcadores para este comando.

PRIVATE - use only para este objetivo de compilación especificado

PUBLIC - utilícelo para el objetivo especificado y para los objetivos que se vinculan con este proyecto

INTERFAZ use úsala solo para destinos que enlacen con el proyecto actual

PS:

  1. Ambos comandos permiten marcar un directorio como SISTEMA para dar una pista de que no es su negocio que los directorios especificados contendrán advertencias.

  2. Una respuesta similar es con otros pares de comandos target_compile_definitions/add_definitions, target_compile_options/CMAKE_C_FLAGS

 6
Author: bruziuz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 23:13:15

Yo tenía el mismo problema.

El directorio de mi proyecto era así:

    --project
    ---Classes
    ----Application
    -----.h and .c files
    ----OtherFolders
    --main.cpp

Y lo que solía incluir los archivos en todas esas carpetas:

    file(GLOB source_files
            "*.h"
            "*.cpp"
            "Classes/*/*.cpp"
            "Classes/*/*.h"
    )

    add_executable(Server ${source_files})

Y funcionó totalmente.

 1
Author: Seyed Hussein Mirzaki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-15 23:13:49