简述企业网站建设的目的有哪些/长沙网站关键词排名推广公司
在使用 android studio 进行 集成的时候终于 将我之前对于 find_X 不懂的 搞懂了一点
说在前面
androidstudio 默认下载的cmake 为 cmake version 3.10.2 目前我的android studio 的版本是: Android Studio 4.0
可以自己下载最新版本的 cmake 然后进行配置 比方我在 local.properties cmake.dir=D\:\\softwarefiles\\chrome\\cmake-3.10.2-win64-x64 增加了 这个,还需要在 build.gradle 中增加android {
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
复制代码当然,还是以自带的为准。因为 会有其他问题的.因为android为我们配置好了cmake 你一定要换个最新的 你需要自己实现一套 android.toolchain.cmake 否则 凉凉
因为每次编译都会 重复执行很多遍 ,所以在 build.gradle 中增加如下代码android {
defaultConfig {
ndk{
abiFilters "arm64-v8a"
}
}
}
复制代码这样只会编译指定平台的代码
初步印象
首先Android 默认 会有下面这些 选项:
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
endif()
if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
endif()
复制代码
上述的选项 产生的影响如下
# 影响 find_package()
message(WARNING "CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ${CMAKE_FIND_ROOT_PATH_MODE_PACKAGE}")
# 影响 find_program()
message(WARNING "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ${CMAKE_FIND_ROOT_PATH_MODE_PROGRAM}")
# 影响 find_library()
message(WARNING "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ${CMAKE_FIND_ROOT_PATH_MODE_LIBRARY}")
# 影响 find_file() 和 find_path()
message(WARNING "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ${CMAKE_FIND_ROOT_PATH_MODE_INCLUDE}")
复制代码
具体的值为:
ONLY 有关 root只在 CMAKE_FIND_ROOT_PATH 这里面进行查找
NEVER 有关 root只在 CMAKE_SYSROOT 这里面查找
BOTH 有关 root 会在 CMAKE_SYSROOT CMAKE_FIND_ROOT_PATH 一起查找
进入正文
再看 Android里面的配置
tree /f
├─cpp
│ │ CMakeLists.txt
│ │ test.c
│ └─curl
│ │ CMakeLists.txt
│ │ Findcurl.cmake
│ │
│ ├─include
│ │ curl.h
│ └─lib
│ libcurl.a
├─java
│ └─com
│ └─example
│ └─myapplication
│ MainActivity.kt
复制代码
大致的结构如上所示
目的我想 在AndroidStudio 中 让 我的 外层CMakeLists.txt 能够查找到 curl的库
,通过 find_package 的方式进行查找
当前最新版本的 cmake 是 3.18 不过 ,3.10.2 也不影响我们的使用是吧。哈哈。
先写个 Findcurl.cmake 名称的格式是固定的,这个不能改,当然有其他两种备选的格式,按住不表。
按 官方文档说,这里且直接上正确答案吧。【高考不易,加油】
set(libname curl)
find_path(${libname}_INCLUDE_DIR
curl.h
HINTS ${CMAKE_SOURCE_DIR}/curl/include
CMAKE_FIND_ROOT_PATH_BOTH
)
FIND_LIBRARY(${libname}_LIBRARY NAMES curl PATHS curl/lib)
IF(${libname}_INCLUDE_DIR AND ${libname}_LIBRARY)
SET(${libname}_FOUND TRUE)
ENDIF()
IF(${libname}_FOUND)
if(NOT ${libname}_FIND_QUIETLY)
MESSAGE(WARNING "FOUND LIBRARY:${${libname}_LIBRARY}")
ENDIF()
ELSE(${libname}_FOUND)
if(${libname}_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "cant found")
endif()
endif(${libname}_FOUND)
复制代码
这里说下 出现问题的原因 一直找不到 头文件 curl.h 比方说。
打开官方文档,【其实这才是最正确的解题思路啊】。
上面说了 find_path 的查找规则,
所以如果你是用 find_path (BOOST_STATE_HPP NAMES curl.h PATHS module/curl/include NO_DEFAULT_PATH) 抱歉 你是找不到的。
文档说:查找的 优先级 有六个。
简单说就是
第一级可以通过 NO_CMAKE_PATH 进行跳过, 如果设置了 CMAKE_LIBRARY_ARCHITECTURE 则 会添加后缀的
然后 去 CMAKE_PREFIX_PATH CMAKE_INCLUDE_PATH CMAKE_FRAMEWORK_PATH 这些地方进行查找
第二级可以通过 NO_CMAKE_ENVIRONMENT_PATH 进行跳过
这里如果设置了 HINTS
第四级可以通过 NO_SYSTEM_ENVIRONMENT_PATH 进行跳过
第五级可以通过 NO_CMAKE_SYSTEM_PATH 进行跳过,然后去 CMAKE_SYSTEM_PREFIX_PATH CMAKE_SYSTEM_INCLUDE_PATH CMAKE_SYSTEM_FRAMEWORK_PATH 进行查找
这里如果设置了 PATHS
官网给出的api如下
find_path ( name1 [path1 path2 ...])
find_path (
name | NAMES name1 [name2 ...]
[HINTS path1 [path2 ... ENV var]]
[PATHS path1 [path2 ... ENV var]]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
[DOC "cache documentation string"]
[NO_DEFAULT_PATH]
[NO_CMAKE_PATH]
[NO_CMAKE_ENVIRONMENT_PATH]
[NO_SYSTEM_ENVIRONMENT_PATH]
[NO_CMAKE_SYSTEM_PATH]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
复制代码
这里打印下 可能影响的参数值
message(WARNING "CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH}")
message(WARNING "CMAKE_ANDROID_ARCH_ABI ${CMAKE_ANDROID_ARCH_ABI}")
message(WARNING "CMAKE_LIBRARY_ARCHITECTURE ${CMAKE_LIBRARY_ARCHITECTURE}")
message(WARNING "CMAKE_SYSTEM_INCLUDE_PATH ${CMAKE_SYSTEM_INCLUDE_PATH}")
message(WARNING "CMAKE_SYSTEM_FRAMEWORK_PATH ${CMAKE_SYSTEM_FRAMEWORK_PATH}")
message(WARNING "CMAKE_FIND_ROOT_PATH ${CMAKE_FIND_ROOT_PATH}")
message(WARNING "CMAKE_FIND_APPBUNDLE ${CMAKE_FIND_APPBUNDLE}")
message(WARNING "CMAKE_FIND_FRAMEWORK ${CMAKE_FIND_FRAMEWORK}")
message(WARNING "CMAKE_STAGING_PREFIX ${CMAKE_STAGING_PREFIX}")
message(WARNING "CMAKE_SYSROOT ${CMAKE_SYSROOT}")
message(WARNING "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ${CMAKE_FIND_ROOT_PATH_MODE_INCLUDE}")
复制代码
输出
CMAKE_PREFIX_PATH
CMAKE_ANDROID_ARCH_ABI armeabi-v7a
CMAKE_LIBRARY_ARCHITECTURE arm-linux-androideabi
CMAKE_SYSTEM_INCLUDE_PATH /usr/include/X11
CMAKE_SYSTEM_FRAMEWORK_PATH
CMAKE_FIND_ROOT_PATH
D:\workspace\AndroidStudio\AndroidStudioProjects\app\.cxx\cmake\debug\prefab\armeabi-v7a\prefab;D:/env/android-ndk-r20b
CMAKE_FIND_APPBUNDLE
CMAKE_FIND_FRAMEWORK
CMAKE_STAGING_PREFIX
CMAKE_SYSROOT
D:/env/android-ndk-r20b/toolchains/llvm/prebuilt/windows-x86_64/sysroot
CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY
复制代码
这里写下不可行的情况,以及可行的情况
易错点一: CMAKE_MODULE_PATH
CMAKE_MODULE_PATH 且认为他只会影响 find_package 的查找路径。所以对他的设置 对于find_path 是没有意义的
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/module/curl/include ${CMAKE_MODULE_PATH}")
复制代码
易错点二: CMAKE_PREFIX_PATH
通过上面可知,find_path 的确 受 CMAKE_PREFIX_PATH 的影响,所以,应该设置是有效的,实则不然,官网说:如果设置了 CMAKE_LIBRARY_ARCHITECTURE 则 查找的路径会变更为 /include/ 在android studio 中 是会被设置的!!
使用android的ndk 是会默认帮你配置好的,具体可查看 ndk 的安装目录底下 android-ndk-r20b\build\cmake\android.toolchain.cmake 就可以看到一共设置了哪些变量。
易错点三: 给了全路径还是查找不到
find_path (BOOST_STATE_HPP NAMES curl.h PATHS D:/test)
在这种情况下,就需要 添加 CMAKE_FIND_ROOT_PATH_BOTH或 NO_CMAKE_FIND_ROOT_PATH,或者 set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "BOTH") 这个指定 BOTH 即可
这样 FindXX.cmake 就可以正确找到了。在 CMakeLists.txt中就可以去使用了
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/curl)
find_package(curl REQUIRED)
message(WARNING "find it ${curl_LIBRARY}")
add_library(native-lib
SHARED
test.c
)
target_include_directories(native-lib PRIVATE ${curl_INCLUDE_DIR})
target_link_libraries(native-lib
${log-lib}
${curl_LIBRARY}
-lz
)
复制代码
这时候你的代码里面就可以引用
#include "curl.h"
#include
#include
int main(){
printf("hello");
CURL * curl = curl_easy_init();
}
复制代码
顺便说一下: 如果你对导入的头文件有要求 比方说 不要 curl.h 想要 include/curl.h 那 就需要在 改成如下的形式了
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE "NEVER")
find_path(${libname}_INCLUDE_DIR
include/curl.h
HINTS ${CMAKE_SOURCE_DIR}/curl
#[[CMAKE_FIND_ROOT_PATH_BOTH]]
NO_DEFAULT_PATH
)
复制代码
如上 你就可以在自己的项目中导入
#include "include/curl.h"
#include
#include
int main(){
printf("hello");
CURL * curl = curl_easy_init();
}
复制代码
以上。是使用 Android Studio IDE 进行 的。cmake 编译。当然你也可以自己 通过设置env的方式进行 配置
export NDK_HOME=~/workspace/env/ndk_r20/android-ndk-r20
export NDK_BUILD=${NDK_HOME}/ndk-build
export TOOLROOT=${NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin
export TOOLPREFIX=arm-linux-androideabi
export CC=${TOOLROOT}/armv7a-linux-androideabi16-clang
export CXX=${TOOLROOT}/armv7a-linux-androideabi16-clang++
export CPP="${CC} -E"
export AR=${TOOLROOT}/arm-linux-androideabi-ar
export LD=${TOOLROOT}/arm-linux-androideabi-ld
export NM=${TOOLROOT}/arm-linux-androideabi-nm
export RANLIB=${TOOLROOT}/arm-linux-androideabi-ranlib
export STRIP=${TOOLROOT}/arm-linux-androideabi-strip
export READELF=${TOOLROOT}/arm-linux-androideabi-readelf
export ADDR2LINE=${TOOLROOT}/arm-linux-androideabi-addr2line
export OBJDUMP=${TOOLROOT}/arm-linux-androideabi-objdump
export LDFLAGS="-static-libstdc++"
export PRJ_NAME=android
export ARCH=arm
复制代码
然后剩下的事情就是和 其他平台开发的事情一摸一样了。
source ./env
$CC test.c
复制代码