¿Cuál es la diferencia entre include_directories y target_include_directories en CMake?

134

Tengo una estructura de directorio para mi código C ++ que es así:

|
|->include
|->src

Estoy escribiendo un archivo CMakeLists.txt para mi código. Quiero entender la diferencia entre include_directoriesy target_include_directoriesen CMake.

¿Cuál es la diferencia entre su uso y para agregar mi ruta de archivo de inclusión cuál debo usar?

Ujjwal Aryan
fuente
44
¿Has leído la documentación para include_directoriesy target_include_directories? ¿Qué es lo que no entiendes sobre la diferencia entre ellos?
Algún tipo programador
74
No hay claridad en la documentación. Lo leí y deduje lo que Angew ha escrito en su respuesta, pero no hay descripciones, ejemplos y para un sistema destinado a la construcción de proyectos, no hay ejemplos basados ​​en proyectos en la documentación de CMake. Si hubiera habido una buena y exhaustiva documentación de CMake, no habría estado cargando a la comunidad con estas preguntas.
Ujjwal Aryan
Los conceptos de cmake están poco documentados. Especialmente objetivo y "sin objetivo".
John Greene

Respuestas:

148

include_directories(x/y)afecta el alcance del directorio. Todos los objetivos en esta CMakeList, así como aquellos en todos los subdirectorios agregados después del punto de su llamada, tendrán la ruta x/yagregada a su ruta de inclusión.

target_include_directories(t x/y)tiene alcance objetivo: se agrega x/ya la ruta de inclusión para el objetivo t.

Desea el primero si todos sus objetivos usan los directorios de inclusión en cuestión. Desea el último si la ruta es específica de un objetivo, o si desea un control más preciso de la visibilidad de la ruta. Este último viene del hecho de que target_include_directories()es compatible con los PRIVATE, PUBLICy INTERFACEcalificadores.

Angew ya no está orgulloso de SO
fuente
35
Creo que este último generalmente debería preferirse (siempre y cuando uno esté usando cmake 3). Tiene el beneficio adicional de x/yincluir la ruta de inclusión de cualquier objetivo dependiente que use ten sus target_link_librariescomandos. Por supuesto, hay un lugar para el primero, pero creo que el último es generalmente mejor.
Phil
2
La respuesta original indicaba que solo los objetivos y subdirecciones añadidos después include_directoriesse verán afectados. Estoy editando la respuesta: la documentación indica claramente que todos los objetivos en las CMakeLists actuales están afectados. La documentación no menciona pero solo subdirece después de que la llamada se ve afectada (como se indicó correctamente en la respuesta original)
tamas.kenez
@Phil, target_include_directoriesse introdujo en CMake 2.8.11 (mayo de 2013)
tamas.kenez
@ tamas.kenez Gracias por llamar mi atención sobre esto, solucionado. Estaba bastante convencido de que era una cosa "de ahora en adelante".
Angew ya no está orgulloso de SO
40

Además de lo que dice correctamente la respuesta de Angew , otra diferencia muy importante entre include_directoriesy target_include_directorieses que, cuando se usa con PUBLICo INTERFACE, este último llena la INTERFACE_INCLUDE_DIRECTORIESpropiedad del objetivo. Esta propiedad es útil cuando otro objetivo utiliza target_link_librariespara vincular al objetivo original, ya que el objetivo de vinculación tendrá automáticamente los directorios de inclusión agregados. Ver ejemplo .

Esta característica importante está bastante bien oculta en la documentación: target_include_directories menciona la población INTERFACE_INCLUDE_DIRECTORIES, cuya documentación dice:

Cuando las dependencias de destino se especifican utilizando target_link_libraries () , CMake leerá esta propiedad de todas las dependencias de destino para determinar las propiedades de compilación del consumidor.

Antonio
fuente
¡Es la primera vez que leo una explicación comprensible de las PUBLICpropiedades, etc.! Gracias: D
RL-S
2

Como dijo @Angew, la diferencia es:

1, include_directories () es accesible para todos los archivos en el árbol de origen 2, target_include_directories () es accesible solo para un destino específico cuando se compila.

Nick.Rhan
fuente