CMake使用ExternalProject在zlib与libpng依赖间传递变量的问题
问题根因
- 选项配置错误:libpng的
PNG_BUILD_ZLIB选项逻辑为开启时使用libpng内置的zlib源码构建,关闭时才会查找外部自定义zlib,你当前将该选项设为1,自然不会读取你传入的zlib路径。 - 变量作用域问题:主项目中通过
set设置的缓存变量仅在主项目CMake上下文生效,ExternalProject_Add触发的是独立的子构建流程,不会继承主项目的任何缓存变量,必须通过CMAKE_ARGS显式传递参数。 - 头文件路径不全:zlib有两个头文件目录,
zlib.h存放在源码目录,编译生成的配置头文件zconf.h存放在zlib的构建目录,你仅配置了源码目录,会导致找不到zconf.h。 - 传参写法错误:你之前的传参
"-DZLIB_INCLUDE_DIRS=\"${${ZLIB_INCLUDE_DIRS}}\""存在两层多余的变量解引用和多余的转义引号,会导致路径解析异常。
修正方案
第一步:修正zlib头文件路径配置
在获取zlib的源码目录和构建目录后,同时将两个目录加入zlib的头文件路径,同时设置libpng会查找的ZLIB_INCLUDE_DIR变量:
# Set zlib variables required by libpng ExternalProject_Get_property(zlib BINARY_DIR) ExternalProject_Get_property(zlib SOURCE_DIR) set(zlib_DIR "${BINARY_DIR}/Debug" CACHE PATH "zlib dir" FORCE) set(ZLIB_ROOT ${SOURCE_DIR} CACHE PATH "zlib root" FORCE) # 同时包含源码目录(zlib.h)和构建目录(生成的zconf.h) set(ZLIB_INCLUDE_DIRS ${SOURCE_DIR} ${BINARY_DIR} CACHE PATH "zlib include dir" FORCE) # libpng内部同时会查找ZLIB_INCLUDE_DIR变量,需同步设置 set(ZLIB_INCLUDE_DIR ${ZLIB_INCLUDE_DIRS} CACHE PATH "zlib include dir" FORCE) if(WIN32) set(ZLIB_LIBRARY ${zlib_DIR}/zlibd.dll CACHE FILEPATH "zlib dynamic library" FORCE) set(ZLIB_LIBRARIES ${zlib_DIR}/zlibd.dll CACHE FILEPATH "zlib dynamic library" FORCE) else() set(ZLIB_LIBRARY ${zlib_DIR}/libzlibd.so CACHE FILEPATH "zlib dynamic library" FORCE) set(ZLIB_LIBRARIES ${zlib_DIR}/libzlibd.so CACHE FILEPATH "zlib dynamic library" FORCE) endif()
第二步:修正libpng的ExternalProject配置
关闭PNG_BUILD_ZLIB选项,同时将所有zlib相关变量显式传入CMAKE_ARGS:
ExternalProject_Add(libpng PREFIX ${CMAKE_CURRENT_BINARY_DIR}/deps/png DEPENDS zlib INSTALL_DIR ${CMAKE_INSTALL_PREFIX} DOWNLOAD_DIR "" TMP_DIR ${DEPS_TMP}/png STAMP_DIR ${DEPS_STAMP}/png LOG_DIR ${DEPS_LOG}/png BINARY_DIR ${DEPS_BUILD}/png SOURCE_DIR ${DEPS}/libpng INSTALL_COMMAND "${CMAKE_COMMAND}" -E echo "Skipping install step for dependency libpng" INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} BUILD_ALWAYS OFF CMAKE_ARGS "-DPNG_BUILD_ZLIB=0" # 关闭内置zlib构建,使用外部自定义zlib "-DZLIB_ROOT=${ZLIB_ROOT}" "-DZLIB_INCLUDE_DIR=${ZLIB_INCLUDE_DIR}" "-DZLIB_INCLUDE_DIRS=${ZLIB_INCLUDE_DIRS}" "-DZLIB_LIBRARY=${ZLIB_LIBRARY}" "-DZLIB_LIBRARIES=${ZLIB_LIBRARIES}" "-DPNG_SHARED=1" "-DPNG_STATIC=0" "-DPNG_TESTS=0" "-DPNG_EXECUTABLES=0" "-DPNG_HARDWARE_OPTIMIZATIONS=1" "-DPNG_DEBUG=0" )
可选优化方案
你可以去掉zlib的跳过安装配置,让zlib正常执行安装步骤,之后在libpng的CMAKE_ARGS中传入"-DCMAKE_PREFIX_PATH=${CMAKE_INSTALL_PREFIX}",libpng会自动通过find_package找到已安装的zlib,无需手动传递所有zlib相关变量,配置更简洁不易出错。
内容的提问来源于stack exchange,提问作者rbaleksandar
相关产品推荐
相关产品推荐

