CMakeLists.txt 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. # CMake project for JNI wrapper
  2. cmake_minimum_required(VERSION 3.20)
  3. project(aac_jni LANGUAGES C)
  4. add_library(aac_jni SHARED aac_jni.c)
  5. # 自动处理 JAVA_HOME(跨平台)
  6. # 1) 命令行 -DJAVA_HOME 传入优先
  7. # 2) 环境变量 JAVA_HOME 其次
  8. # 3) find_package(Java) 自动探测兜底
  9. set(JAVA_HOME "" CACHE PATH "Path to JDK home")
  10. if(NOT JAVA_HOME AND DEFINED ENV{JAVA_HOME})
  11. set(JAVA_HOME "$ENV{JAVA_HOME}")
  12. endif()
  13. if(NOT JAVA_HOME)
  14. find_package(Java COMPONENTS Development)
  15. # 可兼容多版本JDK;如需限定最低版本,可启用如下检查:
  16. # if(DEFINED Java_VERSION_STRING AND Java_VERSION_STRING VERSION_LESS 17)
  17. # message(FATAL_ERROR "需要 JDK 17 及以上,当前: ${Java_VERSION_STRING}")
  18. # endif()
  19. if(Java_FOUND AND Java_JAVAC_EXECUTABLE)
  20. get_filename_component(_javac_dir "${Java_JAVAC_EXECUTABLE}" DIRECTORY)
  21. get_filename_component(JAVA_HOME "${_javac_dir}/.." ABSOLUTE)
  22. set(JAVA_HOME "${JAVA_HOME}" CACHE PATH "Path to JDK home" FORCE)
  23. endif()
  24. endif()
  25. if(NOT JAVA_HOME)
  26. message(FATAL_ERROR "JAVA_HOME 未设置。请通过 -DJAVA_HOME=... 或设置环境变量 JAVA_HOME,或确保 CMake 能自动探测到 JDK。")
  27. endif()
  28. message(STATUS "Using JAVA_HOME: ${JAVA_HOME}")
  29. # 平台相关配置
  30. if(WIN32)
  31. # Windows 平台配置
  32. set(PLATFORM_DIR "win32")
  33. set(NATIVE_PLATFORM_DIR "windows/x64")
  34. set(FDK_AAC_LIB "${CMAKE_SOURCE_DIR}/../../native/windows/x64/Release/fdk-aac.lib")
  35. # 为了避免绝对路径引用,将 JDK 头文件复制到构建目录下的相对路径
  36. set(JDK_LOCAL_INCLUDE_DIR "${CMAKE_BINARY_DIR}/jdk/include")
  37. set(JDK_LOCAL_PLATFORM_INCLUDE_DIR "${JDK_LOCAL_INCLUDE_DIR}/${PLATFORM_DIR}")
  38. file(MAKE_DIRECTORY "${JDK_LOCAL_INCLUDE_DIR}")
  39. file(MAKE_DIRECTORY "${JDK_LOCAL_PLATFORM_INCLUDE_DIR}")
  40. file(COPY "${JAVA_HOME}/include/" DESTINATION "${JDK_LOCAL_INCLUDE_DIR}")
  41. file(COPY "${JAVA_HOME}/include/${PLATFORM_DIR}/" DESTINATION "${JDK_LOCAL_PLATFORM_INCLUDE_DIR}")
  42. # Windows 包含目录
  43. target_include_directories(aac_jni PRIVATE
  44. "${JDK_LOCAL_INCLUDE_DIR}"
  45. "${JDK_LOCAL_PLATFORM_INCLUDE_DIR}"
  46. "${CMAKE_SOURCE_DIR}/../../native/include/fdk-aac"
  47. )
  48. # Windows 链接库
  49. target_link_libraries(aac_jni PRIVATE
  50. "${FDK_AAC_LIB}"
  51. )
  52. # Windows 输出目录
  53. set_target_properties(aac_jni PROPERTIES
  54. OUTPUT_NAME "aac_jni"
  55. RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../../native/windows/x64/"
  56. )
  57. # 让 MSVC 以 UTF-8 编译,避免 C4819 警告
  58. target_compile_options(aac_jni PRIVATE "$<$<C_COMPILER_ID:MSVC>:/utf-8>")
  59. elseif(UNIX AND NOT APPLE)
  60. # Linux 平台配置
  61. set(PLATFORM_DIR "linux")
  62. set(NATIVE_PLATFORM_DIR "linux")
  63. # 确保 JDK 头文件路径正确
  64. set(JDK_INCLUDE_DIR "${JAVA_HOME}/include")
  65. set(JDK_PLATFORM_INCLUDE_DIR "${JDK_INCLUDE_DIR}/${PLATFORM_DIR}")
  66. # 验证 JDK 头文件路径是否存在
  67. if(NOT EXISTS "${JDK_INCLUDE_DIR}/jni.h")
  68. message(WARNING "JNI 头文件 jni.h 未找到在 ${JDK_INCLUDE_DIR}")
  69. # 尝试常见的 Linux JDK 路径
  70. set(ALTERNATIVE_JDK_PATHS
  71. "/usr/lib/jvm/default/include"
  72. "/usr/lib/jvm/java-11-openjdk-amd64/include"
  73. "/usr/lib/jvm/java-17-openjdk-amd64/include"
  74. )
  75. foreach(ALT_PATH IN LISTS ALTERNATIVE_JDK_PATHS)
  76. if(EXISTS "${ALT_PATH}/jni.h")
  77. set(JDK_INCLUDE_DIR "${ALT_PATH}")
  78. set(JDK_PLATFORM_INCLUDE_DIR "${JDK_INCLUDE_DIR}/${PLATFORM_DIR}")
  79. message(STATUS "找到替代 JDK 头文件路径: ${JDK_INCLUDE_DIR}")
  80. break()
  81. endif()
  82. endforeach()
  83. endif()
  84. # Linux 包含目录
  85. target_include_directories(aac_jni PRIVATE
  86. "${JDK_INCLUDE_DIR}"
  87. "${JDK_PLATFORM_INCLUDE_DIR}"
  88. "${CMAKE_SOURCE_DIR}/../../native/include/fdk-aac"
  89. )
  90. # Linux 链接库 - 尝试多种可能的库文件路径
  91. set(FDK_AAC_LIB_PATHS
  92. "${CMAKE_SOURCE_DIR}/../../native/linux/libfdk-aac.so"
  93. "/usr/lib/x86_64-linux-gnu/libfdk-aac.so"
  94. "/usr/lib/libfdk-aac.so"
  95. )
  96. # 查找存在的 fdk-aac 库
  97. foreach(LIB_PATH IN LISTS FDK_AAC_LIB_PATHS)
  98. if(EXISTS "${LIB_PATH}")
  99. set(FDK_AAC_LIB "${LIB_PATH}")
  100. message(STATUS "找到 fdk-aac 库: ${FDK_AAC_LIB}")
  101. break()
  102. endif()
  103. endforeach()
  104. # 如果找不到库文件,尝试使用系统库
  105. if(NOT DEFINED FDK_AAC_LIB)
  106. message(STATUS "未找到预编译的 fdk-aac 库,尝试使用系统库")
  107. find_library(FDK_AAC_LIB NAMES fdk-aac)
  108. if(FDK_AAC_LIB)
  109. message(STATUS "找到系统 fdk-aac 库: ${FDK_AAC_LIB}")
  110. else()
  111. message(FATAL_ERROR "未找到 fdk-aac 库,请确保已安装或放置在正确位置")
  112. endif()
  113. endif()
  114. # 链接库
  115. target_link_libraries(aac_jni PRIVATE
  116. "${FDK_AAC_LIB}"
  117. )
  118. # Linux 输出目录
  119. set_target_properties(aac_jni PROPERTIES
  120. OUTPUT_NAME "aac_jni"
  121. LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/../../native/linux/"
  122. )
  123. # Linux 编译选项
  124. target_compile_options(aac_jni PRIVATE
  125. -fPIC
  126. -Wall
  127. -Wextra
  128. -Wpedantic
  129. -std=c99 # 使用 C99 标准,确保 size_t 等类型正确定义
  130. )
  131. else()
  132. message(FATAL_ERROR "当前平台不支持。支持的平台:Windows 和 Linux。")
  133. endif()