使用 CMake 包含具有相同名称但来自不同库的标头

问题描述 投票:0回答:2

我有两个(或更多)库,其中包含具有相同名称的头文件(例如“point.h”)。在我的项目中,我需要在不同的上下文中使用这些标头中定义的类的属性,但是当然不可能以常见的方式包含正确的文件,因为同名存在歧义。

许多库通过“命名空间”其标头来解决这个问题(例如,“#include ”)。我想这样做。如何配置 CMake 来实现此目的?有没有一种常见的(可能是简单的)方法来做到这一点?

这是我的 CMakeLists.txt:

cmake_minimum_required(VERSION 3.5)

project(GISManager LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(OSMManager REQUIRED) #First libray
find_package(GeoJSONParser REQUIRED) #Second library

set(GISManager_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src)
set(GISManager_H ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(Hdrs ${GISManager_H}/gismanager.h )
set(Srcs ${GISManager_SRC}/gismanager.cpp)

add_library(GISManager ${Hdrs} ${Srcs})
target_include_directories(GISManager PUBLIC
    $<BUILD_INTERFACE:${GISManager_H}/>
    ${OSMManager_INCLUDE_DIRS}/
    ${GeoJSONParser_INCLUDE_DIRS}/
)
target_link_libraries(GISManager ${OSMManager_LIBRARIES} ${GeoJSONParser_LIBRARIES})

add_executable(GISManager_Test ${Hdrs} ${Srcs} ${GISManager_SRC}/main.cpp)
target_include_directories(GISManager_Test PUBLIC
    $<BUILD_INTERFACE:${GISManager_H}/>
    ${OSMManager_INCLUDE_DIRS}/
    ${GeoJSONParser_INCLUDE_DIRS}/
)
target_link_libraries(GISManager_Test ${OSMManager_LIBRARIES} ${GeoJSONParser_LIBRARIES})

install(FILES  ${Hdrs}  DESTINATION include/GISManager-${version})
install(TARGETS GISManager
        DESTINATION lib/GISManager-${version}
        EXPORT GISManager-targets)
install(EXPORT GISManager-targets
        DESTINATION lib/GISManager-${version})

configure_file(
   ${GISManager_SOURCE_DIR}/pkg/gismanager-config.cmake.in
   ${GISManager_BINARY_DIR}/pkg/gismanager-config.cmake @ONLY)

configure_file(
   ${GISManager_SOURCE_DIR}/pkg/gismanager-config-version.cmake.in
   ${GISManager_BINARY_DIR}/pkg/gismanager-config-version.cmake @ONLY)

install(FILES ${GISManager_BINARY_DIR}/pkg/gismanager-config.cmake
         ${GISManager_BINARY_DIR}/pkg/gismanager-config-version.cmake
         DESTINATION lib/GISManager-${version})

这些库是使用接下来的两个 CMakeLists.txt 文件生成的:

cmake_minimum_required(VERSION 3.5)

project(GeoJSONParser LANGUAGES CXX)
set(version 1.0)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(GeoJSONParser_H ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(GeoJSONParser_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src)
find_path(RapidJSON_INCLUDE_DIRS rapidjson)


set(HDRS
    ${GeoJSONParser_H}/object.h
    ${GeoJSONParser_H}/featurecollection.h
    ${GeoJSONParser_H}/feature.h
    ${GeoJSONParser_H}/geometry.h
    ${GeoJSONParser_H}/point.h
    ${GeoJSONParser_H}/multipoint.h
    ${GeoJSONParser_H}/linestring.h
    ${GeoJSONParser_H}/multilinestring.h
    ${GeoJSONParser_H}/polygon.h
    ${GeoJSONParser_H}/multipolygon.h
    ${GeoJSONParser_H}/geometrycollection.h
    ${GeoJSONParser_H}/utils.h
    ${GeoJSONParser_H}/types.h
)
set(SRCS
    ${GeoJSONParser_SRC}/featurecollection.cpp
    ${GeoJSONParser_SRC}/feature.cpp
    ${GeoJSONParser_SRC}/point.cpp
    ${GeoJSONParser_SRC}/multipoint.cpp
    ${GeoJSONParser_SRC}/linestring.cpp
    ${GeoJSONParser_SRC}/multilinestring.cpp
    ${GeoJSONParser_SRC}/polygon.cpp
    ${GeoJSONParser_SRC}/multipolygon.cpp
    ${GeoJSONParser_SRC}/geometrycollection.cpp
    ${GeoJSONParser_SRC}/utils.cpp
)

add_library(GeoJSONParser ${HDRS} ${SRCS})
target_include_directories(GeoJSONParser PUBLIC $<BUILD_INTERFACE:${GeoJSONParser_H}/> ${RapidJSON_INCLUDE_DIRS})

add_executable(GeoJSONParser_Test ${HDRS} ${SRCS} ${GeoJSONParser_SRC}/main.cpp)
target_include_directories(GeoJSONParser_Test PUBLIC $<BUILD_INTERFACE:${GeoJSONParser_H}/> ${RapidJSON_INCLUDE_DIRS})

install(FILES  ${HDRS}  DESTINATION include/GeoJSONParser-${version})
install(TARGETS GeoJSONParser
        DESTINATION lib/GeoJSONParser-${version}
        EXPORT GeoJSONParser-targets)
install(EXPORT GeoJSONParser-targets
        DESTINATION lib/GeoJSONParser-${version})

configure_file(
   ${GeoJSONParser_SOURCE_DIR}/pkg/geojsonparser-config.cmake.in
   ${GeoJSONParser_BINARY_DIR}/pkg/geojsonparser-config.cmake @ONLY)

configure_file(
   ${GeoJSONParser_SOURCE_DIR}/pkg/geojsonparser-config-version.cmake.in
   ${GeoJSONParser_BINARY_DIR}/pkg/geojsonparser-config-version.cmake @ONLY)

install(FILES ${GeoJSONParser_BINARY_DIR}/pkg/geojsonparser-config.cmake
         ${GeoJSONParser_BINARY_DIR}/pkg/geojsonparser-config-version.cmake
         DESTINATION lib/GeoJSONParser-${version})


cmake_minimum_required(VERSION 3.5)

project(OSMManager LANGUAGES CXX)
set(version 1.0)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(OSMManager_H ${CMAKE_CURRENT_SOURCE_DIR}/include)
set(OSMManager_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src)
find_path(RapidJSON_INCLUDE_DIRS rapidjson)
find_package(PROJ)

set(HDRS
    ${OSMManager_H}/root.h
    ${OSMManager_H}/node.h
    ${OSMManager_H}/way.h
    ${OSMManager_H}/relation.h
    ${OSMManager_H}/coordinatesconverter.h
    ${OSMManager_H}/utils.h
    ${OSMManager_H}/types.h
    ${OSMManager_H}/tinyxml2.h
)
set(SRCS
    ${OSMManager_SRC}/root.cpp
    ${OSMManager_SRC}/node.cpp
    ${OSMManager_SRC}/way.cpp
    ${OSMManager_SRC}/relation.cpp
    ${OSMManager_SRC}/coordinatesconverter.cpp
    ${OSMManager_SRC}/tinyxml2.cpp
)

add_library(OSMManager ${HDRS} ${SRCS})
target_include_directories(OSMManager PUBLIC $<BUILD_INTERFACE:${OSMManager_H}/> ${RapidJSON_INCLUDE_DIRS} ${PROJ_INCLUDE_DIRS})
target_link_libraries(OSMManager ${PROJ_LIBRARIES})

add_executable(OSMManager_Test ${HDRS} ${SRCS} ${OSMManager_SRC}/main.cpp)
target_include_directories(OSMManager_Test PUBLIC $<BUILD_INTERFACE:${OSMManager_H}/> ${RapidJSON_INCLUDE_DIRS} ${PROJ_INCLUDE_DIRS})
target_link_libraries(OSMManager_Test ${PROJ_LIBRARIES})

install(FILES ${HDRS} DESTINATION include/OSMManager-${version})
install(TARGETS OSMManager
        DESTINATION lib/OSMManager-${version}
        EXPORT OSMManager-targets)
install(EXPORT OSMManager-targets
        DESTINATION lib/OSMManager-${version})

configure_file(
   ${OSMManager_SOURCE_DIR}/pkg/osmmanager-config.cmake.in
   ${OSMManager_BINARY_DIR}/pkg/osmmanager-config.cmake @ONLY)

configure_file(
   ${OSMManager_SOURCE_DIR}/pkg/osmmanager-config-version.cmake.in
   ${OSMManager_BINARY_DIR}/pkg/osmmanager-config-version.cmake @ONLY)

install(FILES ${OSMManager_BINARY_DIR}/pkg/osmmanager-config.cmake
         ${OSMManager_BINARY_DIR}/pkg/osmmanager-config-version.cmake
         DESTINATION lib/OSMManager-${version})



文件 library-config.cmake.in 在两个库中具有或多或少相同的结构,这是 GeoJSONParser 的结构:

# Compute installation prefix relative to this file.
get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_prefix "${_dir}/../.." ABSOLUTE)

# Import the targets.
include("${_prefix}/lib/GeoJSONParser-@version@/GeoJSONParser-targets.cmake")

# Report other information.
set(GeoJSONParser_INCLUDE_DIRS "${_prefix}/include/GeoJSONParser-@version@/")

file(GLOB GeoJSONParser_LIBRARIES "${_prefix}/lib/GeoJSONParser-@version@/lib*")

正如您在上面看到的,这两个库都有一个“utils.h”,包括一些特定于相关库的函数。

c++ cmake include
2个回答
0
投票

只需确保传递给编译器的包含目录是包含这样一个中间目录的目录,该中间目录执行您想要为

#include
指令提供的命名空间。

您需要对源树和安装树都这样做。

如果您想获得配置代码的答案,请提供一个最小的、有代表性的示例设置。


0
投票

我认为可能有两种方法:
第二种方法我没试过。


第一种方法是您可以通过在

#include
中添加文件夹名称来添加同名头文件。

假设您在不同的文件夹中有两个“point.h”文件:
“include/two_dim/point.h”和“include/third_dim/point.h”

您可以考虑将文件夹名称放入源代码中,CPP:

#include two_dim/point.h
#include three_dim/point.h

这是“CMakeLists.txt”部分的示例

set(project_name GISManager) 
project(${project_name})
set(includes include)
set(exec_sources src/main.cpp) 
add_executable( ${project_name} ${exec_sources} )
target_include_directories ( ${project_name} PUBLIC ${includes} )

第二种方法是使用两个“target_include_directories”行。

假设您在不同的文件夹中有两个“point.h”文件,但父文件夹名称“geo”也相同:
“include/two_dim/geo/point.h”和“include/third_dim/geo/point.h”

您可以考虑将文件夹名称放入源代码中,CPP:

#include geo/point.h
#include geo/point.h

这是“CMakeLists.txt”部分的示例

set(project_name GISManager) 
project(${project_name})
set(includes_two_dim include/two_dim)
set(includes_three_dim include/three_dim)
set(exec_sources src/main.cpp) 
add_executable( ${project_name} ${exec_sources} )
target_include_directories ( ${project_name} PUBLIC ${includes_two_dim} )
target_include_directories ( ${project_name} PUBLIC ${includes_three_dim} )
© www.soinside.com 2019 - 2024. All rights reserved.