# CMake project for JNI wrapper cmake_minimum_required(VERSION 3.20) project(aac_jni LANGUAGES C) add_library(aac_jni SHARED aac_jni.c) # 自动处理 JAVA_HOME(跨平台) # 1) 命令行 -DJAVA_HOME 传入优先 # 2) 环境变量 JAVA_HOME 其次 # 3) find_package(Java) 自动探测兜底 set(JAVA_HOME "" CACHE PATH "Path to JDK home") if(NOT JAVA_HOME AND DEFINED ENV{JAVA_HOME}) set(JAVA_HOME "$ENV{JAVA_HOME}") endif() if(NOT JAVA_HOME) find_package(Java COMPONENTS Development) # 可兼容多版本JDK;如需限定最低版本,可启用如下检查: # if(DEFINED Java_VERSION_STRING AND Java_VERSION_STRING VERSION_LESS 17) # message(FATAL_ERROR "需要 JDK 17 及以上,当前: ${Java_VERSION_STRING}") # endif() if(Java_FOUND AND Java_JAVAC_EXECUTABLE) get_filename_component(_javac_dir "${Java_JAVAC_EXECUTABLE}" DIRECTORY) get_filename_component(JAVA_HOME "${_javac_dir}/.." ABSOLUTE) set(JAVA_HOME "${JAVA_HOME}" CACHE PATH "Path to JDK home" FORCE) endif() endif() if(NOT JAVA_HOME) message(FATAL_ERROR "JAVA_HOME 未设置。请通过 -DJAVA_HOME=... 或设置环境变量 JAVA_HOME,或确保 CMake 能自动探测到 JDK。") endif() message(STATUS "Using JAVA_HOME: ${JAVA_HOME}") # 平台相关配置 if(WIN32) # Windows 平台配置 set(PLATFORM_DIR "win32") set(NATIVE_PLATFORM_DIR "windows/x64") set(FDK_AAC_LIB "${CMAKE_SOURCE_DIR}/../../native/windows/x64/Release/fdk-aac.lib") # 为了避免绝对路径引用,将 JDK 头文件复制到构建目录下的相对路径 set(JDK_LOCAL_INCLUDE_DIR "${CMAKE_BINARY_DIR}/jdk/include") set(JDK_LOCAL_PLATFORM_INCLUDE_DIR "${JDK_LOCAL_INCLUDE_DIR}/${PLATFORM_DIR}") file(MAKE_DIRECTORY "${JDK_LOCAL_INCLUDE_DIR}") file(MAKE_DIRECTORY "${JDK_LOCAL_PLATFORM_INCLUDE_DIR}") file(COPY "${JAVA_HOME}/include/" DESTINATION "${JDK_LOCAL_INCLUDE_DIR}") file(COPY "${JAVA_HOME}/include/${PLATFORM_DIR}/" DESTINATION "${JDK_LOCAL_PLATFORM_INCLUDE_DIR}") # Windows 包含目录 target_include_directories(aac_jni PRIVATE "${JDK_LOCAL_INCLUDE_DIR}" "${JDK_LOCAL_PLATFORM_INCLUDE_DIR}" "${CMAKE_SOURCE_DIR}/../../native/include/fdk-aac" ) # Windows 链接库 target_link_libraries(aac_jni PRIVATE "${FDK_AAC_LIB}" ) # Windows 输出目录 set_target_properties(aac_jni PROPERTIES OUTPUT_NAME "aac_jni" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../../native/windows/x64/" ) # 让 MSVC 以 UTF-8 编译,避免 C4819 警告 target_compile_options(aac_jni PRIVATE "$<$:/utf-8>") elseif(UNIX AND NOT APPLE) # Linux 平台配置 set(PLATFORM_DIR "linux") set(NATIVE_PLATFORM_DIR "linux") # 确保 JDK 头文件路径正确 set(JDK_INCLUDE_DIR "${JAVA_HOME}/include") set(JDK_PLATFORM_INCLUDE_DIR "${JDK_INCLUDE_DIR}/${PLATFORM_DIR}") # 验证 JDK 头文件路径是否存在 if(NOT EXISTS "${JDK_INCLUDE_DIR}/jni.h") message(WARNING "JNI 头文件 jni.h 未找到在 ${JDK_INCLUDE_DIR}") # 尝试常见的 Linux JDK 路径 set(ALTERNATIVE_JDK_PATHS "/usr/lib/jvm/default/include" "/usr/lib/jvm/java-11-openjdk-amd64/include" "/usr/lib/jvm/java-17-openjdk-amd64/include" ) foreach(ALT_PATH IN LISTS ALTERNATIVE_JDK_PATHS) if(EXISTS "${ALT_PATH}/jni.h") set(JDK_INCLUDE_DIR "${ALT_PATH}") set(JDK_PLATFORM_INCLUDE_DIR "${JDK_INCLUDE_DIR}/${PLATFORM_DIR}") message(STATUS "找到替代 JDK 头文件路径: ${JDK_INCLUDE_DIR}") break() endif() endforeach() endif() # Linux 包含目录 target_include_directories(aac_jni PRIVATE "${JDK_INCLUDE_DIR}" "${JDK_PLATFORM_INCLUDE_DIR}" "${CMAKE_SOURCE_DIR}/../../native/include/fdk-aac" ) # Linux 链接库 - 尝试多种可能的库文件路径 set(FDK_AAC_LIB_PATHS "${CMAKE_SOURCE_DIR}/../../native/linux/libfdk-aac.so" "/usr/lib/x86_64-linux-gnu/libfdk-aac.so" "/usr/lib/libfdk-aac.so" ) # 查找存在的 fdk-aac 库 foreach(LIB_PATH IN LISTS FDK_AAC_LIB_PATHS) if(EXISTS "${LIB_PATH}") set(FDK_AAC_LIB "${LIB_PATH}") message(STATUS "找到 fdk-aac 库: ${FDK_AAC_LIB}") break() endif() endforeach() # 如果找不到库文件,尝试使用系统库 if(NOT DEFINED FDK_AAC_LIB) message(STATUS "未找到预编译的 fdk-aac 库,尝试使用系统库") find_library(FDK_AAC_LIB NAMES fdk-aac) if(FDK_AAC_LIB) message(STATUS "找到系统 fdk-aac 库: ${FDK_AAC_LIB}") else() message(FATAL_ERROR "未找到 fdk-aac 库,请确保已安装或放置在正确位置") endif() endif() # 链接库 target_link_libraries(aac_jni PRIVATE "${FDK_AAC_LIB}" ) # Linux 输出目录 set_target_properties(aac_jni PROPERTIES OUTPUT_NAME "aac_jni" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../../native/linux/" ) # Linux 编译选项 target_compile_options(aac_jni PRIVATE -fPIC -Wall -Wextra -Wpedantic -std=c99 # 使用 C99 标准,确保 size_t 等类型正确定义 ) else() message(FATAL_ERROR "当前平台不支持。支持的平台:Windows 和 Linux。") endif()