cmake:善用find_package()提高效率暨查找JNI支持
cmake提供了很多实用的cmake-modules,通过find_package()命令调用这些modules,用于写CMakeLists.txt脚本时方便的查找依赖的库或其他编译相关的信息,善用这些modules,可以提高写脚本的效率和脚本通用性。
说起来真的有点太抽象,举个我最近遇到的简单例子吧。
我们写java的JNI接口代码时,肯定是需要jni.h文件的,那么在写cmake脚本中,就需要找到你当前电脑的jni.h的安装位置加入include搜索路径(对了还需要 jni_md.h的位置)。
下面是我原先用于定位jni.h以及jni_md.h的位置,并将其加入到include搜索路径中的cmake脚本。
# 通过 JAVA_HOME环境变量定位 jni.h和jni_md.h if(NOT DEFINED ENV{JAVA_HOME}) # 没有找到JAVA_HOME环境变量,输出错误信息退出 message(FATAL_ERROR "not defined environment variable:JAVA_HOME") endif() set(JNI_INCLUDE "$ENV{JAVA_HOME}/include") # jni.h的位置加入搜索路径 include_directories(${JNI_INCLUDE}) # 判断操作系统,添加jni_md.h搜索路径 if(WIN32) #win32系统下`jni_md.h`位于`<jni_h_dir>/win32`下 include_directories("${JNI_INCLUDE}/win32") elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") #linux系统下`jni_md.h`位于`<jni_h_dir>/linux`下 include_directories("${JNI_INCLUDE}/linux") else() # 不支持的操作系统报错退出 message(FATAL_ERROR "other unsupported platform: ${CMAKE_SYSTEM_NAME}") endif(CMAKE_SYSTEM_NAME MATCHES "Windows")
写了一堆代码,只满足了windows和linux下的jni支持查找。
其实cmake本身就提供了一个叫 FindJNI的modules,调用它就可以获取关于JNI配置的一切变量。
FindJNI Find JNI java libraries. This module finds if Java is installed and determines where the include files and libraries are. It also determines what the name of the library is. The caller may set variable JAVA_HOME to specify a Java installation prefix explicitly. This module sets the following result variables: JNI_INCLUDE_DIRS = the include dirs to use JNI_LIBRARIES = the libraries to use JNI_FOUND = TRUE if JNI headers and libraries were found. JAVA_AWT_LIBRARY = the path to the jawt library JAVA_JVM_LIBRARY = the path to the jvm library JAVA_INCLUDE_PATH = the include path to jni.h JAVA_INCLUDE_PATH2 = the include path to jni_md.h JAVA_AWT_INCLUDE_PATH = the include path to jawt.h
使用FindJNI,前面的cmake脚本就可以改成下面这样:
# 加入REQUIRED 参数,如果找不到JNI,就报错退出
find_package(JNI REQUIRED)
# 加入jni支持
include_directories(${JAVA_INCLUDE_PATH})
include_directories(${JAVA_INCLUDE_PATH2})
只有三行。。。而且对所有平台适用!
尼玛,知识改变命运呐,早知道这么个神器,我费那劲写辣么多代码干嘛呀,不查手册活该受累呀。
在cmake手册关于《cmake-modules》(点击打开链接)的页面中你还能找到更多常用的第三方库的modules
关于find_package()命令更详细的用法参见:https://cmake.org/cmake/help/v3.1/command/find_package.html#command:find_package
和
https://cmake.org/cmake/help/v3.1/manual/cmake-packages.7.html