導航:首頁 > 操作系統 > toolchainandroid

toolchainandroid

發布時間:2022-07-28 21:34:10

⑴ 如何編譯android動態鏈編的native c/c++code

編譯環境要求:下載Android的源碼,並執行完一次完整的編譯。以下的所有命令均是在編譯後的源碼根目錄下執行。

1. 編譯C code
同樣以hello.c為例:

#include <stdio.h>
#include <stdlib.h>

int main()
{
printf("hello, world!\n");
return 0;
}


執行以下步驟生成動態鏈編的binary文件:
生成目標文件:prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-gcc -I bionic/libc/arch-arm/include -I bionic/libc/include -I bionic/libstdc++/include -I bionic/libc/kernel/common -I bionic/libc/kernel/arch-arm -include system/core/include/arch/linux-arm/AndroidConfig.h -c -o hello.o hello.c
生成可執行程序:prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm- eabi-gcc -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,noreloc -o hello -Lout/target/proct/generic/obj/lib -Wl,-rpath-link=out/target/proct/generic/obj/lib -lc -lstdc++ out/target/proct/generic/obj/lib/crtbegin_dynamic.o hello.o -Wl,--no-undefined ./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a out/target/proct/generic/obj/lib/crtend_android.o

用命令file查看生成的hello文件屬性:
hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped
可以證明此時的hello是一個動態鏈編的文件。

2. 編譯native c++ 代碼
以hello_cpp為例:

hello_cpp.h
#ifndef HELLO_CPP_H
#define HELLO_CPP_H

class Hello
{
public:
Hello();
~Hello();
void printMessage(char* msg);
};

#endif

hello_cpp.cpp
#include <stdio.h>
#include "hello_cpp.h"

Hello::Hello()
{
}

Hello::~Hello()
{
}

void Hello::printMessage(char* msg)
{
printf("C++ example printing message: %s", msg);
}

int main(void)
{
Hello hello_obj;
hello_obj.printMessage("Hello world!\n");
return 0;
}
執行以下命令完成:
編譯目標文件:prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm-eabi-g++ -I bionic/libc/arch-arm/include -I bionic/libc/include -I bionic/libstdc++/include -I bionic/libc/kernel/common -I bionic/libc/kernel/arch-arm -include system/core/include/arch/linux-arm/AndroidConfig.h -fno-exceptions -fno-rtti -c -o hello_cpp.o hello_cpp.cpp
編譯可執行程序:prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/arm- eabi-g++ -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,noreloc -o hello_cpp -Lout/target/proct/generic/obj/lib -Wl,-rpath-link=out/target/proct/generic/obj/lib -lc -lstdc++ out/target/proct/generic/obj/lib/crtbegin_dynamic.o hello_cpp.o -Wl,--no-undefined ./prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin/../lib/gcc/arm-eabi/4.2.1/interwork/libgcc.a out/target/proct/generic/obj/lib/crtend_android.o

同樣用file查看hello_cpp的文件屬性:
hello_cpp: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), stripped

但是很不幸的是,android自帶的toolchain不支持C++標准庫的開發,即所有的std namespace下的類均無法使用,包括基本的string。

⑵ android ndk 用什麼工具

首先需要確定目標機器的指令集。
如果是 x86 的機器,用 x86-4.4.3 版本的工具鏈;如果是 arm 指令的,用 arm-linux-androideabi-4.4.3 版本 (x86-4.4.3 和 arm-linux-androideabi-4.4.3 位於ndk目錄中)
1、gcc 的sysroot 選項
sysroot 選項設定 gcc 在編譯源碼的時候,尋找頭文件和庫文件的根目錄。可以這樣調用 gcc --sysroot=/tmp/gcc-arm (及其他選項)。NDK 根目錄下的 platforms 目錄中的各個子目錄的路徑都可以直接傳給 gcc --sysroot=<dir>。為了簡化操作,可以在linux系統的命令終端執行以下命令,設置SYSROOT環境變數,$NDK是ndk的根目錄。
$ SYSROOT=$NDK/platforms/android-8/arch-arm
2、調用 NDK gcc(第1種方法)。 設置 SYSROOT之後,要把它傳給 gcc 的 --sysroot 選項。由於unix/linux自帶的gcc並非交叉編譯工具,而我們需要使用的是ndk中提供的交叉編譯工具(也是gcc),所以需要想辦法讓編譯腳本找到ndk中的gcc,而不要去尋找系統中的gcc。而 unix/linux 系統的編譯腳本常常會用 CC 環境變數來引用編譯器,所以通過把 CC 設置為ndk中的gcc的路徑,就能幫助編譯腳本找到正確的gcc(我們還能順便加上--sysroot選項)。
將CC 按如下設置
$ export CC="$NDK/toolchains/<name>/prebuilt/<host-system>/bin/<prefix>gcc --sysroot=$SYSROOT"
$ $CC -o foo.o -c foo.c (不必執行這一行,這條命令是調用gcc編譯程序)
上面第1行之後之後,再去執行./configure 就可以編譯出arm程序了。不過還需要考慮共享庫的鏈接問題,要確保該程序沒有鏈接ndk未提供的共享庫。該方法的缺陷就是,不能使用 C++ STL(STLport 或 GNU libstdc++ ),也不能使用異常機制和RTTI。
3、調用NDK編譯器(第2種方法,更簡單)
android ndk 提供腳本,允許自己定製一套工具鏈。例如:
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain [ --arch=x86 ]
將會在/tmp/my-android-toolchain 中創建 sysroot 環境和 工具鏈。--arch 選項選擇目標程序的指令架構,默認是為 arm。
如果不加 --install-dir 選項,則會創建 /tmp/ndk/<toolchain-name>.tar.bz2。
(執行 make-standalone-toolchain.sh --help 查看幫助。)
運行之後,這樣使用:
$ export PATH=/tmp/my-android-toolchain/bin:$PATH
$ export CC=arm-linux-androideabi-gcc
$ export CXX=arm-linux-androideabi-g++
$ export CXXFLAGS="-lstdc++"
執行完以上設置環境變數的命令之後,就可以直接編譯了(例如,執行 ./configure 然後 make 得到的就是 arm 程序了)。不用再設定 sysroot, CC 了。而且,可以使用 STL,異常,RTTI。
4、ABI 兼容性
ndk 同時支持 arm5 和 arm7,一般只用 arm5就好了。arm7是高端一點的,NDK 默認也是 arm5 。
推薦加上 -mthumb 選項給gcc,來生成 16-bit Thumb-1 指令。
如果要用 arm7,可以設定 CFLAGS='-march=armv7-a -mfloat-abi=softfp', 使用 Thumb-2 指令,且這兩個選項不能分開!
5、警告 & 限制
5.1 Windows支持
Windows 上的NDK 工具鏈不依賴 Cygwin,因而速度比用 Cygwin 快一點,但是這些工具不能理解
Cygwin 的路徑名(例如, /cygdrive/c/foo/bar)。只能理解 C: /cygdrive/c/foo/bar 這類路徑
不過,NDK 提供的build工具能夠很好地應對上述問題(ndk-build)
5.2 wchar_t 支持
wchar_t 類型僅從 Android 2.3 開始支持。
在 android-9 上, wchar_t 是 4位元組。 並且 C語言庫提供支持寬字元的函數
(例外:multi-byte 編碼/解碼 函數 和 wsprintf/wsscanf )
在android-9 以前的平台上,wchar_t 是1位元組,而且寬字元函數不起作用。
建議不使用 wchar_t,提供 wchar_t 支持是為了方便移植以前的代碼。
5.3 異常, RTTI 和 STL
NDK 工具鏈默認支持C++異常和RTTI(Run Time Type Information),可以用 -fno-exception 和 -fno-rtti 關閉(生成的機器碼更小)
注意: 如果要用這兩個特性,需要顯式鏈接 libsupc++。例如: arm-linux-androideabi-g++ .... -lsupc++
NDK 提供了 libstdc++,因而可以用 STL,但需要顯式鏈接 libstdc++ ( gcc ... -lstdc++)。不過在將來可以不用手動指定這個鏈接參數。

⑶ 如何使用android的ndk建立native的開發環境

從網上看了一篇使用andriod的toolchain在cygwin上來建立android的開發環境,但是在vista上編譯始終失敗,在xp上能夠成功。但是編譯的時間比較長,而且對於新手來說也比較麻煩,難道就沒有簡單的方法嗎?google已經把andriod的ndk已經放出來了,所以我就想著打它的主意了,把它配置一下,就能來開發c的程序了。旁邊小伙肯定笑了,「搞啥?,有病啊,ndk就是一個開發native code的環境。」大哥,我當然知道了,雖然使用ndk來開發native code相對容易,但是它的.mk文件我看的是雲里霧里,我本來想調用自己寫的另外一個so庫,都不知道在.mk文件里如何寫,我現在也懶的去看ndk裡面的mk文件,等哪天(哪天?天曉得是哪一天)有空了好好研究一下。好了,閑話少說,開練吧。首先安裝cygwin,這個網上的教程多的是,就不說了,接著下載android ndk,這個在andriod的官網上就有了,然後下載一個從android模擬器里取system lib的工具busybox,然後調用命令

$adb push busybox /dev/sample/busybox

$adb shell chmod 777 /dev/sample/busybox

$adb shell ./dev/sample/busybox tar -cf /dev/sample/libs.tar /system/lib

$adb pull /dev/sample/libs.tar libs.tar

這樣就將模擬器下的 /system/lib 目錄的所有庫(so)文件打包並下載下來了,解壓libs.tar就得到了我們所需要的所有庫文件。

接著將所有的文件 到 $(NDK)/build/prebuilt/windows/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1,好了,這個時候基本的配置工作就結束了,怎麼樣簡單多了吧。

接著編寫一個簡單的c文件 tutorial01.c

#include <stdio.h>

int getinformation()

{

return 0;

}

然後編寫一個Makefile文件

CC = /cygdrive/f/software/android/android-ndk-1.5_r1/build/prebuilt/windows/arm-eabi-4.2.1/bin/arm-eabi-gcc

CFLAGS = -g -O2 -fPIC -DANDROID -I ./ -I ../ -I F:/software/android/android-ndk-1.5_r1/build/platforms/android-1.5/arch-arm/usr/include

SDFLAGS = -nostdlib -Wl,-T,armelf.xsc -Wl,-soname,$@ -Wl,-shared,-Bsymbolic -lc

CRT_OBJS= -lz -lm

all: libtutorial01.so

libtutorial01.so: tutorial01.o

$(CC) $(SDFLAGS) -o $@ tutorial01.o $(CRT_OBJS)

tutorial01.o: tutorial01.c

然後make,這個時候會報錯 can't find "armelf.xsc", 在ndk的目錄里搜索一下,搜到之後 到$(NDK)/build/prebuilt/windows/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1,然後make,成功。這樣一個簡單的so文件就生成了,這個時候如果想在android的虛擬機上運行,我們還需要給它包裝一下。再編寫一個文件test01.c,在這里是使用dl動態載入so文件,靜態載入始終有問題,搞不清楚android是如何搜索目錄,而且現在只能用絕對路徑,這個問題還得仔細研究研究。

#include <string.h>

#include <jni.h>

jint

java_com_example_testffmpeg_testffmpeg_getinformation( JNIEnv* env,

jobject thiz )

{

void* filehandle = dlopen("/data/data/com.example.test/lib/libtutorial.so", RTLD_LAZY );

int ll = -1;

if(filehandle)

{

int( * getinformation ) ();

getinformation = dlsym(filehandle, "getinformation");

if( getinformation )

{

ll = getinformation();

}

else

{

ll = -3;

}

dlclose(filehandle);

filehandle=0;

}

else

{

ll = -2;

}

return ll;

}

同樣再來一個Makefile文件

CC = /cygdrive/f/software/android/android-ndk-1.5_r1/build/prebuilt/windows/arm-eabi-4.2.1/bin/arm-eabi-gcc

CFLAGS = -g -O2 -fPIC -DANDROID -I ./ -I ../ -I F:/software/android/android-ndk-1.5_r1/build/platforms/android-1.5/arch-arm/usr/include

SDFLAGS = -nostdlib -Wl,-T,armelf.xsc -Wl,-shared,-Bsymbolic -Wl,-soname,$@ -lc -L ../tutorial

CRT_OBJS= -lz -lm -ldl

all: libtest01.so

libtest01.so: test01.o

$(CC) $(SDFLAGS) -o $@ test01.o $(CRT_OBJS)

ok, make一下成功。好了,接下來使用andriod的sdk寫一個簡單的activity, testapp來測試其運行情況,以下是test01.java的代碼。

package com.example.test;

import android.app.Activity;

import android.widget.TextView;

import android.os.Bundle;

public class test01 extends Activity

{

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState)

{

super.onCreate(savedInstanceState);

/* Create a TextView and set its content.

* the text is retrieved by calling a native

* function.

*/

TextView tv = new TextView(this);

// tv.setText( stringFromJNI() );

Integer ll = getinformation();

String lls = ll.toString();

tv.setText(lls);

setContentView(tv);

}

/* A native method that is implemented by the

* 'hello-jni' native library, which is packaged

* with this application.

*/

public native int getinformation();

/* this is used to load the 'hello-jni' library on application

* startup. The library has already been unpacked into

* /data/data/com.example.HelloJni/lib/libhello-jni.so at

* installation time by the package manager.

*/

static {System.loadLibrary("test");

}

}

在eclipse中運行,在模擬器上顯示0,就表示成功了。
轉載

⑷ 在android中如何編譯連接 c 的可執行文件

1. 在./development目錄下創建一目錄 如:myhello
2. 進入hello目錄,在其下編寫自己的.c文件,如: myhello.c
#include <stdio.h>
int main()
{
printf("hello world\n");
exit(0);
//return 0;
}
3. 在hello目錄中,編寫Android.mk, 內容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myhelloworld
LOCAL_SRC_FILES := myhello.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
4. 回到Android源代碼頂層目錄,進行編譯,make myhelloworld
5. 生成的可執行文件位於:out/target/proct/lotus/system/bin/ 目錄下
6. adb push 到手機 /data 目錄下,然後進入adb shell,到data目錄下,執行./myhelloworld 皆可

手動編譯連接【arm-eabi-gcc 的目錄隨andorid的版本而有變化,還有就是需要鏈接的文件如果比較多時,需要很多-l 就很麻煩了】
7、編譯成目標文件:
#$(yourAndroid)/prebuilt/linux-x86/toolchain/[arm-eabi-4.2.1]/bin/arm-eabi-gcc -I bionic/libc/arch-arm/include/ -I bionic/libc/include -I bionic/libc/kernel/common -I bionic/libc/kernel/arch-arm -g -c helloworld.c -o hello.o
8、生成可執行代碼:
#$(yourAndroid)/prebuilt/linux-x86/toolchain/[arm-eabi-4.2.1]/bin/arm-eabi-gcc -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,noreloc -o helloworld -Lout/target/proct/[generic]/obj/lib -Wl,-rpath-link=out/target/proct/[generic]/obj/lib -lc hello.o -entry=main

其中[ ]中部分根據實際情況修改

**************************************************
實驗:
1. 建目錄(my Android)/development/test, 在該目錄下新建 Android.mk和fb_test.c文件

2. Android.mk文件

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myfbtest
LOCAL_SRC_FILES := fb_test.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

3. 以下為fb_test.c
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/kd.h>

#include <stdio.h>

#define FBBIT_PER_PIXEL 32
#define FBBIT_PIXEL_IMAGE 16
#define PIXELS_WIDTH_BYTE 4
#define BYTE_PER_PIXEL 3
#define FB_GRAPHICS_PATH "/dev/graphics/fb0"
#define DEV_TTY0_PATH "/dev/tty0"

#define DISPLAY_ERROR -1
#define DISPLAY_SUCCESS 0

#define GET_BATTERYCAPACITY_ERR -1

#define MAX_STR 255

static struct {
int fd;
void *pixels;
struct fb_fix_screeninfo fixed;
struct fb_var_screeninfo var;
int align_xres;
} fb;

int getBatteryCapacity(void)
{
FILE *in;
char tmpStr[MAX_STR + 1];
char capfile[] = "/sys/class/power_supply/battery/capacity";

if (capfile == NULL)
return GET_BATTERYCAPACITY_ERR;

in = fopen(capfile, "rt");
if (in == NULL)
return GET_BATTERYCAPACITY_ERR;

if (fgets(tmpStr, MAX_STR, in) == NULL) {
printf("Failed to read battery capacity!\n");
fclose(in);
return GET_BATTERYCAPACITY_ERR;

}

printf("Battery capacity(ascii): %s\n", tmpStr);
fclose(in);

return 0;//atoi(tmpStr);
}

static int vt_set_graphicsmode(int graphics)
{
int fd, r;
fd = open(DEV_TTY0_PATH, O_RDWR | O_SYNC);
if (fd < 0)
return DISPLAY_ERROR;
r = ioctl(fd, KDSETMODE, graphics);
close(fd);
return r;
}

int display_init(void)
{
fb.fd = open(FB_GRAPHICS_PATH, O_RDWR);
if (fb.fd < 0)
return DISPLAY_ERROR;

if (ioctl(fb.fd, FBIOGET_FSCREENINFO, &fb.fixed) < 0)
return DISPLAY_ERROR;
if (ioctl(fb.fd, FBIOGET_VSCREENINFO, &fb.var) < 0)
return DISPLAY_ERROR;
fb.align_xres = fb.fixed.line_length /
(fb.var.bits_per_pixel >> BYTE_PER_PIXEL);

fb.pixels = mmap(0, fb.fixed.line_length * fb.var.yres_virtual,
PROT_READ | PROT_WRITE, MAP_SHARED, fb.fd, 0);
if (fb.pixels == MAP_FAILED)
return DISPLAY_ERROR;

vt_set_graphicsmode(KD_GRAPHICS);

memset(fb.pixels, 0, fb.fixed.line_length * fb.var.yres_virtual);
//display_update(fb.pixels, fb.align_xres, fb.var.yres);
fb.var.activate = FB_ACTIVATE_FORCE;
ioctl(fb.fd, FBIOPUT_VSCREENINFO, &fb.var);

printf("display_init ok\n");

return DISPLAY_SUCCESS;
}

void display_on(void)
{
ioctl(fb.fd, FBIOBLANK, FB_BLANK_UNBLANK);
}

void display_off(void)
{
ioctl(fb.fd, FBIOBLANK, FB_BLANK_POWERDOWN);
}

int main()
{
display_init();
display_off();//關顯示屏

getBatteryCapacity();
sleep(5);

display_on();//開顯示屏

return 0;
}

⑸ 怎麼單獨編bootimge android

需要先找到toolchain,一般位置在你下載的源碼的android/prebuilt/***/toolchain目錄內。然後通過export配置toolchain的環境。配置完成後,進入boot_imx目錄,位置為android/bootable/bootloader/uboot-imx中,導入配置文件後,make一下就可以得到uboot了。然後不要改變toolchain的環境配置,再進入android/kernel_imx目錄,導入配置文件後,make uImage即可得到uImage。

⑹ 如何制定android交叉編譯工具鏈

經常搞嵌入式開發的朋友對於交叉編譯環境應該並不陌生,說白了,就是一組運行在x86 PC機的編譯工具,可以讓你在PC機上編譯出目標平台(例如ARM)可識別的二進制文件。Android平台也提供了這樣的交叉編譯工具鏈,就放在Android的NDK開發包的toolchains目錄下,因此,我們的Makefile文件中,只需給出相應的編譯工具即可。
廢話就先說到這,直接上例子,我們目標是把下面這個math.c文件編譯成一個靜態庫文件:
#include <stdio.h>
int add( int a , int b ) {
return a+b;
}
你需要編寫一個Makefile文件,這里假設你的Android ndk被安裝在 /opt/android/ndk 目錄下,當然,你可以根據自己的實際情況修改Makefile中相關路徑的定義,Makefile文件示例如下:
# Makefile Written by ticktick
# Show how to cross-compile c/c++ code for android platform
.PHONY: clean
NDKROOT=/opt/android/ndk
PLATFORM=$(NDKROOT)/platforms/android-14/arch-arm
CROSS_COMPILE=$(NDKROOT)/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/arm-linux-androideabi-
CC=$(CROSS_COMPILE)gcc
AR=$(CROSS_COMPILE)ar
LD=$(CROSS_COMPILE)ld
CFLAGS = -I$(PWD) -I$(PLATFORM)/usr/include -Wall -O2 -fPIC -DANDROID -DHAVE_PTHREAD -mfpu=neon -mfloat-abi=softfp
LDFLAGS =
TARGET = libmath.a
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
all: $(OBJS)
$(AR) -rc $(TARGET) $(OBJS)
clean:
rm -f *.o *.a *.so
這里不講Makefile文件的基本原理,只說明一下針對Android環境的Makefile文件編寫的注意事項。
(1) CROSS_COMPILE
必須正確給出Android NDK編譯工具鏈的路徑,當在目錄中執行make命令的時候,編譯系統會根據 CROSS_COMPILE 前綴尋找對應的編譯命令。
(2) -I$(PLATFORM)/usr/include
由於Android平台沒有使用傳統的c語言庫libc,而是自己編寫了一套更加高效更適合嵌入式平台的c語言庫,所以系統頭文件目錄不能再使用默認的路徑,必須直到Android平台的頭文件目錄
(3) -Wall -O2 -fPIC -DANDROID -DHAVE_PTHREAD -mfpu=neon -mfloat-abi=softfp
這些參數的意義網上基本上都有介紹,我就不一一解釋了,並不都是必須添加的,但比較常用。
編譯方法:
寫好makefile文件,並且保存之後,就可以直接在當前目錄下執行make命令,編譯完成後,當前目錄下會生成 libmath.a ,即可直接拿到Android的jni工程中和使用了。

⑺ 怎麼使用Android源碼編譯c模塊生成可執行文件

1. 在./development目錄下創建一目錄 如:myhello
2. 進入hello目錄,在其下編寫自己的.c文件,如: myhello.c
#include <stdio.h>
int main()
{
printf("hello world\n");
exit(0);
//return 0;
}
3. 在hello目錄中,編寫Android.mk, 內容如下:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myhelloworld
LOCAL_SRC_FILES := myhello.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
4. 回到Android源代碼頂層目錄,進行編譯,make myhelloworld
5. 生成的可執行文件位於:out/target/proct/lotus/system/bin/ 目錄下
6. adb push 到手機 /data 目錄下,然後進入adb shell,到data目錄下,執行./myhelloworld 皆可

手動編譯連接【arm-eabi-gcc 的目錄隨andorid的版本而有變化,還有就是需要鏈接的文件如果比較多時,需要很多-l 就很麻煩了】
7、編譯成目標文件:
#$(yourAndroid)/prebuilt/linux-x86/toolchain/[arm-eabi-4.2.1]/bin/arm-eabi-gcc -I bionic/libc/arch-arm/include/ -I bionic/libc/include -I bionic/libc/kernel/common -I bionic/libc/kernel/arch-arm -g -c helloworld.c -o hello.o
8、生成可執行代碼:
#$(yourAndroid)/prebuilt/linux-x86/toolchain/[arm-eabi-4.2.1]/bin/arm-eabi-gcc -nostdlib -Bdynamic -Wl,-T,build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,noreloc -o helloworld -Lout/target/proct/[generic]/obj/lib -Wl,-rpath-link=out/target/proct/[generic]/obj/lib -lc hello.o -entry=main

其中[ ]中部分根據實際情況修改

**************************************************
實驗:
1. 建目錄(my Android)/development/test, 在該目錄下新建 Android.mk和fb_test.c文件

2. Android.mk文件

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myfbtest
LOCAL_SRC_FILES := fb_test.c
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

3. 以下為fb_test.c
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <linux/kd.h>

#include <stdio.h>

#define FBBIT_PER_PIXEL 32
#define FBBIT_PIXEL_IMAGE 16
#define PIXELS_WIDTH_BYTE 4
#define BYTE_PER_PIXEL 3
#define FB_GRAPHICS_PATH "/dev/graphics/fb0"
#define DEV_TTY0_PATH "/dev/tty0"

#define DISPLAY_ERROR -1
#define DISPLAY_SUCCESS 0

#define GET_BATTERYCAPACITY_ERR -1

#define MAX_STR 255

static struct {
int fd;
void *pixels;
struct fb_fix_screeninfo fixed;
struct fb_var_screeninfo var;
int align_xres;
} fb;

int getBatteryCapacity(void)
{
FILE *in;
char tmpStr[MAX_STR + 1];
char capfile[] = "/sys/class/power_supply/battery/capacity";

if (capfile == NULL)
return GET_BATTERYCAPACITY_ERR;

in = fopen(capfile, "rt");
if (in == NULL)
return GET_BATTERYCAPACITY_ERR;

if (fgets(tmpStr, MAX_STR, in) == NULL) {
printf("Failed to read battery capacity!\n");
fclose(in);
return GET_BATTERYCAPACITY_ERR;

}

printf("Battery capacity(ascii): %s\n", tmpStr);
fclose(in);

return 0;//atoi(tmpStr);
}

static int vt_set_graphicsmode(int graphics)
{
int fd, r;
fd = open(DEV_TTY0_PATH, O_RDWR | O_SYNC);
if (fd < 0)
return DISPLAY_ERROR;
r = ioctl(fd, KDSETMODE, graphics);
close(fd);
return r;
}

int display_init(void)
{
fb.fd = open(FB_GRAPHICS_PATH, O_RDWR);
if (fb.fd < 0)
return DISPLAY_ERROR;

if (ioctl(fb.fd, FBIOGET_FSCREENINFO, &fb.fixed) < 0)
return DISPLAY_ERROR;
if (ioctl(fb.fd, FBIOGET_VSCREENINFO, &fb.var) < 0)
return DISPLAY_ERROR;
fb.align_xres = fb.fixed.line_length /
(fb.var.bits_per_pixel >> BYTE_PER_PIXEL);

fb.pixels = mmap(0, fb.fixed.line_length * fb.var.yres_virtual,
PROT_READ | PROT_WRITE, MAP_SHARED, fb.fd, 0);
if (fb.pixels == MAP_FAILED)
return DISPLAY_ERROR;

vt_set_graphicsmode(KD_GRAPHICS);

memset(fb.pixels, 0, fb.fixed.line_length * fb.var.yres_virtual);
//display_update(fb.pixels, fb.align_xres, fb.var.yres);
fb.var.activate = FB_ACTIVATE_FORCE;
ioctl(fb.fd, FBIOPUT_VSCREENINFO, &fb.var);

printf("display_init ok\n");

return DISPLAY_SUCCESS;
}

void display_on(void)
{
ioctl(fb.fd, FBIOBLANK, FB_BLANK_UNBLANK);
}

void display_off(void)
{
ioctl(fb.fd, FBIOBLANK, FB_BLANK_POWERDOWN);
}

int main()
{
display_init();
display_off();//關顯示屏

getBatteryCapacity();
sleep(5);

display_on();//開顯示屏

return 0;
}

⑻ android studio 2.2.2 32位怎麼配置ndk cmake環境

編譯mac靜態庫 這個比較簡單,直接Xcode -GXcode,然後用xcodebuild命令即可。 編譯Andoird靜態庫 編譯android庫我們同樣可以引入一個toolchain文件,這里我是從 android-cmake 裡面下載的。 在使用這個toolchain文件之前,我們先要使用ndk自帶的make-standalone-toolchain.sh腳本來生成對應平台的toolchain.這個腳本位於你的NDK的路徑下面的buil/tools目錄下。 比如要生成arm平台的toolchain,我們可以使用下列命令: sh $ ANDROID_NDK / build / tools / make - standalone - toolchain . sh -- platform = android - $ANDROID_API_LEVEL -- install - dir = . / android - toolchain -- system = darwin - x86_64 -- ndk - dir = /Users / guanghui / AndroidDev / android - ndk - r9d / -- toolchain = arm - linux - androideabi - 4.8 這里的$ANDROID_NDK為你的NDK的安裝路徑。這段命令可以生成arm的toolchain,最終可以編譯出armeabi和armeabi-v7a靜態庫。 如果想生成x86的toolchain,指需要使用下列命令: sh $ ANDROID_NDK / build / tools / make - standalone - toolchain . sh -- platform = android - $ANDROID_API_LEVEL -- install - dir = . / android - toolchain - x86 -- system = darwin - x86_64 -- ndk - dir= / Users / guanghui / AndroidDev / android - ndk - r9d / -- toolchain = x86 - 4.8 最後,我們要告訴CMake使用外部toolchain文件,可以使用參數-DCMAKE_TOOLCHAIN_FILE=xxx。此外,我們還需要在導出兩個環境變數給此toolchain文件: ...編譯mac靜態庫 這個比較簡單,直接Xcode -GXcode,然後用xcodebuild命令即可。 編譯Andoird靜態庫 編譯android庫我們同樣可以引入一個toolchain文件,這里我是從 android-cmake 裡面下載的。 在使用這個toolchain文件之前,我們先要使用ndk自帶的make-standalone-toolchain.sh腳本來生成對應平台的toolchain.這個腳本位於你的NDK的路徑下面的buil/tools目錄下。 比如要生成arm平台的toolchain,我們可以使用下列命令: sh $ ANDROID_NDK / build / tools / make - standalone - toolchain . sh -- platform = android - $ANDROID_API_LEVEL -- install - dir = . / android - toolchain -- system = darwin - x86_64 -- ndk - dir = /Users / guanghui / AndroidDev / android - ndk - r9d / -- toolchain = arm - linux - androideabi - 4.8 這里的$ANDROID_NDK為你的NDK的安裝路徑。這段命令可以生成arm的toolchain,最終可以編譯出armeabi和armeabi-v7a靜態庫。 如果想生成x86的toolchain,指需要使用下列命令: sh $ ANDROID_NDK / build / tools / make - standalone - toolchain . sh -- platform = android - $ANDROID_API_LEVEL -- install - dir = . / android - toolchain - x86 -- system = darwin - x86_64 -- ndk - dir= / Users / guanghui / AndroidDev / android - ndk - r9d / -- toolchain = x86 - 4.8 最後,我們要告訴CMake使用外部toolchain文件,可以使用參數-DCMAKE_TOOLCHAIN_FILE=xxx。此外,我們還需要在導出兩個環境變數給此toolchain文件: export PATH = $ PATH : . / android - toolchain / bin export ANDROID_STANDALONE_TOOLCHAIN = . / android - toolchain cmake - DCMAKE_TOOLCHAIN_FILE = . . / android . toolchain . cmake - DANDROID_ABI = "armeabi" . .收起

⑼ 不同的android有不同的toolchain么

搞清楚一點就好。toochain是干什麼的?
是為了在與目標機不同的環境下編譯出能在目標機上執行的代碼。
比如說在x86機器的linux下編譯能跑在arm上的android的內核,那麼只要找到一個linux-86 -arm的toochain就可以。這個也可以用android源碼自帶的toolchain。理由是因為內核並不需要用到bionic。
如果編譯android,那就要用android自帶的toolchain,因為如斑竹所說,android用的c庫是bionic而不是標準的libc,而且載入庫使用的/system/bin/linker而不是常用的/lib/ld.so; 因此用其他的toolchain則只能編譯成靜態的才能跑。當然如果能夠製作出兼容bionic的toolchain出來理論上也是能用的,不過沒看到過成功的例子。
說錯的地方請拍磚。

閱讀全文

與toolchainandroid相關的資料

熱點內容
python單實例化 瀏覽:349
str中python 瀏覽:89
java的equals用法 瀏覽:845
奧維雲伺服器怎麼開通 瀏覽:171
js取得伺服器地址 瀏覽:812
起點中文網小說緩存在哪個文件夾 瀏覽:216
java瘋狂講義pdf 瀏覽:299
推有錢app在哪裡 瀏覽:744
寧波鮑斯壓縮機 瀏覽:93
新建文件夾電影2完整版演員表 瀏覽:988
空調壓縮機為什麼不能放到冷庫用 瀏覽:89
江西雲伺服器節點虛擬主機 瀏覽:997
新氧app如何測試臉型 瀏覽:688
個稅app如何查詢社保 瀏覽:495
安卓設備快充什麼時候開啟的 瀏覽:13
ipad怎麼用安卓手機傳文件 瀏覽:584
編輯程序員視頻 瀏覽:634
極光app的雲助手在哪裡 瀏覽:777
信合有什麼ApP 瀏覽:958
android絕對位置 瀏覽:79