欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

windows下使用AndroidStudio编译so

程序员文章站 2024-01-24 15:32:46
...

前面实践过在Linux下使用Ndk将C++代码编译成so

https://blog.csdn.net/dhd040805/article/details/105855805

DK 开发或者老的项目都是基于 Android.mk、Application.mk 来构建项目的,但从 AS 2.2 之后便开始采用 CMake 的方式来构建 C/C++ 项目,采用 CMake 相比与之前的 Android.mk、Application.mk 方便简单了许多。

#1. 指定 cmake 的最小版本
cmake_minimum_required(VERSION 3.4.1)

#2. 设置项目名称
project(demo)

#3. 设置编译类型
add_executable(demo test.cpp) # 生成可执行文件
add_library(common STATIC test.cpp) # 生成静态库
add_library(common SHARED test.cpp) # 生成动态库或共享库

#4. 明确指定包含哪些源文件
add_library(demo test.cpp test1.cpp test2.cpp)

#5. 自定义搜索规则并加载文件
file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST}) //加载当前目录下所有的 cpp 文件
## 或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
## 或者
aux_source_directory(. SRC_LIST)//搜索当前目录下的所有.cpp文件
aux_source_directory(protocol SRC_PROTOCOL_LIST) 
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

#6. 查找指定库文件
find_library(
              log-lib //为 log 定义一个变量名称
              log ) //ndk 下的 log 库

#7. 设置包含的目录
include_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}
    ${CMAKE_CURRENT_BINARY_DIR}
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)

#8. 设置链接库搜索目录
link_directories(
    ${CMAKE_CURRENT_SOURCE_DIR}/libs
)

#9. 设置 target 需要链接的库
target_link_libraries( # 目标库
                       demo
 
                       # 目标库需要链接的库
                       # log-lib 是上面 find_library 指定的变量名
                       ${log-lib} )
                       
#10. 指定链接动态库或者静态库
target_link_libraries(demo libtest.a) # 链接libtest.a
target_link_libraries(demo libtest.so) # 链接libtest.so

#11. 根据全路径链接动态静态库
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libtest.a)
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/libs/libtest.so)

#12. 指定链接多个库
target_link_libraries(demo
    ${CMAKE_CURRENT_SOURCE_DIR}/libs/libtest.a
    test.a
    boost_thread
    pthread)
    

常用变量

预定义变量 说明
PROJECT_SOURCE_DIR 工程的根目录
PROJECT_BINARY_DIR 运行 cmake 命令的目录,通常是 ${PROJECT_SOURCE_DIR}/build
PROJECT_NAME 返回通过 project 命令定义的项目名称
CMAKE_CURRENT_SOURCE_DIR 当前处理的 CMakeLists.txt 所在的路径
CMAKE_CURRENT_BINARY_DIR target 编译目录
CMAKE_CURRENT_LIST_DIR CMakeLists.txt 的完整路径
CMAKE_CURRENT_LIST_LINE 当前所在的行
CMAKE_MODULE_PATH 定义自己的 cmake 模块所在的路径,SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块
EXECUTABLE_OUTPUT_PATH 重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH 重新定义目标链接库文件的存放位置

构建 C/C++ Android 项目

  1. 以静态库构建项目

    • 定义 native 接口

      public class MainActivity extends AppCompatActivity {
      
          static {
              System.loadLibrary("native-lib");
          }
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              testCmake();
          }
      
          /**
           * 测试 cmake 构建程序
           */
          public native static void testCmake();
      }
      复制代码
    • 编写 cpp

      // extern int main();  这样写有坑,因为 main 方法是属于 c 的,而当前是 CPP
      
      extern "C" { //必须这样定义
          int main();
      }
      
      extern "C" JNIEXPORT void JNICALL
      Java_com_dhd_cmake_1application_MainActivity_testCmake(
              JNIEnv *env,
              jobject /* this */) {
          std::string hello = "Hello from C++";
      
          __android_log_print(ANDROID_LOG_DEBUG, "DevYK", "main--->:%d", main());
      
      }
      复制代码
    • 编写 CmakeLists.txt 文件

      cmake_minimum_required(VERSION 3.4.1)
      
      # 打印日志
      message("当前CMake的路径是:${CMAKE_SOURCE_DIR}")
      message("当前 CMAKE_ANDROID_ARCH_ABI 的路径是:${CMAKE_ANDROID_ARCH_ABI}")
      
      # 批量引入源文件
      file(GLOB allCpp *.cpp)
      
      # 加入cpp源文件
      add_library(
              native-lib
              SHARED
              # native-lib.cpp 替换  ${allCpp} 批量导入文件
              ${allCpp}
      )
      
      # 导入静态库
      add_library(test_a STATIC IMPORTED)
      # 开始真正的导入
      set_target_properties(test_a PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libtest.a)
      
      # 只能找系统的
      find_library(
              log-lib
              log)
              
      message("当前的log路径在哪里啊 >>>>>>>>>>>>>>>>> ${log-lib}")
      
      #开始链接指定的库
      target_link_libraries(
              native-lib
              ${log-lib}
              test_a
      )
      复制代码
    • app/build.gradle cmake 配置

  2. 以动态库构建项目

    • 代码加载 so 库到手机中

          static {
              System.loadLibrary("Test");
              System.loadLibrary("native-lib");
          }
      复制代码
    • so 库导入在 main/jniLibs 下

       

      windows下使用AndroidStudio编译so

       

    • CmakeLists.txt 配置

      cmake_minimum_required(VERSION 3.4.1)
      
      # 打印日志
      message("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>>>")
      message("当前CMake的路径是:${CMAKE_SOURCE_DIR}")
      message("当前 CMAKE_ANDROID_ARCH_ABI 的路径是:${CMAKE_ANDROID_ARCH_ABI}")
      
      # 批量引入源文件
      file(GLOB allCpp *.cpp)
      
      # 加入cpp源文件
      add_library(
              native-lib
              SHARED
              # native-lib.cpp
              ${allCpp}
      )
      
      # 导入静态库
      #add_library(test_a STATIC IMPORTED)
      # 开始真正的导入
      #set_target_properties(test_a PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libtest.a)
      
      # 导入动态库
      add_library(test_so SHARED IMPORTED)
      # 早起的cmake ANDROID_ABI == 当前CPU平台
      set_target_properties(test_so PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libTest.so)
      
      # 只能找系统的
      find_library(
              log-lib
              log)
      message("当前的log路径在哪里啊 >>>>>>>>>>>>>>>>> ${log-lib}")
      
      # CMAKE_SOURCE_DIR == D:\NDK\CoursewareCreate\ndk_12\project\ndk12_cmake\app\src\main\cpp\CMakeLists.txt
      
      target_link_libraries(
              native-lib
              ${log-lib}
              test_so
      )
      复制代码
    • 在AS上编译运行,截图省略

 

相关标签: ndk Android ndk