c++ - otro - incluir header en c
Manejo de dependencias de archivos de cabecera con cmake (4)
Estoy usando CMake en un pequeño proyecto de C ++ y hasta ahora funciona muy bien ... con un giro: x
Cuando cambio un archivo de encabezado, generalmente requiere volver a compilar varios archivos de fuentes (aquellos que lo incluyen, directa o indirectamente), sin embargo, parece que cmake solo detecta algunos de los archivos de origen que se recompilarán, lo que lleva a un estado dañado. Puedo evitar esto borrando el proyecto y reconstruyéndolo desde cero, pero esto elude el objetivo de usar una utilidad make: solo recompilando lo que se necesita.
Por lo tanto, supongo que estoy haciendo algo mal.
Mi proyecto está muy organizado:
- un directorio superior donde se sientan todos los recursos, el principal CMakeLists.txt se sienta allí
- un directorio "incluir" donde se encuentran todos los encabezados públicos (en varios subdirectorios)
- un directorio "src" donde están todos los subdirectorios para los archivos de fuentes, el src CMakeLists.txt se sienta allí
- un CMakeLists.txt por subdirectorio en el directorio "src"
El directorio principal tiene:
cmake_minimum_required(VERSION 2.8)
project(FOO)
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
# Compiler Options
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++0x -Wall -Wextra -Werror")
include_directories($(FOO_SOURCE_DIR)/include)
add_subdirectory(src)
El directorio "src":
add_subdirectory(sub1)
add_subdirectory(sub2)
add_subdirectory(sub3)
add_subdirectory(sub4)
add_executable(foo main.cpp)
target_link_libraries(foo sub1 sub2 sub3 sub4)
Donde sub4
depende de sub3
que depende de sub2
que depende de sub1
Y un ejemplo de un subdirectorio (sub3):
set(SUB3_SRCS
File1.cpp
File2.cpp
File3.cpp
File4.cpp
File5.cpp
File6.cpp
)
add_library(sub3 ${SUB3_SRCS})
target_link_libraries(sub3 sub1 sub2)
Me alegraría que alguien pudiera señalar mi error a mí, buscando aquí o en CMake no cedió nada, así que supongo que es muy fácil o debería funcionar de la caja ...
(como referencia, estoy usando cmake versión 2.8.2 en MSYS)
EDITAR :
Gracias a la sugerencia de Bill, he comprobado el archivo depend.make
generado por CMake, y de hecho falta (severamente). Aquí hay un ejemplo:
src/sub3/CMakeFiles/sub3.dir/File1.cpp.obj: ../src/sub3/File1.cpp
Sí, eso es todo, no se hizo referencia a ninguna de las inclusiones: x
¿Ejecutó cmake antes o después de agregar las inclusiones a sus archivos cpp?
Me encontré con este problema y volver a ejecutar cmake lo solucionó. Agregué el include post-cmake.
Acabo de golpear el mismo problema. Después de cambiar las rutas en include_directories()
de absoluta a relativa, agregó las dependencias apropiadas.
Parece que CMake intenta adivinar qué encabezados son el sistema y cuáles están relacionados con el proyecto. Sospecho que los directorios que comienzan con /
pasan como -isystem /some/path
y, por lo tanto, no se presentan en las dependencias generadas.
Si no puede reemplazar ${FOO_SOURCE_DIR}
con la ruta relativa, puede intentar calcular la ruta relativa utilizando las funciones CMake apropiadas. Es decir:
file(RELATIVE_PATH FOO_SOURCE_REL_DIR
${CMAKE_CURRENT_SOURCE_DIR}
${FOO_SOURCE_DIR}/.)
include_directories(${FOO_SOURCE_REL_DIR}/include)
Aparentemente, cmake elimina el sistema e incluye rutas desde los árboles de dependencias (gracias @ony por esta sugerencia). Esto probablemente tenga sentido la mayor parte del tiempo, pero a veces cmake no sabe lo que el compilador cree que es una ruta del sistema o no. Estamos utilizando una compilación gcc personalizada que ignora /usr/include
, pero cmake cree que no la ignora. Para forzar a cmake a hacer /usr/include
una dependencia que NO esté optimizada, pruebe este truco: anteponer /.
al camino
Estoy tratando de hacer que todas las dependencias de la biblioteca usen la característica de dependencia cmake, incluidas ciertas bibliotecas de terceros que no siempre están instaladas por defecto en Linux o incluso disponibles. Por ejemplo, compresión Z-lib.
El siguiente objetivo de interfaz funcionó bien si la lib lib incluye no estaba en /usr/include
, pero se rompería si lo estuviera.
find_package(ZLIB REQUIRED)
message(status "found zlib ${ZLIB_LIBRARIES}")
message(status "found zlib includes ${ZLIB_INCLUDE_DIRS}")
target_link_libraries(zlib_target INTERFACE ${ZLIB_LIBRARIES})
target_include_directories(zlib_target INTERFACE ${ZLIB_INCLUDE_DIRS})
Cambié la última línea a
target_include_directories(zlib_target INTERFACE /.${ZLIB_INCLUDE_DIRS})
Y funcionó. Ahora los objetivos que dependían de zlib_target
obtendrían automáticamente -I/./usr/include
durante la compilación.
Debería mirar los archivos depend.make
en su árbol binario. Será en CMakeFiles/target.dir/depend.make
. Intenta encontrar uno de los que falta un archivo .h
que crees que debería tener. A continuación, cree un informe de errores para cmake o envíe un correo electrónico a la lista de correo de cmake.