深入浅出Android NDK之Hello-Ndk

目录
上一篇 深入浅出Android NDK之课程简介

这一节,我们介绍怎么使用NDK编译C语言源文件。
首先我们从以下页面下载一下最新的ndk
https://developer.android.google.cn/ndk/downloads/
截止到目前为止,NDK的最新版本是r20b,下载下来后,解压到任意文件夹。
比如,我解压后的路径是D:\android-ndk-r20b。
然后需要将D:\android-ndk-r20b\build目录加入PATH环境变量。
加入环境变量后,打开控制台,输入:ndk-build -v
如果能看到以下输出,说明环境变量配置成功:

C:\Users\zy>ndk-build -v
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for i686-w64-mingw32

ndk的下载,也可以参考以下链接,直接在android studio中下载。
https://developer.android.google.cn/studio/projects/install-ndk#specific-version

下面我们来新建一个hello-ndk的项目,目录结构如下:
在这里插入图片描述
hello-ndk是我们的项目根目录,hello-ndk目录下有一个jni文件夹,jni文件夹下面有Android.mk和main.c两个文件。
Android.mk的文件内容如下:

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-ndk
LOCAL_SRC_FILES := main.c
include $(BUILD_SHARED_LIBRARY)

main.c可以是一个空文件。
下面我们打开控件台,输入以下内容,cd到hello-ndk目录,输入ndk-build命令,开始编译,详细过程如下图所示:
在这里插入图片描述
编译成功后,我们打开hello-ndk\libs目录查看,发现有四个文件夹,每个文件夹下面都有一个名为libhello-ndk.so的文件。
在这里插入图片描述
libhello-ndk.so就是我们所需要的共享库。

下面我们讲解一下ndk-build编译的过程。
当我们在命令行输入ndk-build后,他会在当前目录下寻找jni文件夹,找到jni文件夹后,他会在jni文件夹下寻找文件Android.mk,找到Android.mk后,根据Android.mk所指定的编译脚本来进行编译。
所以,要想编译成功,我们的工程目录下必需要有一个名字jni的文件夹,jni文件下面必需要有一个名为Android.mk的文件。
下面我们来讲解一下Android.mk中每行代码的意思。

LOCAL_MODULE := hello-ndk

LOCAL_MODULE用于指定当前模块的名字,这个名字有两个作用:
1.影响生成的SO的名字。
2.如果Android.mk文件中有多个模块,我们可以通让名字,让模块之间相互引用。

LOCAL_SRC_FILES := main.c

LOCAL_SRC_FILES用于指定我们要编译的源文件列表,如果有多个源文件,每个源文件件之间以空格或者Tab分开,比如:

LOCAL_SRC_FILES := main.c test1.c test2.c

源文件必须在同一行指定,不能换行。
如果源文件太多一行放不下,或者为了清晰,可以像下面这么做:

LOCAL_SRC_FILES := main.c \
test1.c \
test2.c

反斜杠后紧跟回车的意思是,我这一行还没完,把下一行的内容连到当前行。

LOCAL_PATH := $(call my-dir)

LOCAL_PATH用于指定LOCAL_SRC_FILES变量中所指定的这些源文件的相对路径,一般情况下,LOCAL_SRC_FILES中所指定的都是相对路径,相对于谁呢?相对于LOCAL_PATH。
$(call my-dir)是获得Android.mk文件所在的目录,也就是jni目录。
所以我们刚刚指定的LOCAL_SRC_FILES的文件都是相对于jni目录的。
如果我们把LOCAL_PATH的值修改为D:,再调用ndk-build编译会发生什么情况呢?

LOCAL_PATH := D:
D:\ndk-demo\hello-ndk>ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version 
android-16.
make: *** No rule to make target `D:/main.c', needed by `obj/local/arm64-v8a/
objs/hello-ndk/main.o'.  Stop.

编译时发生了错误,因为找不到源文件D:/main.c。
要解决这个错误除了个以修正LOCAL_PATH的值外,还可以直接指定绝对路径:

LOCAL_SRC_FILES := D:\ndk-demo\hello-ndk\jni\main.c

当然一般很少有人会指定绝对路径,这里只是做个实验。

include $(BUILD_SHARED_LIBRARY)

这一名话标明我们这个模块是一个动态库,如果是动态库,最终会在工程目录下生成一系列的后缀名为.so的文件。

除了生成动态库外,我们也可以用include $(BUILD_STATIC_LIBRARY)成静态库。
修改一下Android.mk的内容:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := hello-ndk
LOCAL_SRC_FILES := main.c
include $(BUILD_STATIC_LIBRARY)

控制台输入ndk-build重新编译一下:

D:\ndk-demo\hello-ndk>ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
[arm64-v8a] Compile        : hello-ndk <= main.c
[arm64-v8a] StaticLibrary  : libhello-ndk.a
[armeabi-v7a] Compile thumb  : hello-ndk <= main.c
[armeabi-v7a] StaticLibrary  : libhello-ndk.a
[x86] Compile        : hello-ndk <= main.c
[x86] StaticLibrary  : libhello-ndk.a
[x86_64] Compile        : hello-ndk <= main.c
[x86_64] StaticLibrary  : libhello-ndk.a

文件管理器查看obj\local目录:
在这里插入图片描述
这四个目录,每个目录下面都有一个libhello-ndk.a的文件。

除了动态库和静态库,我们还可以生成可执行文件。
修改Android.mk如下:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := hello-ndk
LOCAL_SRC_FILES := main.c
include $(BUILD_EXECUTABLE)

控制台输入ndk-build

D:\ndk-demo\hello-ndk>ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
[arm64-v8a] Compile        : hello-ndk <= main.c
[arm64-v8a] Executable     : hello-ndk
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/../sysroot/usr/lib/aarch64-linux-android/21\crtbegin_dynamic.o: In function `_start_main':
crtbegin.c:(.text+0x38): undefined reference to `main'
crtbegin.c:(.text+0x3c): undefined reference to `main'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [obj/local/arm64-v8a/hello-ndk] Error 1

报错了,说找不到main函数。我们在main.c中添加以下内容:

int main(){
	return 0;
}

控制台输入ndk-build编译:

D:\ndk-demo\hello-ndk>ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
[arm64-v8a] Compile        : hello-ndk <= main.c
[arm64-v8a] Executable     : hello-ndk
[arm64-v8a] Install        : hello-ndk => libs/arm64-v8a/hello-ndk
[armeabi-v7a] Compile thumb  : hello-ndk <= main.c
[armeabi-v7a] Executable     : hello-ndk
[armeabi-v7a] Install        : hello-ndk => libs/armeabi-v7a/hello-ndk
[x86] Compile        : hello-ndk <= main.c
[x86] Executable     : hello-ndk
[x86] Install        : hello-ndk => libs/x86/hello-ndk
[x86_64] Compile        : hello-ndk <= main.c
[x86_64] Executable     : hello-ndk
[x86_64] Install        : hello-ndk => libs/x86_64/hello-ndk

查看libs目录:
在这里插入图片描述
这个四个目录,第个目录下都有一个可执行文件hello-ndk

include $(CLEAR_VARS)

这一句的作用是清除除了LOCAL_PATH以外,其他所有以LOCAL_开头的变量的值,比如LOCAL_SRC_FILES,LOCAL_MODULE的值。
更重要的作用是,这一句标志着一个新的模块的开始,每个模块必须以这句话开头,因为新开始了一个模块,新的模块会重新定义LOCAL_XXX的变量,为了避免不必要的bug,上一个模块的LOCAL_XXX的变量的值都应该清除,如果模块不以这句话开头,在编译的时候会报错。

下在我们来看一个多模块的例子:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := hello-ndk
LOCAL_SRC_FILES := main.c
include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := main.c
include $(BUILD_SHARED_LIBRARY)

上面的Android.mk定义了两个模块,hello-ndk和hello-jni,虽然两个模块LOCAL_SRC_FILES都是main.c,但这确实是两个模块。
在控制台输入ndk-build编译:

D:\ndk-demo\hello-ndk>ndk-build
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
[arm64-v8a] Compile        : hello-jni <= main.c
[arm64-v8a] SharedLibrary  : libhello-jni.so
[arm64-v8a] Install        : libhello-jni.so => libs/arm64-v8a/libhello-jni.so
[arm64-v8a] Compile        : hello-ndk <= main.c
[arm64-v8a] SharedLibrary  : libhello-ndk.so
[arm64-v8a] Install        : libhello-ndk.so => libs/arm64-v8a/libhello-ndk.so
[armeabi-v7a] Compile thumb  : hello-jni <= main.c
[armeabi-v7a] SharedLibrary  : libhello-jni.so
[armeabi-v7a] Install        : libhello-jni.so => libs/armeabi-v7a/libhello-jni.so
[armeabi-v7a] Compile thumb  : hello-ndk <= main.c
[armeabi-v7a] SharedLibrary  : libhello-ndk.so
[armeabi-v7a] Install        : libhello-ndk.so => libs/armeabi-v7a/libhello-ndk.so
[x86] Compile        : hello-jni <= main.c
[x86] SharedLibrary  : libhello-jni.so
[x86] Install        : libhello-jni.so => libs/x86/libhello-jni.so
[x86] Compile        : hello-ndk <= main.c
[x86] SharedLibrary  : libhello-ndk.so
[x86] Install        : libhello-ndk.so => libs/x86/libhello-ndk.so
[x86_64] Compile        : hello-jni <= main.c
[x86_64] SharedLibrary  : libhello-jni.so
[x86_64] Install        : libhello-jni.so => libs/x86_64/libhello-jni.so
[x86_64] Compile        : hello-ndk <= main.c
[x86_64] SharedLibrary  : libhello-ndk.so
[x86_64] Install        : libhello-ndk.so => libs/x86_64/libhello-ndk.so

输出多了很多,主要多了libhello-jni.so的生成,打开文件管理器,查看libs\ameabi-v7a目录
在这里插入图片描述
该目录下不仅有libhello-ndk.so还有libhello-jni.so

下面我们总结一下Android.mk的结构:
1.一般情况下,每个Android.mk都以LOCAL_PATH := $(call my-dir)开头
2.一般情况下,每个模块都以include $(CLEAR_VARS)开头,以include ( B U I L D S H A R E D L I B R A R Y ) 或 者 (BUILD_SHARED_LIBRARY)或者 (BUILDSHAREDLIBRARY)(BUILD_STATIC_LIBRARY)或者include $(BUILD_EXECUTABLE)结尾。
3.中间定义的LOCAL_XXX变量,这些变量的顺序无所谓,哪个在前,哪个在后都可以

下面我们再还看一个ndk-build的其他用法。

ndk-build -C <project> 

除了cd到项目目录(jni文件夹的父目录),调用ndk-build外,我们还要以像下面这么做。
在任意目录,调用ndk-build -C D:\ndk-demo\hello-ndk,效果也是一样的。
也就是说我们也要通过-C参数指定项目目录,如果没有指定,则ndk-build默认以当前目录做为项目目录。

ndk-build clean 

这个写代码的应该都知道,其作用相当于删除obj文件夹和libs文件夹。
默认情况下,ndk-build都是增量编译,如果你的源文件编译过,在没有修改过源文件的情况下,下一次执行ndk-build的时候,为了节省编译时候,你的源文件不会重新编译。
调用了ndk-build clean以后再调用ndk-build所有的文件都会被重新编译。

ndk-build -B

强制执行完整的重新编译,其实就是先ndk-build clean再ndk-build

ndk-build V=1

在编译时会有更详细的输出,显示编译和链接命令,像下面这样。

D:\ndk-demo\hello-ndk>ndk-build V=1
Android NDK: APP_PLATFORM not set. Defaulting to minimum supported version android-16.
del /f/q .\libs\arm64-v8a\libhello-ndk.so .\libs\armeabi-v7a\libhello-ndk.so .\libs\x86\libhello-ndk.so .\libs\x86_64\libhello-ndk.so >NUL 2>NUL
[arm64-v8a] Compile        : hello-jni <= main.c
del /f/q .\obj\local\arm64-v8a\objs\hello-jni\main.o >NUL 2>NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF ./obj/local/arm64-v8a/objs/hello-jni/main.o.d -target aarch64-none-linux-android21 -fdata-sections -ffunction-sections -fstack-protector-strong -funwind-tables -no-canonical-prefixes  --sysroot D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -Wno-invalid-command-line-argument -Wno-unused-command-line-argument  -fno-addrsig -fpic -O2 -DNDEBUG  -Ijni   -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security  -c  jni/main.c -o ./obj/local/arm64-v8a/objs/hello-jni/main.o
[arm64-v8a] SharedLibrary  : libhello-jni.so
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libhello-jni.so -shared ./obj/local/arm64-v8a/objs/hello-jni/main.o -lgcc -Wl,--exclude-libs,libgcc.a -latomic -Wl,--exclude-libs,libatomic.a -target aarch64-none-linux-android21 -no-canonical-prefixes     -Wl,--build-id -stdlib=libstdc++ -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--warn-shared-textrel -Wl,--fatal-warnings  -lc -lm -o ./obj/local/arm64-v8a/libhello-jni.so
[arm64-v8a] Install        : libhello-jni.so => libs/arm64-v8a/libhello-jni.so
copy /b/y ".\obj\local\arm64-v8a\libhello-jni.so" ".\libs\arm64-v8a\libhello-jni.so" > NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-strip --strip-unneeded  ./libs/arm64-v8a/libhello-jni.so
[arm64-v8a] Compile        : hello-ndk <= main.c
del /f/q .\obj\local\arm64-v8a\objs\hello-ndk\main.o >NUL 2>NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF ./obj/local/arm64-v8a/objs/hello-ndk/main.o.d -target aarch64-none-linux-android21 -fdata-sections -ffunction-sections -fstack-protector-strong -funwind-tables -no-canonical-prefixes  --sysroot D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -Wno-invalid-command-line-argument -Wno-unused-command-line-argument  -fno-addrsig -fpic -O2 -DNDEBUG  -Ijni   -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security  -c  jni/main.c -o ./obj/local/arm64-v8a/objs/hello-ndk/main.o
[arm64-v8a] SharedLibrary  : libhello-ndk.so
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libhello-ndk.so -shared ./obj/local/arm64-v8a/objs/hello-ndk/main.o -lgcc -Wl,--exclude-libs,libgcc.a -latomic -Wl,--exclude-libs,libatomic.a -target aarch64-none-linux-android21 -no-canonical-prefixes     -Wl,--build-id -stdlib=libstdc++ -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--warn-shared-textrel -Wl,--fatal-warnings  -lc -lm -o ./obj/local/arm64-v8a/libhello-ndk.so
[arm64-v8a] Install        : libhello-ndk.so => libs/arm64-v8a/libhello-ndk.so
copy /b/y ".\obj\local\arm64-v8a\libhello-ndk.so" ".\libs\arm64-v8a\libhello-ndk.so" > NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/aarch64-linux-android-strip --strip-unneeded  ./libs/arm64-v8a/libhello-ndk.so
[armeabi-v7a] Compile thumb  : hello-jni <= main.c
del /f/q .\obj\local\armeabi-v7a\objs\hello-jni\main.o >NUL 2>NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF ./obj/local/armeabi-v7a/objs/hello-jni/main.o.d -target armv7-none-linux-androideabi16 -fdata-sections -ffunction-sections -fstack-protector-strong -funwind-tables -no-canonical-prefixes  --sysroot D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -Wno-invalid-command-line-argument -Wno-unused-command-line-argument  -fno-addrsig -fpic -march=armv7-a -mthumb -Oz -DNDEBUG  -Ijni   -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security  -c  jni/main.c -o ./obj/local/armeabi-v7a/objs/hello-jni/main.o
[armeabi-v7a] SharedLibrary  : libhello-jni.so
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libhello-jni.so -shared ./obj/local/armeabi-v7a/objs/hello-jni/main.o -lgcc -Wl,--exclude-libs,libgcc.a -latomic -Wl,--exclude-libs,libatomic.a -target armv7-none-linux-androideabi16 -no-canonical-prefixes     -Wl,--build-id -stdlib=libstdc++ -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--warn-shared-textrel -Wl,--fatal-warnings   -lc -lm -o ./obj/local/armeabi-v7a/libhello-jni.so
[armeabi-v7a] Install        : libhello-jni.so => libs/armeabi-v7a/libhello-jni.so
copy /b/y ".\obj\local\armeabi-v7a\libhello-jni.so" ".\libs\armeabi-v7a\libhello-jni.so" > NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/arm-linux-androideabi-strip --strip-unneeded  ./libs/armeabi-v7a/libhello-jni.so
[armeabi-v7a] Compile thumb  : hello-ndk <= main.c
del /f/q .\obj\local\armeabi-v7a\objs\hello-ndk\main.o >NUL 2>NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF ./obj/local/armeabi-v7a/objs/hello-ndk/main.o.d -target armv7-none-linux-androideabi16 -fdata-sections -ffunction-sections -fstack-protector-strong -funwind-tables -no-canonical-prefixes  --sysroot D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -Wno-invalid-command-line-argument -Wno-unused-command-line-argument  -fno-addrsig -fpic -march=armv7-a -mthumb -Oz -DNDEBUG  -Ijni   -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security  -c  jni/main.c -o ./obj/local/armeabi-v7a/objs/hello-ndk/main.o
[armeabi-v7a] SharedLibrary  : libhello-ndk.so
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libhello-ndk.so -shared ./obj/local/armeabi-v7a/objs/hello-ndk/main.o -lgcc -Wl,--exclude-libs,libgcc.a -latomic -Wl,--exclude-libs,libatomic.a -target armv7-none-linux-androideabi16 -no-canonical-prefixes     -Wl,--build-id -stdlib=libstdc++ -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--warn-shared-textrel -Wl,--fatal-warnings   -lc -lm -o ./obj/local/armeabi-v7a/libhello-ndk.so
[armeabi-v7a] Install        : libhello-ndk.so => libs/armeabi-v7a/libhello-ndk.so
copy /b/y ".\obj\local\armeabi-v7a\libhello-ndk.so" ".\libs\armeabi-v7a\libhello-ndk.so" > NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/arm-linux-androideabi-strip --strip-unneeded  ./libs/armeabi-v7a/libhello-ndk.so
[x86] Compile        : hello-jni <= main.c
del /f/q .\obj\local\x86\objs\hello-jni\main.o >NUL 2>NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF ./obj/local/x86/objs/hello-jni/main.o.d -target i686-none-linux-android16 -fdata-sections -ffunction-sections -fstack-protector-strong -funwind-tables -no-canonical-prefixes  --sysroot D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -Wno-invalid-command-line-argument -Wno-unused-command-line-argument  -fno-addrsig -fPIC -O2 -DNDEBUG  -Ijni   -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security -mstackrealign  -c  jni/main.c -o ./obj/local/x86/objs/hello-jni/main.o
[x86] SharedLibrary  : libhello-jni.so
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libhello-jni.so -shared ./obj/local/x86/objs/hello-jni/main.o -lgcc -Wl,--exclude-libs,libgcc.a -latomic -Wl,--exclude-libs,libatomic.a -target i686-none-linux-android16 -no-canonical-prefixes     -Wl,--build-id -stdlib=libstdc++ -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--warn-shared-textrel -Wl,--fatal-warnings  -lc -lm -o ./obj/local/x86/libhello-jni.so
[x86] Install        : libhello-jni.so => libs/x86/libhello-jni.so
copy /b/y ".\obj\local\x86\libhello-jni.so" ".\libs\x86\libhello-jni.so" > NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/i686-linux-android-strip --strip-unneeded  ./libs/x86/libhello-jni.so                                                                                                 [x86] Compile        : hello-ndk <= main.c
del /f/q .\obj\local\x86\objs\hello-ndk\main.o >NUL 2>NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF ./obj/local/x86/objs/hello-ndk/main.o.d -target i686-none-linux-android16 -fdata-sections -ffunction-sections -fstack-protector-strong -funwind-tables -no-canonical-prefixes  --sysroot D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -Wno-invalid-command-line-argument -Wno-unused-command-line-argument  -fno-addrsig -fPIC -O2 -DNDEBUG  -Ijni   -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security -mstackrealign  -c  jni/main.c -o ./obj/local/x86/objs/hello-ndk/main.o
[x86] SharedLibrary  : libhello-ndk.so
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libhello-ndk.so -shared ./obj/local/x86/objs/hello-ndk/main.o -lgcc -Wl,--exclude-libs,libgcc.a -latomic -Wl,--exclude-libs,libatomic.a -target i686-none-linux-android16 -no-canonical-prefixes     -Wl,--build-id -stdlib=libstdc++ -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--warn-shared-textrel -Wl,--fatal-warnings  -lc -lm -o ./obj/local/x86/libhello-ndk.so
[x86] Install        : libhello-ndk.so => libs/x86/libhello-ndk.so
copy /b/y ".\obj\local\x86\libhello-ndk.so" ".\libs\x86\libhello-ndk.so" > NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/i686-linux-android-strip --strip-unneeded  ./libs/x86/libhello-ndk.so
[x86_64] Compile        : hello-jni <= main.c
del /f/q .\obj\local\x86_64\objs\hello-jni\main.o >NUL 2>NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF ./obj/local/x86_64/objs/hello-jni/main.o.d -target x86_64-none-linux-android21 -fdata-sections -ffunction-sections -fstack-protector-strong -funwind-tables -no-canonical-prefixes  --sysroot D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -Wno-invalid-command-line-argument -Wno-unused-command-line-argument  -fno-addrsig -fPIC -O2 -DNDEBUG  -Ijni   -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security  -c  jni/main.c -o ./obj/local/x86_64/objs/hello-jni/main.o[x86_64] SharedLibrary  : libhello-jni.so                                                                               D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libhello-jni.so -shared ./obj/local/x86_64/objs/hello-jni/main.o -lgcc -Wl,--exclude-libs,libgcc.a -latomic -Wl,--exclude-libs,libatomic.a -target x86_64-none-linux-android21 -no-canonical-prefixes     -Wl,--build-id -stdlib=libstdc++ -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--warn-shared-textrel -Wl,--fatal-warnings  -lc -lm -o ./obj/local/x86_64/libhello-jni.so
[x86_64] Install        : libhello-jni.so => libs/x86_64/libhello-jni.so
copy /b/y ".\obj\local\x86_64\libhello-jni.so" ".\libs\x86_64\libhello-jni.so" > NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/x86_64-linux-android-strip --strip-unneeded  ./libs/x86_64/libhello-jni.so
[x86_64] Compile        : hello-ndk <= main.c
del /f/q .\obj\local\x86_64\objs\hello-ndk\main.o >NUL 2>NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang.exe -MMD -MP -MF ./obj/local/x86_64/objs/hello-ndk/main.o.d -target x86_64-none-linux-android21 -fdata-sections -ffunction-sections -fstack-protector-strong -funwind-tables -no-canonical-prefixes  --sysroot D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/sysroot -g -Wno-invalid-command-line-argument -Wno-unused-command-line-argument  -fno-addrsig -fPIC -O2 -DNDEBUG  -Ijni   -DANDROID  -Wa,--noexecstack -Wformat -Werror=format-security  -c  jni/main.c -o ./obj/local/x86_64/objs/hello-ndk/main.o[x86_64] SharedLibrary  : libhello-ndk.so
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/clang++.exe -Wl,-soname,libhello-ndk.so -shared ./obj/local/x86_64/objs/hello-ndk/main.o -lgcc -Wl,--exclude-libs,libgcc.a -latomic -Wl,--exclude-libs,libatomic.a -target x86_64-none-linux-android21 -no-canonical-prefixes     -Wl,--build-id -stdlib=libstdc++ -Wl,--no-undefined -Wl,-z,noexecstack -Wl,--warn-shared-textrel -Wl,--fatal-warnings  -lc -lm -o ./obj/local/x86_64/libhello-ndk.so
[x86_64] Install        : libhello-ndk.so => libs/x86_64/libhello-ndk.so
copy /b/y ".\obj\local\x86_64\libhello-ndk.so" ".\libs\x86_64\libhello-ndk.so" > NUL
D:/android-ndk-r20b/build//../toolchains/llvm/prebuilt/windows-x86_64/bin/x86_64-linux-android-strip --strip-unneeded  ./libs/x86_64/libhello-ndk.so

最后再说一个文档上没有但很有用的,默认情况下,ndk-build都是单线程编译。如果你的源文件较多,那编译可能会有点儿慢,可以通过传递-j参数开启多线程编译,比如像下面这样:
ndk-build -j32
开启32个线程进行编译,编译速度杠杠的。

最后,执行ndk-build,其实相当于执行:
$GNUMAKE -f /build/core/build-local.mk
build-local.mk会将我们的Android.mk包含进去,所以除了-j32外,gnu make有什么参数,都可以加在ndk-build里面

下一篇 深入浅出Android NDK之Android.mk基本语法

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值