You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

迁移算法至CUDA时,CMake项目中PROJ与GDAL导出目标问题咨询

解决同一CMake项目中PROJ与GDAL的导出目标冲突问题

问题背景

在将算法从CPU迁移到CUDA的项目中,引入SQLite3、PROJ、GDAL作为Git子模块依赖,CMake配置阶段出现以下错误:

  1. 初始报错:

export called with target "GDAL" which requires target "proj" that is not in any export set

  1. 添加自定义install(EXPORT)后新增报错:

An exported target cannot depend upon another target which is exported multiple times. Consider consolidating the exports of the "proj" target to a single export.

核心原因:PROJ的CMake配置默认会生成自身的导出集(proj-targets.cmake),用户额外添加的install(EXPORT)又重复导出PROJ,导致GDAL导出时检测到PROJ存在于多个导出集中,违反CMake的导出规则。

可行解决方案

方案1:禁用PROJ自身导出,统一管理导出集

利用PROJ的CMake选项禁用其默认安装导出逻辑,改用项目统一的导出集管理PROJ和GDAL:

修改PROJ相关CMake代码:

# PROJ
# 禁用PROJ自带的安装导出
set(PROJ_BUILD_INSTALL OFF CACHE BOOL "")
set(BUILD_APPS 0)
set(BUILD_TESTING 0)
add_subdirectory("${DEPS_DIR}/proj")

# 统一导出PROJ和GDAL到同一个集合
install(TARGETS proj GDAL
        EXPORT MyProjectTargets
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib
        RUNTIME DESTINATION bin
        INCLUDES DESTINATION include)
install(EXPORT MyProjectTargets
        FILE MyProjectTargets.cmake
        DESTINATION "${CMAKE_BINARY_DIR}/install/")

同时移除GDAL部分的冗余查找代码(add_subdirectory已直接引入目标,无需重复查找):

# GDAL
set(SQLite3_HAS_MUTEX_ALLOC 1)
set(BUILD_SHARED_LIBS 0)
set(BUILD_TESTING 0)
set(BUILD_APPS 0)
set(GDAL_BUILD_OPTIONAL_DRIVERS 0)
set(OGR_BUILD_OPTIONAL_DRIVERS 0)
set(GDAL_USE_TIFF_INTERNAL 1)
set(GDAL_USE_TIFF 0)
set(GDAL_USE_GEOTIFF_INTERNAL 1)
set(GDAL_USE_GEOTIFF 0)
add_subdirectory("${DEPS_DIR}/gdal")
# 移除以下冗余代码
# set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${CMAKE_BINARY_DIR}/bin/lib/cmake/gdal)
# find_package(GDAL CONFIG)
# if(NOT GDAL_FOUND)
#     find_package(GDAL REQUIRED)
# endif()

方案2:将PROJ作为ExternalProject构建,与GDAL解耦

把PROJ从add_subdirectory改为ExternalProject_Add,让它在独立CMake上下文构建,GDAL通过find_package查找已安装的PROJ,避免同一上下文的导出冲突:

修改前三者的CMake代码:

if(BUILD_DEPS)
    # SQLite3
    include(ExternalProject)
    ExternalProject_Add(sqlite3
        SOURCE_DIR "${DEPS_DIR}/sqlite"
        CONFIGURE_COMMAND ${DEPS_DIR}/sqlite/configure --all --prefix=${CMAKE_BINARY_DIR} CFLAGS="-Os" CXXFLAGS="-Os" SQLITE_THREADSAFE=2 SQLITE_OMIT_COMPLETE=1 SQLITE_OMIT_CHECK=1 SQLITE_OMIT_DEPRECATED=1 --disable-debug
        BUILD_COMMAND ${MAKE}
        INSTALL_COMMAND ${MAKE} install)

    # PROJ 作为独立外部项目构建
    ExternalProject_Add(proj
        SOURCE_DIR "${DEPS_DIR}/proj"
        DEPENDS sqlite3
        CMAKE_ARGS
            -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR}
            -DBUILD_APPS=0
            -DBUILD_TESTING=0
            -DSQLITE3_INCLUDE_DIR=${CMAKE_BINARY_DIR}/include
            -DSQLite3_LIBRARY=${CMAKE_BINARY_DIR}/lib/libsqlite3.a
            -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
        BUILD_COMMAND ${CMAKE_COMMAND} --build .
        INSTALL_COMMAND ${CMAKE_COMMAND} --install .)

    # GDAL
    set(SQLite3_HAS_MUTEX_ALLOC 1)
    set(BUILD_SHARED_LIBS 0)
    set(BUILD_TESTING 0)
    set(BUILD_APPS 0)
    set(GDAL_BUILD_OPTIONAL_DRIVERS 0)
    set(OGR_BUILD_OPTIONAL_DRIVERS 0)
    set(GDAL_USE_TIFF_INTERNAL 1)
    set(GDAL_USE_TIFF 0)
    set(GDAL_USE_GEOTIFF_INTERNAL 1)
    set(GDAL_USE_GEOTIFF 0)
    # 让GDAL能找到PROJ的安装目录
    set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${CMAKE_BINARY_DIR})
    # 确保PROJ安装完成后再构建GDAL
    add_dependencies(gdal proj)
    add_subdirectory("${DEPS_DIR}/gdal")
endif()

方案3:禁用GDAL的导出逻辑(仅适用于内部使用场景)

如果项目仅在内部使用GDAL,不需要导出其目标供其他项目调用,可以直接禁用GDAL的安装导出:

# GDAL部分添加选项,禁用安装导出
set(GDAL_BUILD_INSTALL OFF CACHE BOOL "")

内容的提问来源于stack exchange,提问作者rbaleksandar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 19:24:51