编写 CMakeLists查找库的findxxx.cmake文件

文章目录

Find模块标准模板

cmake 复制代码
# Find<PackageName>.cmake
# 示例: FindMozPng.cmake 或 FindTurboJpeg.cmake

# ============================================
# 1. 模块基本信息
# ============================================
cmake_minimum_required(VERSION 3.10)
include(FindPackageHandleStandardArgs)
include(SelectLibraryConfigurations)

# ============================================
# 2. 用户可配置变量
# ============================================
# 允许用户通过变量或环境变量指定库路径
if(DEFINED ENV{<PACKAGE>_ROOT})  # 例如: MOZ_PNG_ROOT
    set(<PACKAGE>_ROOT "$ENV{<PACKAGE>_ROOT}")
endif()

if(DEFINED <PACKAGE>_ROOT)
    set(_<PACKAGE>_SEARCH_ROOT PATHS ${<PACKAGE>_ROOT} NO_DEFAULT_PATH)
else()
    set(_<PACKAGE>_SEARCH_ROOT "")
endif()

# ============================================
# 3. 平台架构检测
# ============================================
function(detect_platform_architecture)
    # 平台检测
    if(WIN32)
        set(PLATFORM "Windows")
        if(CMAKE_SIZEOF_VOID_P EQUAL 8)
            set(ARCH "x64")
        else()
            set(ARCH "x86")
        endif()
    elseif(APPLE)
        if(IOS)
            set(PLATFORM "iOS")
            set(ARCH "iphoneos")
        else()
            set(PLATFORM "macOS")
            set(ARCH "macosx")
        endif()
    elseif(ANDROID)
        set(PLATFORM "Android")
        if(CMAKE_ANDROID_ARCH_ABI STREQUAL "armeabi-v7a")
            set(ARCH "ARM")
        elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
            set(ARCH "ARM64")
        elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86")
            set(ARCH "x86")
        elseif(CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64")
            set(ARCH "x86_64")
        else()
            set(ARCH ${CMAKE_ANDROID_ARCH_ABI})
        endif()
    elseif(UNIX)
        set(PLATFORM "Linux")
        if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
            set(ARCH "x64")
        elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i[3456]86")
            set(ARCH "x86")
        elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm")
            set(ARCH "ARM")
        elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64")
            set(ARCH "ARM64")
        else()
            set(ARCH ${CMAKE_SYSTEM_PROCESSOR})
        endif()
    else()
        set(PLATFORM "Unknown")
        set(ARCH ${CMAKE_SYSTEM_PROCESSOR})
    endif()
    
    set(<PACKAGE>_PLATFORM ${PLATFORM} PARENT_SCOPE)
    set(<PACKAGE>_ARCH ${ARCH} PARENT_SCOPE)
endfunction()

# 调用平台检测函数
detect_platform_architecture()

# ============================================
# 4. 搜索路径配置
# ============================================
# 如果用户提供了ROOT,优先使用
if(DEFINED <PACKAGE>_ROOT)
    set(_<PACKAGE>_BASE_DIR ${<PACKAGE>_ROOT})
else()
    # 默认使用模块所在目录(当模块随库一起分发时)
    set(_<PACKAGE>_BASE_DIR ${CMAKE_CURRENT_LIST_DIR})
endif()

# 设置头文件和库文件的搜索路径
set(<PACKAGE>_INCLUDE_DIR
    ${_<PACKAGE>_BASE_DIR}/include
    ${_<PACKAGE>_BASE_DIR}/inc
    ${_<PACKAGE>_BASE_DIR}/include/<package>  # 小写版本
    ${_<PACKAGE>_BASE_DIR}/inc/<package>      # 小写版本
)

# 库文件路径(根据平台架构)
set(<PACKAGE>_LIB_DIR
    ${_<PACKAGE>_BASE_DIR}/lib/${<PACKAGE>_PLATFORM}/${<PACKAGE>_ARCH}
    ${_<PACKAGE>_BASE_DIR}/lib
    ${_<PACKAGE>_BASE_DIR}/libs
)

# ============================================
# 5. 查找头文件
# ============================================
# 主要头文件列表(按优先级)
set(_<PACKAGE>_HEADER_NAMES
    <package>.h        # 例如: png.h, turbojpeg.h
    <Package>.h        # 例如: Png.h
    <PACKAGE>.h        # 例如: PNG.h
)

find_path(<PACKAGE>_INCLUDE_DIR
    NAMES ${_<PACKAGE>_HEADER_NAMES}
    HINTS ${_<PACKAGE>_SEARCH_ROOT}
    PATHS ${<PACKAGE>_INCLUDE_DIR}
    PATH_SUFFIXES include inc
)

# ============================================
# 6. 查找库文件
# ============================================
# 库名称列表(不同平台/配置可能不同)
set(_<PACKAGE>_LIB_NAMES
    <package>          # 例如: png, turbojpeg
    <package>static    # 静态库
    <package>_static   # 静态库(带下划线)
    <package>_s        # 静态库(短格式)
    lib<package>       # Unix前缀
)

# 调试版本库名称
set(_<PACKAGE>_LIB_NAMES_DEBUG
    <package>d         # 调试后缀
    <package>_d        # 调试后缀(带下划线)
    <package>_debug    # 调试后缀(全称)
    ${_<PACKAGE>_LIB_NAMES}  # 也包含基本名称
)

# 查找Release库
find_library(<PACKAGE>_LIBRARY_RELEASE
    NAMES ${_<PACKAGE>_LIB_NAMES}
    HINTS ${_<PACKAGE>_SEARCH_ROOT}
    PATHS ${<PACKAGE>_LIB_DIR}
    PATH_SUFFIXES lib libs Release release REL
)

# 查找Debug库
find_library(<PACKAGE>_LIBRARY_DEBUG
    NAMES ${_<PACKAGE>_LIB_NAMES_DEBUG}
    HINTS ${_<PACKAGE>_SEARCH_ROOT}
    PATHS ${<PACKAGE>_LIB_DIR}
    PATH_SUFFIXES lib libs Debug debug DBG
)

# 如果找不到特定配置的库,尝试通用查找
if(NOT <PACKAGE>_LIBRARY_RELEASE AND NOT <PACKAGE>_LIBRARY_DEBUG)
    find_library(<PACKAGE>_LIBRARY
        NAMES ${_<PACKAGE>_LIB_NAMES}
        HINTS ${_<PACKAGE>_SEARCH_ROOT}
        PATHS ${<PACKAGE>_LIB_DIR}
    )
endif()

# ============================================
# 7. 处理库配置
# ============================================
if(<PACKAGE>_LIBRARY_RELEASE OR <PACKAGE>_LIBRARY_DEBUG)
    # 使用SelectLibraryConfigurations自动设置<PACKAGE>_LIBRARY变量
    select_library_configurations(<PACKAGE>)
elseif(<PACKAGE>_LIBRARY)
    # 如果只有单一库,同时设置为Release和Debug
    set(<PACKAGE>_LIBRARY_RELEASE ${<PACKAGE>_LIBRARY})
    set(<PACKAGE>_LIBRARY_DEBUG ${<PACKAGE>_LIBRARY})
    set(<PACKAGE>_LIBRARY ${<PACKAGE>_LIBRARY})
endif()

# ============================================
# 8. 版本检测(可选)
# ============================================
if(<PACKAGE>_INCLUDE_DIR)
    # 尝试从头文件读取版本
    set(_<PACKAGE>_VERSION_FILE
        ${<PACKAGE>_INCLUDE_DIR}/<package>_version.h
        ${<PACKAGE>_INCLUDE_DIR}/<Package>Version.h
        ${<PACKAGE>_INCLUDE_DIR}/version.h
    )
    
    foreach(_version_file ${_<PACKAGE>_VERSION_FILE})
        if(EXISTS "${_version_file}")
            file(STRINGS "${_version_file}" _version_line
                 REGEX "#define[ \t]+<PACKAGE>_VERSION_[A-Z]+[ \t]+[0-9]+")
            if(_version_line)
                # 解析版本号
                string(REGEX REPLACE ".*#define[ \t]+<PACKAGE>_VERSION_MAJOR[ \t]+([0-9]+).*" "\\1"
                       <PACKAGE>_VERSION_MAJOR "${_version_line}")
                string(REGEX REPLACE ".*#define[ \t]+<PACKAGE>_VERSION_MINOR[ \t]+([0-9]+).*" "\\1"
                       <PACKAGE>_VERSION_MINOR "${_version_line}")
                string(REGEX REPLACE ".*#define[ \t]+<PACKAGE>_VERSION_PATCH[ \t]+([0-9]+).*" "\\1"
                       <PACKAGE>_VERSION_PATCH "${_version_line}")
                
                set(<PACKAGE>_VERSION 
                    "${<PACKAGE>_VERSION_MAJOR}.${<PACKAGE>_VERSION_MINOR}.${<PACKAGE>_VERSION_PATCH}")
                break()
            endif()
        endif()
    endforeach()
endif()

# ============================================
# 9. 验证并设置结果
# ============================================
# 必需变量列表
set(_<PACKAGE>_REQUIRED_VARS <PACKAGE>_INCLUDE_DIR)
if(<PACKAGE>_LIBRARY)
    list(APPEND _<PACKAGE>_REQUIRED_VARS <PACKAGE>_LIBRARY)
elseif(<PACKAGE>_LIBRARY_RELEASE OR <PACKAGE>_LIBRARY_DEBUG)
    list(APPEND _<PACKAGE>_REQUIRED_VARS <PACKAGE>_LIBRARY_RELEASE <PACKAGE>_LIBRARY_DEBUG)
endif()

find_package_handle_standard_args(<PACKAGE>
    FOUND_VAR <PACKAGE>_FOUND
    REQUIRED_VARS ${_<PACKAGE>_REQUIRED_VARS}
    VERSION_VAR <PACKAGE>_VERSION
)

# ============================================
# 10. 创建导入目标
# ============================================
if(<PACKAGE>_FOUND AND NOT TARGET <PACKAGE>::<PACKAGE>)
    # 创建导入目标
    add_library(<PACKAGE>::<PACKAGE> UNKNOWN IMPORTED)
    
    # 设置包含目录
    set_target_properties(<PACKAGE>::<PACKAGE> PROPERTIES
        INTERFACE_INCLUDE_DIRECTORIES "${<PACKAGE>_INCLUDE_DIR}"
    )
    
    # 设置库文件
    if(<PACKAGE>_LIBRARY_RELEASE)
        set_target_properties(<PACKAGE>::<PACKAGE> PROPERTIES
            IMPORTED_CONFIGURATIONS "RELEASE;DEBUG"
            IMPORTED_LOCATION_RELEASE "${<PACKAGE>_LIBRARY_RELEASE}"
        )
    endif()
    
    if(<PACKAGE>_LIBRARY_DEBUG)
        set_target_properties(<PACKAGE>::<PACKAGE> PROPERTIES
            IMPORTED_LOCATION_DEBUG "${<PACKAGE>_LIBRARY_DEBUG}"
        )
    elseif(<PACKAGE>_LIBRARY)
        # 单一库文件,同时用于Release和Debug
        set_target_properties(<PACKAGE>::<PACKAGE> PROPERTIES
            IMPORTED_LOCATION "${<PACKAGE>_LIBRARY}"
        )
    endif()
    
    # 设置输出变量(兼容旧代码)
    set(<PACKAGE>_INCLUDE_DIRS ${<PACKAGE>_INCLUDE_DIR})
    set(<PACKAGE>_LIBRARIES <PACKAGE>::<PACKAGE>)
    
    # 标记高级变量
    mark_as_advanced(
        <PACKAGE>_INCLUDE_DIR
        <PACKAGE>_LIBRARY
        <PACKAGE>_LIBRARY_RELEASE
        <PACKAGE>_LIBRARY_DEBUG
    )
endif()

# ============================================
# 11. 清除内部变量
# ============================================
unset(_<PACKAGE>_SEARCH_ROOT)
unset(_<PACKAGE>_HEADER_NAMES)
unset(_<PACKAGE>_LIB_NAMES)
unset(_<PACKAGE>_LIB_NAMES_DEBUG)
unset(_<PACKAGE>_REQUIRED_VARS)

使用说明

模板中的占位符替换:

将以下占位符替换为实际值:

  • <PACKAGE>: 包名的大写形式(如 MOZ_PNG, TURBOJPEG
  • <Package>: 包名的首字母大写形式(如 MozPng, TurboJpeg
  • <package>: 包名的小写形式(如 moz_png, turbojpeg

根据您的代码修正示例:

如果确实是查找turbojpeg,应该命名为FindTurboJpeg.cmake

cmake 复制代码
# 在模板中替换:
# <PACKAGE> → TURBOJPEG
# <Package> → TurboJpeg
# <package> → turbojpeg

# 头文件名称改为:
set(_TURBOJPEG_HEADER_NAMES
    turbojpeg.h
    jpeglib.h
    jconfig.h
)

# 库名称改为:
set(_TURBOJPEG_LIB_NAMES
    turbojpeg
    turbojpeg-static
    jpeg
    libturbojpeg
)

在CMakeLists.txt中使用:

cmake 复制代码
# 1. 添加模块搜索路径
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# 2. 查找包
find_package(TurboJpeg REQUIRED)

# 3. 使用包(现代方式)
target_link_libraries(my_target PRIVATE TurboJpeg::TurboJpeg)

# 或兼容方式
include_directories(${TURBOJPEG_INCLUDE_DIRS})
target_link_libraries(my_target ${TURBOJPEG_LIBRARIES})

推荐的目录结构:

c 复制代码
项目根目录/
├── CMakeLists.txt
├── cmake/
│   ├── FindTurboJpeg.cmake
│   └── FindOtherLib.cmake
├── include/
├── src/
└── thirdparty/
    └── turbojpeg/
        ├── include/
        │   └── turbojpeg.h
        └── lib/
            ├── Windows/
            │   ├── x64/
            │   │   ├── Debug/
            │   │   └── Release/
            │   └── x86/
            │       ├── Debug/
            │       └── Release/
            └── macOS/
                └── macosx/
                    ├── Debug/
                    └── Release/

这个模板解决了您原始代码中的以下问题:

  1. 模块名称与实际查找的库不一致
  2. 平台检测更全面
  3. 支持更多配置选项
  4. 提供版本检测
  5. 更好的错误处理和用户配置支持

示例如下

根据您的目录结构和参考代码,我为您编写一个适配jbig2dec库的Find模块:

cmake 复制代码
# Findjbig2.cmake - 用于查找jbig2dec库

# ============================================
# 1. 模块基础设置
# ============================================
# 当前模块所在位置
set(JBIG2_ROOT ${CMAKE_CURRENT_LIST_DIR})

# ============================================
# 2. 平台架构检测
# ============================================
# 设置平台架构、编译类型
set(JBIG2_ARCH_NAME ${CMAKE_SYSTEM_PROCESSOR})
set(JBIG2_PLATFORM_NAME "Windows") # 默认为 Windows

if(WIN32)
    set(JBIG2_PLATFORM_NAME "Win")
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
        set(JBIG2_ARCH_NAME x64)
    else()
        set(JBIG2_ARCH_NAME x86)
    endif()
    
elseif(APPLE)
    set(JBIG2_PLATFORM_NAME "Apple")
    
    if(${TARGET_PLATFORM} STREQUAL "darwin")
        # macOS 平台
        set(JBIG2_ARCH_NAME macosx)
    elseif(${TARGET_PLATFORM} STREQUAL "ios")
        # iOS 平台
        set(JBIG2_ARCH_NAME iphoneos)
    else()
        message(FATAL_ERROR "Unknown Apple platform")
    endif()
    
elseif(ANDROID)
    set(JBIG2_PLATFORM_NAME "Android")
    
    if(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "armv7-a" OR 
        ${CMAKE_ANDROID_ARCH_ABI} STREQUAL "armeabi-v7a")
        set(JBIG2_ARCH_NAME ARM)
    elseif(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "AARCH64_arm64" OR 
            ${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64" OR 
            ${CMAKE_ANDROID_ARCH_ABI} STREQUAL "arm64-v8a")
        set(JBIG2_ARCH_NAME ARM64)
    elseif(${CMAKE_ANDROID_ARCH_ABI} STREQUAL "x86")
        set(JBIG2_ARCH_NAME x86)
    elseif(${CMAKE_ANDROID_ARCH_ABI} STREQUAL "x86_64")
        set(JBIG2_ARCH_NAME x86_64)
    else()
        message(WARNING "Unsupported architecture: CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}, CMAKE_ANDROID_ARCH_ABI=${CMAKE_ANDROID_ARCH_ABI}")
        set(JBIG2_ARCH_NAME ${CMAKE_ANDROID_ARCH_ABI})
    endif()
    
elseif(UNIX AND NOT APPLE)  # Linux 和其他Unix系统
    set(JBIG2_PLATFORM_NAME "Linux")
    
    if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64")
        set(JBIG2_ARCH_NAME x64)
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i[3456]86")
        set(JBIG2_ARCH_NAME x86)
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "armv7|armv7-a|armv7l")
        set(JBIG2_ARCH_NAME ARM)
    elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|arm64")
        set(JBIG2_ARCH_NAME ARM64)
    else()
        set(JBIG2_ARCH_NAME ${CMAKE_SYSTEM_PROCESSOR})
    endif()
    
else()
    message(WARNING "Unsupported platform, using default settings")
endif()

# ============================================
# 3. 包路径设置
# ============================================
# 头文件路径
set(JBIG2_INCLUDE_DIR ${JBIG2_ROOT}/include)
# 库文件路径(根据您的目录结构)
set(JBIG2_LIB_DIR ${JBIG2_ROOT}/lib/${JBIG2_PLATFORM_NAME}/${JBIG2_ARCH_NAME})

# 包名(用于变量命名)
set(JBIG2_PKG_NAME jbig2)

# 打印调试信息(可选)
if(JBIG2_DEBUG)
    message(STATUS "JBIG2_ROOT: ${JBIG2_ROOT}")
    message(STATUS "JBIG2_PLATFORM_NAME: ${JBIG2_PLATFORM_NAME}")
    message(STATUS "JBIG2_ARCH_NAME: ${JBIG2_ARCH_NAME}")
    message(STATUS "JBIG2_INCLUDE_DIR: ${JBIG2_INCLUDE_DIR}")
    message(STATUS "JBIG2_LIB_DIR: ${JBIG2_LIB_DIR}")
endif()

# ============================================
# 4. 查找头文件
# ============================================
# 搜索 jbig2.h 是否存在
find_path(${JBIG2_PKG_NAME}_INCLUDE_DIR
    NAMES jbig2.h
    PATHS ${JBIG2_INCLUDE_DIR}
    NO_CACHE
    NO_CMAKE_PATH
    NO_CMAKE_ENVIRONMENT_PATH
    NO_SYSTEM_ENVIRONMENT_PATH
    NO_CMAKE_PACKAGE_REGISTRY
    NO_CMAKE_BUILDS_PATH
    NO_CMAKE_SYSTEM_PATH
    NO_CMAKE_SYSTEM_PACKAGE_REGISTRY
    NO_CMAKE_FIND_ROOT_PATH)

# ============================================
# 5. 查找库文件
# ============================================
# 库名
set(JBIG2_LIB_NAME jbig2dec)
if(WIN32)
    # Windows下可能的库名变体
    set(JBIG2_LIB_NAME_DEBUG jbig2decd)
    set(JBIG2_LIB_NAME_RELEASE jbig2dec)
else()
    # 其他平台
    set(JBIG2_LIB_NAME_DEBUG jbig2dec)
    set(JBIG2_LIB_NAME_RELEASE jbig2dec)
endif()

# 查找Debug库
find_library(${JBIG2_PKG_NAME}_LIBRARY_DEBUG
    NAMES ${JBIG2_LIB_NAME_DEBUG} ${JBIG2_LIB_NAME}
    PATHS ${JBIG2_LIB_DIR}/Debug
    NO_CACHE
    NO_CMAKE_PATH
    NO_CMAKE_ENVIRONMENT_PATH
    NO_SYSTEM_ENVIRONMENT_PATH
    NO_CMAKE_PACKAGE_REGISTRY
    NO_CMAKE_BUILDS_PATH
    NO_CMAKE_SYSTEM_PATH
    NO_CMAKE_SYSTEM_PACKAGE_REGISTRY
    NO_CMAKE_FIND_ROOT_PATH)

# 查找Release库
find_library(${JBIG2_PKG_NAME}_LIBRARY_RELEASE
    NAMES ${JBIG2_LIB_NAME_RELEASE} ${JBIG2_LIB_NAME}
    PATHS ${JBIG2_LIB_DIR}/Release
    NO_CACHE
    NO_CMAKE_PATH
    NO_CMAKE_ENVIRONMENT_PATH
    NO_SYSTEM_ENVIRONMENT_PATH
    NO_CMAKE_PACKAGE_REGISTRY
    NO_CMAKE_BUILDS_PATH
    NO_CMAKE_SYSTEM_PATH
    NO_CMAKE_SYSTEM_PACKAGE_REGISTRY
    NO_CMAKE_FIND_ROOT_PATH)

# 如果找不到特定目录的库,尝试在lib目录下查找(适用于Linux/macOS)
if(NOT ${JBIG2_PKG_NAME}_LIBRARY_DEBUG AND NOT ${JBIG2_PKG_NAME}_LIBRARY_RELEASE)
    find_library(${JBIG2_PKG_NAME}_LIBRARY
        NAMES ${JBIG2_LIB_NAME}
        PATHS ${JBIG2_ROOT}/lib
        NO_CACHE
        NO_CMAKE_PATH
        NO_CMAKE_ENVIRONMENT_PATH
        NO_SYSTEM_ENVIRONMENT_PATH
        NO_CMAKE_PACKAGE_REGISTRY
        NO_CMAKE_BUILDS_PATH
        NO_CMAKE_SYSTEM_PATH
        NO_CMAKE_SYSTEM_PACKAGE_REGISTRY
        NO_CMAKE_FIND_ROOT_PATH)
endif()

# ============================================
# 6. 处理库配置
# ============================================
# 分配不同配置的库
include(SelectLibraryConfigurations)
select_library_configurations(${JBIG2_PKG_NAME})

# ============================================
# 7. 检测包输出目标
# ============================================
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(${JBIG2_PKG_NAME}
    FOUND_VAR
        ${JBIG2_PKG_NAME}_FOUND
    REQUIRED_VARS
        ${JBIG2_PKG_NAME}_LIBRARY
        ${JBIG2_PKG_NAME}_INCLUDE_DIR)

# ============================================
# 8. 配置包输出内容
# ============================================
if(${JBIG2_PKG_NAME}_FOUND)
    # 配置导入库
    if(NOT TARGET ${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME})
        add_library(${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME} UNKNOWN IMPORTED)
    endif()

    # 配置导入库的链接
    if(${JBIG2_PKG_NAME}_LIBRARY_RELEASE)
        # Release 版本
        set_property(TARGET ${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME} APPEND PROPERTY
            IMPORTED_CONFIGURATIONS RELEASE)
        set_target_properties(${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME} PROPERTIES
            IMPORTED_LOCATION_RELEASE "${${JBIG2_PKG_NAME}_LIBRARY_RELEASE}")
    endif()

    if(${JBIG2_PKG_NAME}_LIBRARY_DEBUG)
        # Debug 版本
        set_property(TARGET ${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME} APPEND PROPERTY
            IMPORTED_CONFIGURATIONS DEBUG)
        set_target_properties(${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME} PROPERTIES
            IMPORTED_LOCATION_DEBUG "${${JBIG2_PKG_NAME}_LIBRARY_DEBUG}")
    endif()

    # 如果没有区分Debug/Release,使用通用库
    if(NOT ${JBIG2_PKG_NAME}_LIBRARY_RELEASE AND NOT ${JBIG2_PKG_NAME}_LIBRARY_DEBUG AND ${JBIG2_PKG_NAME}_LIBRARY)
        set_target_properties(${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME} PROPERTIES
            IMPORTED_LOCATION "${${JBIG2_PKG_NAME}_LIBRARY}")
    endif()

    # 设置导入库的包含目录
    set_target_properties(${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME} PROPERTIES
        INTERFACE_INCLUDE_DIRECTORIES "${${JBIG2_PKG_NAME}_INCLUDE_DIR}")

    # 公开的头文件路径变量(兼容旧代码)
    set(${JBIG2_PKG_NAME}_INCLUDE_PATH ${JBIG2_INCLUDE_DIR})
    set(${JBIG2_PKG_NAME}_INCLUDE_DIRS ${${JBIG2_PKG_NAME}_INCLUDE_DIR})
    set(${JBIG2_PKG_NAME}_LIBRARIES ${JBIG2_PKG_NAME}::${JBIG2_PKG_NAME})
    
    # 标记为高级变量
    mark_as_advanced(
        ${JBIG2_PKG_NAME}_INCLUDE_DIR
        ${JBIG2_PKG_NAME}_LIBRARY
        ${JBIG2_PKG_NAME}_LIBRARY_DEBUG
        ${JBIG2_PKG_NAME}_LIBRARY_RELEASE
    )
    
    # 打印找到的信息
    if(JBIG2_DEBUG)
        message(STATUS "Found jbig2dec:")
        message(STATUS "  Include dir: ${${JBIG2_PKG_NAME}_INCLUDE_DIR}")
        if(${JBIG2_PKG_NAME}_LIBRARY_RELEASE)
            message(STATUS "  Release lib: ${${JBIG2_PKG_NAME}_LIBRARY_RELEASE}")
        endif()
        if(${JBIG2_PKG_NAME}_LIBRARY_DEBUG)
            message(STATUS "  Debug lib: ${${JBIG2_PKG_NAME}_LIBRARY_DEBUG}")
        endif()
        if(${JBIG2_PKG_NAME}_LIBRARY)
            message(STATUS "  Library: ${${JBIG2_PKG_NAME}_LIBRARY}")
        endif()
    endif()
else()
    # 如果没找到,给出提示
    if(JBIG2_FIND_REQUIRED)
        message(FATAL_ERROR "Could NOT find jbig2dec (missing: ${JBIG2_PKG_NAME}_INCLUDE_DIR ${JBIG2_PKG_NAME}_LIBRARY)")
    else()
        message(STATUS "Could NOT find jbig2dec")
    endif()
endif()

# ============================================
# 9. 清理内部变量
# ============================================
# 清理不需要暴露的内部变量
unset(JBIG2_ROOT)
unset(JBIG2_INCLUDE_DIR)
unset(JBIG2_LIB_DIR)
unset(JBIG2_LIB_NAME)
unset(JBIG2_LIB_NAME_DEBUG)
unset(JBIG2_LIB_NAME_RELEASE)

使用说明

1. 文件放置位置

Findjbig2.cmake文件放在您的jbig2dec目录下(与includelib目录同级)。

2. 在CMakeLists.txt中使用

cmake 复制代码
# 方法1:直接使用find_package(假设Findjbig2.cmake在CMAKE_MODULE_PATH中)
find_package(jbig2 REQUIRED)

# 方法2:如果Findjbig2.cmake在第三方库目录中
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/jbig2dec")
find_package(jbig2 REQUIRED)

# 使用库(现代方式,推荐)
target_link_libraries(your_target PRIVATE jbig2::jbig2)

# 或兼容方式
target_include_directories(your_target PRIVATE ${JBIG2_INCLUDE_DIRS})
target_link_libraries(your_target ${JBIG2_LIBRARIES})

3. 调试模式

如果需要查看查找过程,可以启用调试模式:

cmake 复制代码
set(JBIG2_DEBUG ON)
find_package(jbig2 REQUIRED)

4. 支持的平台和架构

  • Windows: x86, x64
  • Linux: x86, x64, ARM, ARM64
  • macOS: macosx
  • Android: ARM, ARM64, x86, x86_64
  • iOS: iphoneos

5. 库文件命名约定

  • Windows Debug: jbig2decd.lib (如果存在) 或 jbig2dec.lib
  • Windows Release: jbig2dec.lib
  • 其他平台: jbig2dec

6. 目录结构匹配

您的目录结构:

复制代码
jbig2dec/
├── Findjbig2.cmake
├── include/
│   └── jbig2.h (假设)
└── lib/
    └── Win/
        ├── x64/
        │   ├── Debug/
        │   │   └── jbig2dec.lib
        │   └── Release/
        │       └── jbig2dec.lib
        └── x86/
            ├── Debug/
            │   └── jbig2dec.lib
            └── Release/
                └── jbig2dec.lib

这个Find模块会根据当前平台和架构自动查找正确的库文件。

7. 注意事项

  1. 确保include目录下有jbig2.h头文件
  2. 确保库文件按照预期的命名和目录结构存放
  3. 如果需要支持更多平台,可以扩展平台检测部分
  4. 如果要查找动态库(.dll/.so/.dylib),可能需要调整库名查找逻辑
相关推荐
汉克老师2 小时前
2023年海淀区中小学信息学竞赛复赛(小学组试题第七题 赛车游戏(car))
c++·游戏·双指针·海淀区中小学信息竞赛
Azxcc02 小时前
c++ core guidelines解析--让接口易于使用
开发语言·c++
helloworddm2 小时前
NSIS编写C/C++扩展
c语言·开发语言·c++
ULTRA??2 小时前
QT向量类实现GJK碰撞检测算法3d版本
c++·qt·算法
煤球王子2 小时前
学而时习之:C++ 中的文件处理
c++
天赐学c语言2 小时前
12.10 - 合并两个有序链表 && 对字节对齐的理解
数据结构·c++·leetcode·链表
仰泳的熊猫2 小时前
1092 To Buy or Not to Buy
数据结构·c++·算法·pat考试
CSDN_RTKLIB3 小时前
解除vcpkg对VS的全局配置注入
c++
君义_noip3 小时前
信息学奥赛一本通 4017:【GESP2309三级】小杨的储蓄 | 洛谷 B3867 [GESP202309 三级] 小杨的储蓄
c++·算法·gesp·信息学奥赛