深入浅出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
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: android-ndk-r12b-windows-x86.zip 是一个 Android NDK 的压缩文件。Android NDK (Native Development Kit) 是一个让开发者能够使用 C 或 C++ 程序语言编写 Android 应用的工具集合。它主要用于开发需要高性能或使用底层库的应用程序。 android-ndk-r12b-windows-x86.zip 针对的是 Windows 系统的 32 位操作系统。该文件包含了 Android NDK 的相关文件和工具,可供开发者使用。开发者可以通过下载该文件,解压缩并配置环境变量,以便在 Windows 上编写和构建 C/C++ 代码的 Android 应用程序。 该压缩文件中包含了编译器、调试器、标准系统库、头文件以及其他构建和调试所需的文件。通过使用该工具集合,开发者可以充分利用 C/C++ 语言的速度和功能,编写高性能、复杂的 Android 应用程序。 同时需要注意的是,该压缩文件适用于 Windows 系统的 32 位操作系统。如果你的设备或操作系统是其他类型的,可能需要下载适用于该设备或操作系统的相应版本。 ### 回答2: android-ndk-r12b-windows-x86.zip 是一个Android NDK(Native Development Kit)的压缩文件。 NDK是一个用于开发Android平台上原生代码的工具集。它允许开发者在Java平台上编写Android应用程序的同时,通过使用C或C++等编程语言编写高性能和复杂度较高的代码模块。NDK通过将应用程序的代码编译为与硬件平台相关的机器码实现高效执行。 android-ndk-r12b-windows-x86.zip 这个文件是适用于Windows操作系统的NDK的压缩文件,特定于x86架构。这意味着该NDK版本适用于基于x86架构的32位执行环境,例如32位的Windows操作系统。 该压缩文件包含了开发者在Windows系统上使用NDK所需的所有文件和工具,如编译器、调试器、库文件等。开发者可以使用这个NDK版本来编写和构建在x86架构上运行的Android应用程序。 通过使用NDK,开发者可以利用C或C++编写更高效和功能强大的代码,也可以重用已有的C/C++代码库。这对于需要执行高计算密集型任务、需要访问底层硬件功能或需要与跨平台C/C++库集成的应用程序非常有用。 总之,android-ndk-r12b-windows-x86.zip 是一个适用于Windows操作系统的Android NDK的压缩文件,特定于x86架构。使用这个NDK版本,开发者可以编写高性能、复杂度较高的代码以实现更强大的Android应用程序。 ### 回答3: android-ndk-r12b-windows-x86.zip是一个用于Windows操作系统的Android NDK(Native Development Kit)软件包。Android NDK是一个开发工具集,可以帮助开发人员使用C和C++语言编写Android应用程序。它提供了一组库和工具,允许开发者直接使用本地代码进行开发。 android-ndk-r12b-windows-x86.zip包含了NDK的安装程序和相关的文件。用户可以通过解压缩这个压缩包来安装NDK。一旦安装完成,开发者就可以在Windows操作系统上使用NDK来开发Android应用程序。这个特定的压缩包适用于x86架构的计算机,这是一种常见的Windows计算机架构。 使用android-ndk-r12b-windows-x86.zip,开发者可以利用NDK的功能来更好地优化他们的Android应用程序。这包括直接使用本机代码编写应用程序的能力,以及访问底层系统功能的能力。通过使用NDK,开发者可以在性能关键的部分使用底层代码,提高应用程序的速度和效率。 android-ndk-r12b-windows-x86.zip是一个方便开发者使用Android NDK的软件包。它使开发者能够充分利用底层功能,并开发出更高效的Android应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值