2013年7月21日 星期日

system call for arm platform (2)

from
[1]
http://opencsl.openfoundry.org/Lab06_interrupt_exception.rst.html
[2]
http://blog.csdn.net/wavemcu/article/details/8577058 
[3]
http://blog.xuite.net/ian11832/blogg/29210698-%E5%9C%A8+linux+%E4%B8%AD%E6%96%B0%E5%A2%9E%E8%87%AA%E5%B7%B1%E7%9A%84system+call+%28%E5%AF%A6%E5%81%9A%E5%9C%A8ARM+%E5%B9%B3%E5%8F%B0%E4%B8%8A%29
[4]
http://blog.csdn.net/adaptiver/article/details/7175165

3.1 system call 的撰寫方法

要新增 system call 除了撰寫程式本身之外,還需要向 Linux 註冊讓 kernel 知道它的存在 ,這樣 user program 才能夠透過 kernel 呼叫 system call。
註冊 system call 的步驟如下:
  1. 註冊 system call 的名字
  2. 定義新 system call 的代碼
  3. 調整 Makefile ,使 systam call 被包含在 kernel 中
  4. 增加 system call 的 header file ,讓 user program 能夠 include
另外在撰寫 system call 程式方面,因為程式是在 kernel space 執行, user program 和 system call 所使用的記憶體位置是無法直接互通的,所使用的函式也和一般的 user program 不同,使用上也必須特別小心,像是
  • 使用 printk 而不是 print
  • 使用 kmalloc、kfree 而不是 malloc、free

3.2 加入自己的 system call

在本節中,我們將透過 3.1 所敘述的步驟自己在系統中新增一個 system call ,這個 system call 將會顯示開機後它總共被呼叫了幾次。
  1. 撰寫 system call 的程式
    system call 的程式是放在 <linux>/arch/arm/kernel 中,檔名即為 system call 的名字。
    用編輯器打開 mysyscall.c 後,將以下內容複製進去:
    #include <linux/linkage.h>   // asmlinkage
    #include <linux/kernel.h>   // linux/printk.h
    #include <linux/types.h>   // atomic_t
    #include <linux/atomic.h>   // atomic_inc()
     
    asmlinkage void sys_mysyscall(void)
    {
       static atomic_t count = ATOMIC_INIT(0);
    
       atomic_inc(&count);
       printk("mysyscall has been called for %d time(s)\n", count);
    }
    
  2. header檔linux/kernel.h引用linux/printk.h中包含了printk的log層級:
    #define KERN_EMERG    "<0>"    /* system is unusable */
    #define KERN_ALERT    "<1>"    /* action must be taken immediately */
    #define KERN_CRIT     "<2>"    /* critical conditions */
    #define KERN_ERR      "<3>"    /* error conditions */
    #define KERN_WARNING  "<4>"    /* warning conditions */
    #define KERN_NOTICE   "<5>"    /* normal but significant */
    #define KERN_INFO     "<6>"    /* informational */
    #define KERN_DEBUG    "<7>"    /* debug-level messages */
    
    所以 printk() 可以這樣用:printk(KERN_INFO "Hello, world!\n");。
    log層級太低訊息只會顯示在dmesg指令執行時,在commandline不會顯示任何訊息
  3. 註冊 system call 的名字
    <linux>/arch/arm/kernel/call.S 定義了系統中 system call 的名字,我們要將新的 system call 紀錄在這個檔案中。請用編輯器打開 call.S 之後,找到目前的最後一個 system call,
    CALL(sys_get_mempolicy)
    CALL(sys_set_mempolicy)
    
    然後在後面加上
    CALL(sys_mysyscall)
    
    再存檔即可。
  4. 定義新 system call 的代碼
    <linux>/include/asm-arm/unistd.h 定義了系統中 system call 的代碼,我們也需要在這裡定義新的 system call 代碼。請用編輯器打開 unistd.h 後,找到目前的最後一個 system call(大約在350行),
    #define __NR_get_mempolicy              (__NR_SYSCALL_BASE+320)
    #define __NR_set_mempolicy              (__NR_SYSCALL_BASE+321)
    
    然後在後面加上
    #define __NR_mysyscall                  (__NR_SYSCALL_BASE+322)
    
  5. 調整 Makefile ,使 systam call 被包含在 kernel 中
    <linux>/arch/arm/kernel/Makefile 是該目錄的 makefile ,我們要將 mysyscall.c 加入編譯的範圍內。在檔案一開頭可以找到需要編譯的 object file 列表,
    obj-y := compat.o entry-armv.o .....
    
在此行的後面加上 mysyscall.o 即可。
  1. 增加 system call 的 header file ,讓 user program 能夠 include
    接著,我們要將 mysyscall 的 header 加入 linux 的 header 目錄中,它的位置是 <linux>/include/linux ,在該目錄裡新增 mysyscall.h 的檔案,並填入以下內容:
    #include <linux/unistd.h>
    
    #define __NR_mysyscall         (__NR_SYSCALL_BASE+322)
    #define mysyscall(void)        syscall(__NR_mysyscall);
    
    再存檔即可。
  2. 重新編譯 kernel
    最後,回到 <linux> 並鍵入
    make CROSS_COMPILE=arm-linux-uclibc- ARCH=arm
    
    重新編譯 kernel 後,就會產生新的 kernel image 了。

3.3 用 QEMU 測試

為了測試 system call 是否有成功加到 kernel 中,我們可以先用 QEMU 載入新的 kernel image ,並另外寫一個 user program 來呼叫 mysyscall 。
  1. 撰寫 user program
    若要呼叫 mysyscall ,要在程式中 include linux/mysyscall.h 。以下為使用 mysyscall 的範例:
    #include "linux/mysyscall.h"
    
    int main(){
    
       mysyscall();
    
       return 0;
    }
    
  2. 編譯程式
在寫好程式之後,我們可以用之前做好的 cross-compiler 來編譯程式,不過要注意的一點是,因為程式的內容牽涉到 kernel 的資訊( system call 是包含在 kernel 中的 ),因此我們也需要加入 kernel 的 include 檔。
假設要編譯的程式檔名為 test.c ,而要生成的執行檔為 test.out ,則在終端機下鍵入:
arm-linux-uclibc-gcc -I<linux>/include/ -static test.c -o test.out
即可。

2013年7月19日 星期五

system call for arm platform (1)

android的external/kernel-headers/original目錄
from:
https://github.com/billwangwl/android_linux_stuff/blob/master/android_bionic_kernel-headers-original_explanation_zh_CN.html

external folder中linux kernel header的作用

在Linux中,有一个external/kernel-headers/original,这个文件夹中有很多linux的头文件,与kernel/include/linux有很多重复的文件。

 1、Android external folder

  External refers to external open source libraries. That means libraries that the Android platform depend upon but that are not primarily developed and maintained by the Android open source project. Typical examples are webkit for the browser, FreeType for fonts, SqlLite for databases and so on. As more features are added to Android, more of these libraries are included in external.

 external folder是外部的open source lib,这些lib是android依赖的,但是主要的开发和维护又不是android来做

 http://stackoverflow.com/questions/10477565/android-external-folder-functionality

  2,external/kernel-headers/original 

 (external/kernel-headers/original/README.TXT)

 这个文件夹里的头文件是Bionic来用生成一个干净的user-land(user space)头文件。基于GPL2+。  

3、Bionic

 Bionic libc是BSD standard C library发展而来,最早是Google为Android开发。作用主要有三个: 

a) BSD license: 通过BSD license,Android程序就和GPL分隔开来。

b) Bionic比GNU C Library要小的多。

c) Bionic的速度更快。

 Bionic也缺少很多完整的libc的特性,比如宽字符和C++的异常处理。一些函数也没有实现。 

(http://discuz-android.blogspot.com/2008/10/google-android-native-libc-bionic.html

HAL层,以及除了kernel以外的任意用到的C头文件,都是bionic中的。

 ./core/pathmap.mk,pathmap_INCL := libc:bionic/libc/include (http://www.linuxidc.com/Linux/2011-03/33672.htm

Android编译环境所用的交叉编译工具链是prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin /arm-eabi-gcc,-I和-L参数指定了所用的C库头文件和动态库文件路径分别是bionic/libc/include和out /target/product/generic/obj/lib

 (http://www.360doc.com/content/09/0624/17/36491_4018938.shtml )

 kernel中用的头文件在kernel/include中。user space用的头文件在bionic下。

 4,Bionic kernel header 

 (bionic/libc/kernel/README.TXT)

 Bionic有一套干净的Linux头文件,这些头文件是通过bionic/libc/kernel/tools解析一份原始的,没有修改过的linux头文件生成的,这份头文件就在external/kernel-headers/original

干净的头文件只包括类型和宏定义,不过处于效率的考虑,不会生成一些静态内联函数。 

这些生成的头文件可以用于编译C++,C,也能够按照ANSI模式编译(linux kernel中用到了大量GNU扩展)。

生成头文件的过程是:

 *external/kernel-headers/original 包含通常linux kernel source tree中的include目录。这里仅仅只应该包含android依赖的kernel头文件。

 *bionic/libc/kernel/common 包含平台无关的头文件。 

from:

 http://blog.csdn.net/muge0913/article/details/7518568

 About sys_ni_syscall in Kernel System Call Table

不是所有的系统调用都有实际内容,如sys_ni_syscll在kernel/sys_ni.c中定义:
asmlinkage long sys_ni_syscall(void)
{
    return -ENOSYS;
}

你会发现在sys_call_table中sys_ni_syscall占据了很多内容,其实它代表着已被淘汰的系统调用。其实只要是被内核淘汰的系统调用都会被sys_ni_systcall代替。之所以这样是为了老的程序在新的内核上运行时不至于出现大的问题。如不应调用这个系统调用却调用了那个系统调用了。

from:

http://bbs.csdn.net/topics/350141651

cond_syscall

#ifndef cond_syscall  
     #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall")
#endif

告诉编译器,当在符号表中没有x时,就用sys_ni_syscall这个符号来代替。这样的话,一些在特殊系统中没有定义出的系统调用的函数,就被默认为是sys_ni_syscall了。

2013年7月9日 星期二

ubuntu super user

因為android下envsetup.sh中的mm指令權限不足無法編譯,
而直接下"sudo mm"又無法正確識別為mm指令,
只好成為root帳號來下指令。
要成為root要打指令"su  -",
可是在ubuntu下,一般操作都以sudo指令代替直接以root帳號執行指令,
因此不知道root密碼為何,無法進入root 帳號,
可以用"sudo passwd"修改root密碼再行登入。

2013年7月2日 星期二

oprofile

  • Oprofile 包含在 Linux 2.5 和更高版本的内核中
編譯kernel:
General setup
            Kernel Performance Events And Counters     --->
                          -> Kernel performance events and counters   # CONFIG_PERF_EVENTS
            -> Profiling support  [*]                             # CONFIG_PROFILING
            -> OProfile system profiling  <*>            # CONFIG_OPROFILE
Kernel Features
            -> Enable hardware performance counter support for perf events [*]
            # CONFIG_HW_PERF_EVENTS

在menuconfig模式中,可以用"shift + ?"查詢.config與make menuconfig所設定的對應關係,也可以用"/"查詢.config的選項名稱。

opcontrol  --setup

oprofiled  --session-dir=/data/oprofile  --vmlinux=/vmlinux   \

--kernel-range=c00xxxxx,c0xxxxxx  --events=CPU_CYCLES:255:0:10000:1:1:1   \

--separate-lib=1  --separate-kernel=1


opcontrol  --setup  --vmlinux=/vmlinux  -kernel-range=c00xxxxx,c0xxxxxx    \

--event=CPU_CYCLES:10000:1:1:1

opcontrol --timer


2013年6月25日 星期二

可以動且對開發有幫助的apk

百度一鍵Root.apk:
取得該死的root權限。
Root Explorer.apk:
在圖形介面重新得到"ls"的權利。
AndroidTerm.apk:
可以用。至少比看起來能動的好多了。




2013年6月13日 星期四

ADB: error: insufficient permissions for device

$ sudo adb shell
insufficient permissions for device

$ sudo adb devices
List of devices attached:
??????????????                      no permission


之前有用adb連接user版的android與eng版的android系統,導致這個問題。

解決方法:

$ adb kill-server
$ adb start

link supervision timeout

http://blog.csdn.net/evilcode/article/details/5717527

2013年5月30日 星期四

關於bluetooth active connection

How many ACTIVE bluetooth connections can the iPhone 4 support at one time?

       Am wondering just how many ACTIVE connections my iPhone 4 can support at one time?  I've got my iPhone paired via bluetooth to my car radio...alllowing to answer calls handsfree, as well as listen to my music through the radio.  I'm thinking about purchasing the iPhone radar detector, made by Cobra, which will also utilize a live bluetooth connection.  Is iPhone limited to only one live connection at a time, or can I have more?


Pretty sure bluetooth protocol itself is limited to one active connection by design.  So not a limitation of iPhone but the protocol.

2013年5月28日 星期二

關於 android envsetup.sh的使用注意事項

envsetup.sh用來協助設定android的編譯環境。使用該script一定要在android/目錄之下:

user:productXXX/android$  source build/envsetup.sh
( 列出類似以下訊息代表envsetup.sh執行成功,否則失敗)
including  device/magiclab/xxx/vendorsetup.sh
including  device/magiclab/yyy/vendorsetup.sh
  ...
user:productXXX/androidlunch
(如果不在android/目錄下執行lunch指令,在選擇編譯設定後,會出現"Couldn't locate the top of the tree. Try setting Top."錯誤)
        1.  full-eng
        2.  full_x86-eng
        ...

2013年5月20日 星期一

telnet tera term設定

1.Windows XP端先安裝adb usb driver,adb driver需要
   root權限,android要編譯成engineer版。

2.連接Windows XP端至android tablet,並且正確辨識。
   1.第一次插入USB線時顯示提示"新硬體安裝時出現問題",
     拔出USB線再插一次未出現提示,就可以使用了,不解...

   2.第一次插入USB線時顯示提示"新硬體安裝時出現問題",
     到裝置管理員,選擇MTP右鍵"更新驅動程式",選擇"從
     清單或特定位置安裝" > "不要搜尋,我將選擇要安裝的
     驅動程式,選擇Android Adb interface安裝。也可以解決
     問題。

3.在system/core/rootdir/init.rc中加入telnet開機啟動
   service telnetd /system/xbin/telnetd  -l  /system/bin/sh
           class core
           oneshot


4.執行cmd到adb的目錄中執行adb  forward  tcp:65432  tcp:23

5.執行tera term,Host=127.0.0.1 ,  Service:telnet,  tcp  port# 23
   然後按"OK"。

2013年5月8日 星期三

Ubuntu gnome與terminal混用小小發現


指令:
gnome-open [directory]
用途:
可以直接在terminal模式下以圖形介面資料夾打開路徑為[directory]的資料夾

指令:
gnome-search-tool --start --named=[搜尋的字串]
用途:
可以在圖形介面直接搜尋[搜尋的字串]的檔案

2013年5月7日 星期二

安裝PyBluez

[Unbuntu]
1.先裝bluez
sudo  apt-get  install  bluez
2.裝python
sudo  apt-get  install  python
3.裝python開發套件  python-dev :不然編譯會出現"Python.h : no such file or directory
sudo  apt-get  install  python-dev
4.裝Bluez開發函式庫  libbluetooth-dev :不然編譯會出現"bluez/btmodule.h.h: fatal error: bluetooth/bluetooth.h: No such file or directory,另外,gcc編譯時-lbluetooth也需要該函式庫
sudo  apt-get  install  libbluetooth-dev
5.裝PyBluez
python setup.py install


[Windows]
1.裝PyBluez: 有對應windows平台的python .msi安裝檔可以下載使用 
2.python-dev已經整合在.msi安裝檔裡面
    "The concept of "python-dev package" is a Debian concept which doesn't
        apply to Windows. The standard installation on Windows provides the
        header and library files that you need for interfacing with C.

        Don't put things where your C compiler can find them; do a standard
        no-frills install of Python2.4 using the .msi installer and tell your C
        compiler where the goodies are.

        E.g. using the MinGW32 gcc, you'd need things like:

        gcc -I\python24\include -lpython24 -L\python24\libs
        [first is "i".upper(), second is "L".lower()]


 

2013年5月2日 星期四

sdptool browse local

sdptool browse local可以查詢本地bluetooth支援的服務


sdptool browse local   (O)
sdptool browse hci0    (X) Failed to connect to SDP server on 00:00:00:00:00:00: Host is down
sdptool browse [hci0 bd addr]   (X) Failed to connect to SDP server on [hci0 bd addr]: No route to host

sdptool get hci0和sdptool get local倒是可以通用。

am start

http://stackoverflow.com/questions/5494764/how-to-run-a-specific-android-app-using-terminal

android activity啟動

2013年4月28日 星期日

association models

bluetooth的安全驗證機制稱為Secure Simple Pairing。
主要是探討pairing過程的各種驗證機制。
association models是pairing驗證模式的通稱,描述bluetooth連線驗證方面的專有名詞(spec定義的)。
應用範圍為authentication和security



2013年4月24日 星期三

apk

http://tieba.baidu.com/p/1267596506
摘要:
android中的apk檔是一個zip壓縮檔,可以用解壓縮軟體解開。

http://zeaster.blogspot.tw/2007/11/how-to-decompile-dex-file-on-android_28.html
http://www.imobilebbs.com/wordpress/archives/1026
摘要:
class.dex  為 Java編譯成Dalvik 代碼(非Java code)。
.apk 打包後的 所以.xml 文件格式為binary XML 文件格式,可以使用AXMLPrinter2.jar
將二進位XML轉迴文本格式:
java -jar AXMLPrinter2.jar AndroidManifest.xml > AndroidManifest.xml.txt

 http://jinnsblog.blogspot.com/2011/10/how-to-use-sdk-to-install-apk.html
http://givemepass.blogspot.tw/2011/11/adb.html
摘要:
安裝格式:「adb install path/file
預設會安裝在/system/app/ 底下(我的是/factory)

/sdcard/music = 音樂目錄
/sdcard/Download = 下載檔案的預設目錄 

 http://fecbob.pixnet.net/blog/post/35840955-%E5%8F%B2%E4%B8%8A%E6%9C%80%E5%BC%B7android%E5%8F%8D%E7%B7%A8%E8%AD%AF%E5%B7%A5%E5%85%B7%E7%B6%A0%E8%89%B2%E7%89%88v2.0%EF%BC%88%E6%94%B9%E9%80%B2%E7%89%88
 摘要:
android apk反編譯軟體apktool

Android Bluetooth

07.Android之Bluetooth 

http://blog.csdn.net/jjunjoe/article/details/6928913

2013年4月22日 星期一

bluetooth rfcomm

http://www.piaccess.com/trac/wiki/Linux_BlueZ_Bluetooth_Serial_Setup
http://blog.mcuol.com/User/kynot/Article/7049_1.htm
 About rfcomm arugement "channel"
 http://ubuntuforums.org/showthread.php?t=200142

rfcomm  usage:
rfcomm <command> <Bluetooth Device> <BD Address> < Channel>

# rfcomm bind hci0 00:07:A4:D2:03:67 1
#ls -l /dev/rfcomm0
crw------- root root  <time>  rfcomm0
# hcitool cc 00:07:A4:D2:03:67 

2013年4月9日 星期二

2013年4月8日 星期一

extern struct

http://stackoverflow.com/questions/3266580/extern-struct

I'm using extern to fetch variables from another class, and it works fine for int's, float's etc...
But this doesn't work, and I don't know how to do it:

Class1.cpp
struct MyStruct {
 int x;
}

MyStruct theVar;
 
Class2.cpp
extern MyStruct theVar;

void test() {
 int t = theVar.x;
}
 
It doesn't work because Class2 doesn't know what MyStruct is.
How do I fix this? :/
I tried declaring the same struct in Class2.cpp, and it compiled, but the values were wrong.


7 down vote accepted
You put the struct MyStruct type declaration in a .h file and include it in both class1.cpp and class2.cpp.
IOW:
Myst.h
struct MyStruct {
 int x;
};
 
Class1.cpp
#include "Myst.h"

MyStruct theVar;
 
Class2.cpp
#include "Myst.h"

extern struct MyStruct theVar;

void test() {
 int t = theVar.x;
}

gcc -ldl

-ldl 指示连接器连接一个库。这个库里包含了 dlopen, dlsym 等等的函数。也就是说,是支持“在运行时,显示加载使用动态连接库”的函数库。相关的头文件是 dlfcn.h

2013年4月7日 星期日

gcc引用非標準函式庫(gcc -l -L)

gcc引用非標準函式庫要求正確的引用順序
格式:
gcc [source code: .c, .o, .a] [ -l | -L ]
Example:
gcc sin.c -lm -L/usr/lib -I/usr/include
 
 
Try:
gcc $(CFLAGS) -o xxx xxx.o ../../dbus/libdbus.a  = O OK 
gcc $(CFLAGS) -ldbus -L../../dbus -o xxx xxx.o  = X FAIL
gcc $(CFLAGS) -ldbus -L../../dbus -o xxx xxx.o  = X FAIL
gcc $(CFLAGS) -o xxx xxx.o -ldbus -L../../dbus  = O OK 
gcc $(CFLAGS) -o xxx xxx.o -L../../dbus  = X FAIL
gcc $(CFLAGS) -o xxx xxx.o -L../../dbus -ldbus  = O OK  

gcc -I、:=與#include

http://www.rapidtables.com/code/linux/gcc/gcc-i.htm

gcc -I option flag

gcc -I adds include directory of header files.
Syntax
$ gcc -Idir [options] [source files] [object files] [-o output file]
Example
proj/src/myheader.h:

// myfile.h
#define NUM1 5



myfile.c:

// myfile.c
#include
#include "myheader.h"

void main()
{
int num = NUM1;
printf("num=%d\n", num);
}



Build myfile.c without include directory proj/src :

$ gcc myfile.c -o myfile
myfile.c:2:22: fatal error: myheader.h: No such file or directory
compilation terminated.
$



Build myfile.c with include directory proj/src :

$ gcc -Iproj/src myfile.c -o myfile
$ ./myfile
num=5
$


這個方法是可行的,之前的編譯include路徑無效問題出現在
GCC=gcc
LIBFLAGS:=$(CFLAGS) -c
CFLAGS:= -Dxxx -Wall -g -I...
LIBFLAGS使用當下的選項,CFLAGS為空值,從下make指令後可看出。
應該改為:
GCC=gcc
LIBFLAGS=$(CFLAGS) -c
CFLAGS:= -Dxxx -Wall -g -I...

2013年4月3日 星期三

linker input file unused because linking not done

gcc -c

正當我被GCC "undefined reference"搞得死去活來時...

(1)
拜讀了這篇精闢的解說....
http://ticktick.blog.51cto.com/823160/431329
(2)
undefined reference還是除不完
發現undefined reference to android_atomic_release_cas

extern inline int android_atomic_release_cas(int32_t old_value,
int32_t new_value,
volatile int32_t *ptr)
{
android_memory_barrier();
return android_atomic_cas(old_value, new_value, ptr);
}

改用g++編譯。
(3)
g++編譯錯誤, invalid conversion from...
解决方法:CXXFLAGS = -fpermissive

2013年4月2日 星期二

Android Makefile

http://huenlil.pixnet.net/blog/post/23801824-%5B%E8%BD%89%5Dandroid-jni%E5%AF%A6%E4%BE%8B
http://3sec.kilab.tw/?p=244

GCC #error

#error 強迫compiler停止compile,主要是用來除錯用的。與ifdef並用,可以讓程式在某些define
錯誤狀況下中止

語法是
#error 錯誤訊息

當程式遇到#error,錯誤訊息會在console端顯示出來,一般會和其他compiler所定義的訊息
一起顯示出來。

找不到struct ucred

http://linux.die.net/man/7/unix
Ancillary Messages

SCM_CREDENTIALS
Send or receive UNIX credentials. This can be used for authentication. The credentials are passed as a struct ucred ancillary
message. Thus structure is defined in as follows:

struct ucred {
pid_t pid; /* process ID of the sending process */
uid_t uid; /* user ID of the sending process */
gid_t gid; /* group ID of the sending process */
};

Since glibc 2.8, the _GNU_SOURCE feature test macro must be defined (before including any header files) in order to obtain the
definition of this structure.
The credentials which the sender specifies are checked by the kernel. A process with effective user ID 0 is allowed to specify values
that do not match its own. The sender must specify its own process ID (unless it has the capability CAP_SYS_ADMIN), its user
ID, effective user ID, or saved set-user-ID (unless it has CAP_SETUID), and its group ID, effective group ID, or saved
set-group-ID (unless it has CAP_SETGID). To receive a struct ucred message the SO_PASSCRED option must be enabled on the socket.

2013年3月31日 星期日

學習Makefile(1)

http://tetralet.luna.com.tw/?op=ViewArticle&articleId=185 問題:(timing of interpreting symobol)
"注意到,make 會將整個 Makefile 展開後,再決定變數的值。也就是說,變數的值將會是整個 Mackfile 中最後被指定的值。例:

x = foo
y = $(x) bar
x = xyz
# y 的值為 xyz bar

在上例中,y 的值將會是 xyz bar,而不是 foo bar。"

對策:
"您可以利用 := 來避開這個問題。:= 表示變數的值決定於它在 Makefile 中的位置,而不是整個 Makefile 展開後最終的值。

x := foo
y := $(x) bar
x := xyz
# y 的值為 foo bar

在上例中,y 的值將會是 foo bar,而不是 xyz bar 了。"

參考:
http://lxr.linux.no/#linux+v3.8.5/scripts/Makefile.build

...
PHONY := __build
__build:

# Init all relevant variables used in kbuild files so
# 1) they have correct type
# 2) they do not inherit any value from the environment
obj-y :=
obj-m :=
lib-y :=
lib-m :=
always :=
...

2013年2月20日 星期三

blogger Code排版

原始碼排版網站
http://tools.devshed.com/?option=com_mechtools&tool=25
http://quickhighlighter.com/

看 GCC 預設幫使用者加了什麼東西

看 GCC 預設幫使用者加了什麼東西

http://www.study-area.org/cyril/opentools/opentools/x869.html

gcc怎麼知道去哪裡找foo.c裡面所include的header檔,連結資料庫 與系統定義呢? 總共有下列來源指定gcc去那找。

  1. 當初在編譯時指定的(在~gcc/gcc/collect2.c:locatelib()
  2. 寫在specs內的
  3. 後來用-D -I -L指定的
  4. gcc環境變數設定(編譯的時候)
  5. ld.so的環境變數(這是run time的時候)

 

 

  1. $ echo 'main(){printf("hello world\n");}' | gcc -E -v -
文字介面顯示:
  1. Using built-in specs.
  2. Target: i486-linux-gnu
  3. Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr
  4. --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
  5. --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit
  6. --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --enable-checking=release i486-linux-gnu
  7. Thread model: posix
  8. gcc version 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)
  9.  /usr/lib/gcc/i486-linux-gnu/4.1.3/cc1 -E -quiet -v - -mtune=generic
  10. ignoring nonexistent directory "/usr/local/include/i486-linux-gnu"
  11. ignoring nonexistent directory "/usr/lib/gcc/i486-linux-gnu/4.1.3/../../../../i486-linux-gnu/include"
  12. ignoring nonexistent directory "/usr/include/i486-linux-gnu"
  13. #include "..." search starts here:
  14. #include <...> search starts here:
  15.  /usr/local/include
  16.  /usr/lib/gcc/i486-linux-gnu/4.1.3/include
  17.  /usr/include
  18. End of search list.
  19. # 1 "<stdin>"
  20. # 1 "<built-in>"
  21. # 1 "<command line>"
  22. # 1 "<stdin>"
  23. main(){printf("hello world\n");}
用途: 查看reference的include檔 可以用來展開經過preprocessor處理過後的#define函式