小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Makefile加入編譯選項(xiàng)

 WUCANADA 2012-04-18
Makefile加入編譯選項(xiàng)
2012-02-15 10:44

概述:
    通過Makefile傳遞宏參數(shù)進(jìn)行挑揀編譯,是編程中常用的技術(shù)。
    Windows我不會,也不想會。這里只談 Linux/GNU系統(tǒng)。
    在Linux平臺下,編程大體分為兩種,內(nèi)核態(tài)編程和用戶空間編程。對于內(nèi)核態(tài)編程,對于大多數(shù)人而言,
都是采用內(nèi)核模塊的方式,將自己的代碼加入到內(nèi)核之中。用戶空間的編程就多種多樣了。
    但是無論是在那種context下編程,我們使用的基本上都是GNU的工具:Make,Gcc,LD等。而且無論代碼要在那種context運(yùn)行,都需要 經(jīng)過預(yù)處理,編譯,連接,代碼優(yōu)化等過程。在這個(gè)過程之中,這里討論的只適用于預(yù)處理階段,也就是說選擇性的進(jìn)行編譯。
    由于在內(nèi)核態(tài),通過kernel module的方式進(jìn)行編譯的時(shí)候,程序員主要是借助于Linux kernel KBuild編譯系統(tǒng);然而,在用戶空間編程的時(shí)候,所有的工作都需要我們自己來作,所以兩者之間存在不同。

一. 用戶空間
     因?yàn)閷?shí)際上進(jìn)行預(yù)處理的只是Gcc工具,而make工具只是一個(gè)解決依賴關(guān)系的工具。所以問題就簡化成如何通過make向gcc傳遞參數(shù)。
     通過簡單的例子來說明:
hello.c

 

#include <stdio.h>


void main(void) {
#ifdef DEBUG
     printf("you ask for debug!\n");
#endif
     printf("we must say goodbye\n");
     return;
}
Makefile:


ifeq ($(DEBUG),y)
CFLAGS := $(CFLAGS) -DDEBUG
endif


hello: hello.c
$(CC) $(CFLAGS) $< -o $@
執(zhí)行過程:


[ville@localhost test]$ ls
hello.c Makefile
[ville@localhost test]$ make
cc hello.c -o hello
[ville@localhost test]$ ./hello
we must say goodbye
[ville@localhost test]$ rm hello
[ville@localhost test]$ ls
hello.c Makefile
[ville@localhost test]$ make DEBUG:=y
cc -DDEBUG hello.c -o hello
[ville@localhost test]$ ./hello
you ask for debug!
we must say goodbye
[ville@localhost test]$
通過以上的簡單例子說明如何通過宏開關(guān)進(jìn)行條件編譯。

二. 在內(nèi)核空間的module形式
    KBuild是Linux Kernel的編譯系統(tǒng),但是最終實(shí)際執(zhí)行編譯連接的還是GNU GCC LD。雖然我們是程序員,但是在KBuild的問題上,我們已經(jīng)成為了軟件的使用者。對于用戶而言,我們應(yīng)當(dāng)更多關(guān)注功能,會使用是最終目的,當(dāng)然如果有 時(shí)間學(xué)習(xí)一下KBuild也是十分有意義的!
    有問題,看文檔!Linux Kernel一向以文檔不全不規(guī)范而聞名世界,但是這個(gè)KBuild的文檔還是有的,


linuxXXXXX/Documentation/kbuild 目錄下:

 

00-INDEX

kbuild.txt

kconfig-language.txt

kconfig.txt

makefiles.txt

modules.txt
有空還是要看看的?。?!
      在makefile.txt 第284行,---3.7 Complilation Flags一節(jié)中有說明。
     以前都是使用EXTRA_XFLAGS,現(xiàn)在還是支持,但是建議使用xxflags-y這些內(nèi)置變量了。
    ccflags-y:$(CC)的編譯選項(xiàng)添加這里,宏開關(guān)也在這里添加
    asflags-y:as匯編器使用的
    ldflags-y :ld鏈接器使用的

還是用一個(gè)例子來演示:

ville.c :


/**
* Author : ville lee
* Create Time : 2010/07/31
* Description : This module implements a virtual file system.
* Aimming at learning the theory of Linux VFS.
*
* Change Log :
* version author Date Log
*
*
*
* */


#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>

 

 


/**
* init function of the module
*
* */
static int __init
ville_init(void)
{
#ifdef DEBUG
     /* we give the debug message like: module name : function name : debug message */
     printk(KERN_ALERT "ville :ville_init: you ask for debug!\n");
#endif
     printk(KERN_ALERT "ville :ville_init: ville module init!\n");
     return 0;
}


static void __exit
ville_exit(void)
{
#ifdef DEBUG
     /* we give the debug message like: module name : function name : debug message */
     printk(KERN_ALERT "ville :ville_exit: you ask for debug!\n");
#endif
     printk(KERN_ALERT "ville :ville_exit: ville module exit!\n");


     return;
}


module_init(ville_init);
module_exit(ville_exit);


MODULE_LICENSE("GPL");
MODULE_AUTHOR("ville lee");

Makefile:


## if module is built in the kernel module
## system. Give the work to kbuild.


# provide the default value to module name and ccflags-y
ifeq ($(MODULE),)
     MODULE := ville
endif
ifeq ($(DEBUG),y)
     ccflags-y += -DDEBUG
endif

 


ifneq ($(KERNELRELEASE),)
     obj-m := $(MODULE).o
else
     KERNELDIR := /lib/modules/$(shell uname -r)/build
     PWD := $(shell pwd)


default:
     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif


.PHONY:clean
clean:
     echo "cleaning ...."
     rm modules.order Module.symvers \
        $(MODULE).ko $(MODULE).mod.c \
        $(MODULE).mod.o $(MODULE).o
     echo "clean up"

操作:

 

 

 

[ville@localhost source]$ ls
Makefile ville.c ville.h
[ville@localhost source]$ make
make -C /lib/modules/2.6.35.13-91.fc14.i686.PAE/build M=/home/ville/Programming/VFS/villefs/source modules
make[1]: Entering directory `/usr/src/kernels/2.6.35.13-91.fc14.i686.PAE'
CC [M] /home/ville/Programming/VFS/villefs/source/ville.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/ville/Programming/VFS/villefs/source/ville.mod.o
LD [M] /home/ville/Programming/VFS/villefs/source/ville.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.35.13-91.fc14.i686.PAE'
[ville@localhost source]$ su
Password:
[root@localhost source]# insmod ville.ko
[root@localhost source]# tail /var/log/messages
Aug 1 21:52:20 localhost kernel: [ 527.943854] ville :ville_init: ville module init!
[root@localhost source]# rmmod ville
[root@localhost source]# tail /var/log/messages
Aug 1 21:52:20 localhost kernel: [ 527.943854] ville :ville_init: ville module init!
Aug 1 21:55:06 localhost kernel: [ 694.160046] ville :ville_exit: ville module exit!
[root@localhost source]# exit
exit
[ville@localhost source]$ ls
Makefile modules.order Module.symvers ville.c ville.h ville.ko ville.mod.c ville.mod.o ville.o
[ville@localhost source]$ make clean
echo "cleaning ...."
cleaning ....
rm modules.order Module.symvers \
ville.ko ville.mod.c \
ville.mod.o ville.o
echo "clean up"
clean up
[ville@localhost source]$ make DEBUG:=y
make -C /lib/modules/2.6.35.13-91.fc14.i686.PAE/build M=/home/ville/Programming/VFS/villefs/source modules
make[1]: Entering directory `/usr/src/kernels/2.6.35.13-91.fc14.i686.PAE'
CC [M] /home/ville/Programming/VFS/villefs/source/ville.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/ville/Programming/VFS/villefs/source/ville.mod.o
LD [M] /home/ville/Programming/VFS/villefs/source/ville.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.35.13-91.fc14.i686.PAE'


[ville@localhost source]$ ls
Makefile modules.order Module.symvers ville.c ville.h ville.ko ville.mod.c ville.mod.o ville.o
[ville@localhost source]$ su
Password:
[root@localhost source]# insmod ville.ko
[root@localhost source]# tail /var/log/messages
Aug 1 21:44:24 localhost rtkit-daemon[1721]: Successfully made thread 1838 of process 1836 (/usr/bin/pulseaudio) owned by '500' RT at priority 5.
Aug 1 21:44:24 localhost rtkit-daemon[1721]: Successfully made thread 1839 of process 1836 (/usr/bin/pulseaudio) owned by '500' RT at priority 5.
Aug 1 21:44:24 localhost pulseaudio[1836]: bluetooth-util.c: Error from ListAdapters reply: org.freedesktop.DBus.Error.Spawn.ChildExited
Aug 1 21:44:26 localhost rtkit-daemon[1721]: Successfully made thread 1870 of process 1870 (/usr/bin/pulseaudio) owned by '500' high priority at nice level -11.
Aug 1 21:44:26 localhost pulseaudio[1870]: pid.c: Daemon already running.
Aug 1 21:44:41 localhost dbus: [system] Rejected send message, 2 matched rules; type="method_call", sender=":1.56" (uid=500 pid=1855 comm="nautilus) interface="org.freedesktop.DBus.Properties" member="GetAll" error name="(unset)" requested_reply=0 destination=":1.18" (uid=0 pid=1588 comm="/usr/sbin/console-kit-daemon))
Aug 1 21:52:20 localhost kernel: [ 527.943854] ville :ville_init: ville module init!
Aug 1 21:55:06 localhost kernel: [ 694.160046] ville :ville_exit: ville module exit!
Aug 1 21:56:17 localhost kernel: [ 764.867120] ville :ville_init: you ask for debug!
Aug 1 21:56:17 localhost kernel: [ 764.867127] ville :ville_init: ville module init!
[root@localhost source]# rmmod ville
[root@localhost source]# tail /var/log/messages
Aug 1 21:44:24 localhost pulseaudio[1836]: bluetooth-util.c: Error from ListAdapters reply: org.freedesktop.DBus.Error.Spawn.ChildExited
Aug 1 21:44:26 localhost rtkit-daemon[1721]: Successfully made thread 1870 of process 1870 (/usr/bin/pulseaudio) owned by '500' high priority at nice level -11.
Aug 1 21:44:26 localhost pulseaudio[1870]: pid.c: Daemon already running.
Aug 1 21:44:41 localhost dbus: [system] Rejected send message, 2 matched rules; type="method_call", sender=":1.56" (uid=500 pid=1855 comm="nautilus) interface="org.freedesktop.DBus.Properties" member="GetAll" error name="(unset)" requested_reply=0 destination=":1.18" (uid=0 pid=1588 comm="/usr/sbin/console-kit-daemon))
Aug 1 21:52:20 localhost kernel: [ 527.943854] ville :ville_init: ville module init!
Aug 1 21:55:06 localhost kernel: [ 694.160046] ville :ville_exit: ville module exit!
Aug 1 21:56:17 localhost kernel: [ 764.867120] ville :ville_init: you ask for debug!
Aug 1 21:56:17 localhost kernel: [ 764.867127] ville :ville_init: ville module init!
Aug 1 21:56:44 localhost kernel: [ 792.003641] ville :ville_exit: you ask for debug!
Aug 1 21:56:44 localhost kernel: [ 792.003648] ville :ville_exit: ville module exit!

總結(jié):
      通過這兩個(gè)例子,就了解了如何在用戶空間和內(nèi)核態(tài)模塊中使用開關(guān)宏來進(jìn)行條件編譯。

 


   ville


文章出處:飛諾網(wǎng)(www.):http://www./course/6_system/linux/Linuxjs/20110802/557787.html

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多