当前位置:   article > 正文

C与C++编译器Android交叉编译配置_android 编译c库

android 编译c库

目录

目录

一、gcc与g++编译器

二、使用Linux自带的gcc或g++编译源文件生成的可执行文件

三、编译Android手机可用的可执行文件

四、编译动态库

五、编译静态库


一、gcc与g++编译器

了解C/C++编译器的基本使用,能够在后续移植第三方库进行交叉编译时,清楚了解应该传递什么参数

gcc与g++是我比较常用的编译器,关于这两个编译器有几点需要注意:

(1)gcc和g++都能够编译c/c++,但是编译时候行为不同

(2)后缀为.c的源文件,gcc把它当作是C程序,而g++当作是C++程序;后缀为.cpp的,两者都会认为是c++程序

(3)g++会自动链接c++标准库stl,gcc不会

(4)gcc不会定义__cplusplus宏,而g++会

Linux系统都是自带这两种编译器的,我们可以检验一下。

在终端输入 gcc或g++,出现如下字样,表明已安装

如果没有安装 使用下面指令安装

apt install build-essential

二、使用Linux自带的gcc或g++编译源文件生成的可执行文件

(1)编写一个简单的.c的文件

  1. #include<stdio.h>
  2. int main(){
  3. printf("hello linux!\n");
  4. return 0;
  5. }

(2)使用gcc进行编译

  1. #-o main.o 表示输出的文件名是main.o,也可以不带后缀
  2. gcc -o main.o main.c

这时候有的人就会认为这个生成main.o这个可执行文件应该可以在android手机中执行,毕竟android手机也是Linux系统的。其实并不是这样,因为Ubuntu(我的服务器系统)与android手机的cpu指令集不一样,必须使用android NDK中的gcc或g++去编译才可以

三、编译Android手机可用的可执行文件

1.下载NDK,并进行解压

  1. #下载NDK
  2. wget https://dl.google.com/android/repository/android-ndk-r17b-linux-x86_64.zip
  3. #解压 unzip后面跟着的是刚刚下载的文件
  4. unzip android-ndk-r17b-linux-x86_64.zip

2.设置NDK中gcc的临时环境变量

  1. export ANDROID_64_ARM_GCC=/linux/android-ndk-r17b/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
  2. #注意:
  3. 1)这里填写的应该是绝对路径,我们进入到bin这个目录后输入 pwd这个指令,就可以输出绝对路径了
  4. 2)这里我们用的64位的

3.头文件及库文件的设置

有人认为,使用刚刚设置的临时变量的gcc去编译应该没问题了吧,其实不然。为什么,这个简单的c源文件中引入了stdio.h这个头文件,我们需要给编译器指定一个头文件及库文件的查找路径才行。

关于头文件及库文件的路径的指定有下面几条指令:

(1)--sysroot=目录1

在AAA这个路径下的 usr/include中查找头文件;在目录1这个路径下的 usr/lib中查找库文件

(2)-isysroot 目录2

在目录2这个路径下的usr/include中查找头文件,需要注意的是:这样设置之后,会覆盖--sysroot=目录1中的头文件的查找路径

(3)-isystem 目录3

直接在目录3这个路径的目录下去查找头文件,并不是usr/include中了,需要注意

(4)-I目录4

同(3)

而优先级是:先(4),后(3),再(2)

(5)-L目录 -l库名

-L目录:指定库文件查找目录 

-l库名:指定需要链接的库名

比如我需要链接C:\Users\codef\AppData\Local\Android\Sdk\ndk-bundle\platforms\android-21\arch-x86\usr\lib路径下的liblog.so文件,我就可以这样写

-LC:\Users\codef\AppData\Local\Android\Sdk\ndk-bundle\platforms\android-21\arch-x86\usr\lib -llog

4.给NDK中的头文件及库文件这只一个临时变量

  1. export C_H_PATH="--sysroot=/linux/android-ndk-r17b/platforms/android-21/arch-arm -isysroot /linux/android-ndk-r17b/sysroot -isystem /linux/android-ndk-r17b/sysroot/usr/include/arm-linux-androideabi -pie"
  2. #注意:结尾处一定要加 -pie,否则执行可执行文件时会报错

5.编译

$ANDROID_64_ARM_GCC $C_H_PATH -o main.o main.c

此时生成的main.o文件就可以在在Android手机中运行了

如何测试main.o文件能否在Android手机中运行呢

(1)将main.o文件copy到桌面,我使用的是XShell,所以指令如下

sz main.o

(2)将windows的cmd切换到桌面路径,之后执行如下指令

  1. #将文件传到手机或虚拟中上(前提是有手机连接或虚拟机开启)
  2. adb push main.o /sdcard/
  3. #切换至手机或虚拟机
  4. adb shell
  5. #进入到sdcard目录
  6. cd /sdcard
  7. #执行,如果没有问题的话,就会执行c代码
  8. ./main.o

注意:手机需要root

四、编译动态库

1.生成动态库

  1. $ANDROID_64_ARM_GCC $C_H_PATH -o libTest.so test.c
  2. 注意:
  3. 1)ANDROID_64_ARM_GCC 与 C_H_PATH 是上面定义好的环境变量
  4. 2)libTest.so是生成的动态库文件

2.在android手机中编译

(1)将动态库放在下面的文件夹下,这个路径不可变(可在build.gradle中改变这个路径,默认的话就是这个路径)

(2)在相应的类中调用native-lib-test(动态库的调用在native-lib-test文件中)

(3)native-lib-test.cpp文件的内容

红色的地方一定要特别注意:

⒈动态库是由.c的源文件生成的,所以extern "C"不能少

⒉extern in test() 表示声明动态库的test()文件

(4)CMakeLists.txt中文件的配置

  1. cmake_minimum_required(VERSION 3.4.1)
  2. add_library(
  3. native-lib-test
  4. SHARED
  5. src/main/cpp/native-lib-test.cpp)
  6. #CMAKE_SOURCE_DIR:当前目录的地址
  7. #ANDROID_ABI:jniLibs目录下的cpu架构
  8. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}")
  9. find_library(
  10. log-lib
  11. log )
  12. target_link_libraries(
  13. native-lib-test
  14. Test
  15. ${log-lib} )

这样动态库就能够在Android手机端运行了

五、编译静态库

和动态编译有两个不一样的地方

(1)指令不同

  1. 第一步:$ANDROID_64_ARM_GCC $CFLAGS -o staticTest.o -c staticTest.c
  2. 第二步:a r libstaticTest.a staticTest.o

(2)路径可随意指定,在CMakeLists.txt中进行引用就好了

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/src/main/libs/${ANDROID_ABI}")

有问题可以留言,欢迎指错!欢迎纠正!

资源地址

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/573149
推荐阅读
相关标签
  

闽ICP备14008679号