多目錄Makefile(庫及分層目錄)
本文程式碼雖簡單,但涉及比較複雜的各種呼叫關係,欲研究者需有耐心及清醒頭腦。 切切!
背景交待:
1、正在移植U-Boot,並對其原始碼進行了一些分析,感覺它的Makefile十分強勁; 2、以前寫的Makefile模板不合適多層目錄; 3、研究一下多個庫之間相互呼叫的問題。 平臺及測試環境介紹: 1、fc9系統,i386平臺,gcc版本4.3.2,使用Secure CRT連線linux系統,資料均由該軟體複製而得; 2、工程目錄名稱為lib-test,其下有3個程式碼目錄及一個頭檔案目錄,分別是foo(foo.c及common.c檔案)、bar(bar.c及common.c檔案)、bt(backtrace.c檔案)和configs(foo.h、bar.h及backtrace.h檔案);其中bt目錄為backtrace程式碼,它是作者的工程庫的一部分。 目錄路徑、檔案分佈如下:lib-test
|-->main.c
|-->example.c
|-->Makefile
| |-->foo.c
|-->foo-->|-->common.c
| |-->Makefile
|
| |-->bar.c
|-->bar-->|-->common.c
| |-->Makefile
|
| |-->backtrace.c
|-->bt--->|
| |-->Makefile
|
| |-->foo.h
|-->configs->|-->bar.h
| |-->backtrace.h
for dir in $(SUBDIRS); \意思是進入指定子目錄,並執行子目錄的Makefile檔案(子目錄只負責生成庫檔案)。 庫相互呼叫測試(詳見程式碼): 1、foo.c檔案中hello_foo函式呼叫bar.c檔案中的bar函式以及同一目錄下common.c檔案的common_bar函式; 2、bar.c檔案中hello_bar函式呼叫foo.c檔案中的foo函式以及同一目錄下common.c檔案的common_foo函式。 程式碼示例: 1、foo目錄下: 1)、foo.h
do $(MAKE) -C $$dir all || exit 1; \
done
#ifndef2)、foo.cFOO_H_
#define FOO_H_
void foo(int i);
int hello_foo(void);
#endif
#include <stdio.h>3)、common.c
void foo(int i)
{
printf("hell from %s() in file: %s, num:%d\n", __func__, __FILE__, i);
}
int hello_foo(void)
{
printf("in func: %s()\n", __func__);
bar(100);
common_foo();
printf("=========================================\n");
return 0;
}
#include <stdio.h>2、bar目錄 1)、bar.h
int common_foo(void)
{
printf("this is a common function in foo/common.c\n");
return 0;
}
#ifndef BAR_H_2)、bar.c
#define BAR_H_
void bar(int i);
int hello_bar(void);
#endif
#include <stdio.h>3)、common.c
void bar(int i)
{
printf("hell from %s() in file: %s, num:%d\n", __func__, __FILE__, i);
}
int hello_bar(void)
{
printf("in func: %s()\n", __func__);
foo(200);
common_bar();
printf("=========================================\n");
return 0;
}
#include <stdio.h>3、example.c
int common_bar(void)
{
printf("this is a common function in bar/common.c\n");
return 0;
}
#include <stdio.h>4、main.c
void foo1(int a)
{
int i;
i = a;
}
int fun(int a, int b, int c)
{
char buf[14];
int sum;
sum = a + b + c;
foo1(a);
return sum;
}
#include <stdio.h>(題外話: 這裡的3個自定義標頭檔案使用了尖括號(<>),如果按教科書的說法是不正確的,因為尖括號是從標準庫的路徑搜尋標頭檔案的。然而作者經常看到一些程式碼中標準庫的標頭檔案是使用雙引號來包含的(如#include "stdio.h"),這裡反其道而行之。因為在Makefile中使用-I選項指定了額外的標頭檔案路徑,使用
#include <backtrace.h>
#include <foo.h>
#include <bar.h>
int main(void)
{
printf("hello from %s()\n\n", __func__);
hello_foo();
hello_bar();
print_trace(11);
}
[[email protected] lib-test-latelee.org]$ gcc -g -c main.c example.c --verbose -Iconfigs命令來編譯時顯示了gcc搜尋標頭檔案路徑的過程,如下:
#include "..." search starts here:當然,實際開發中不提倡這種方法,然而在U-Boot中卻是十分常見的,只是有些人不明白其中的道理罷了。 題外話 結束) 庫目錄的Makefile(這裡顯示的是foo目錄下的Makefile,其它者修改庫名稱及程式碼檔名稱即可)
#include <...> search starts here:
configs
/usr/local/include
/usr/lib/gcc/i386-redhat-linux/4.3.2/include
/usr/include
End of search list.
# A simple Makefile for lib(libxxx.a)頂層目錄的Makefile檔案
# By Late Lee(http://www.latelee.org)
AR = ar
ARFLAGS = cr
LIB = libfoo.a
RM = -rm -rf
OBJS := foo.o common.o
all: $(LIB)
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) [email protected] $(OBJS)
clean:
$(RM) $(OBJS) $(LIB) *.bak *~
.PHONY: all clean
#################################################################執行make的過程:
# A simple Makefile
# By Late Lee(http://www.latelee.org)
#
# bugs:
# 1. 需要顯式指定庫位置、名稱;
# 2. make 及 make clean處理得不好(對於庫,要麼刪除再編譯,要麼無操作);
#################################################################
CC=gcc
CFLAGS = -Wall
DEBUG = y
ifeq ($(DEBUG), y)
CFLAGS += -g
else
CFLAGS += -O2
endif
SUBDIRS := foo bar bt
LIBS := bt/libbt.a foo/libfoo.a bar/libbar.a
LDFLAGS = $(LIBS)
RM = -rm -rf
__OBJS = main.o
__OBJS += example.o
__SRCS = $(subst .o,.c,$(__OBJS))
target = a.out
MAKE = make
#all: clean $(target)
all: $(target)
$(__OBJS): $(__SRCS)
$(CC) $(CFLAGS) -c $^ -I ./configs/
$(target): $(__OBJS)
for dir in $(SUBDIRS); \
do $(MAKE) -C $$dir all || exit 1; \
done
$(CC) $(CFLAGS) $^ -o [email protected] $(LDFLAGS)
clean:
@for dir in $(SUBDIRS); do make -C $$dir clean|| exit 1; done
$(RM) $(__OBJS) $(target) *.bak *~
.PHONY: all clean
[[email protected] lib-test]$ make執行結果:
gcc -Wall -g -c main.c example.c -I ./configs/
example.c: In function ‘fun’:
example.c:10: warning: unused variable ‘buf’
for dir in foo bar bt ; \
do make -C $dir all || exit 1 ; \
done
make[1]: Entering directory `/home/latelee/linux-c/lib-test/foo'
cc -c -o foo.o foo.c
cc -c -o common.o common.c
ar cr libfoo.a foo.o common.o
make[1]: Leaving directory `/home/latelee/linux-c/lib-test/foo'
make[1]: Entering directory `/home/latelee/linux-c/lib-test/bar'
cc -c -o bar.o bar.c
cc -c -o common.o common.c
ar cr libbar.a bar.o common.o
make[1]: Leaving directory `/home/latelee/linux-c/lib-test/bar'
make[1]: Entering directory `/home/latelee/linux-c/lib-test/bt'
cc -c -o backtrace.o backtrace.c
ar cr libbt.a backtrace.o
make[1]: Leaving directory `/home/latelee/linux-c/lib-test/bt'
gcc -Wall -g main.o example.o -o a.out bt/libbt.a foo/libfoo.a bar/libbar.a
[[email protected] lib-test]$ ./a.out歡迎指正文中錯誤之處。其它Makefile高階應用,歡迎一起討論,共同進步。
hello from main()
in func: hello_foo()
hell from bar() in file: bar.c, num:100
this is a common function in foo/common.c
=========================================
in func: hello_bar()
hell from foo() in file: foo.c, num:200
this is a common function in bar/common.c
=========================================
Obtained 4 stack frames.
./a.out [0x8048733]
./a.out [0x80486cf]
/lib/libc.so.6(__libc_start_main+0xe5) [0x7ea6d5]
./a.out [0x8048601]
相關推薦
多目錄Makefile(庫及分層目錄)
本文程式碼雖簡單,但涉及比較複雜的各種呼叫關係,欲研究者需有耐心及清醒頭腦。 切切! 背景交待: 1、正在移植U-Boot,並對其原始碼進行了一些分析,感覺它的Makefile十分強勁; 2、以前寫的Makefile模板不合適多層目錄; 3、研究一下多個庫之間相互
Caffe的依賴庫及原始碼目錄結構
1. Boost庫:它是一個可移植、跨平臺,提供原始碼的C++庫,作為標準庫的後備。 在Caffe中用到的Boost標頭檔案包括: (1)、shared_ptr.hpp:智慧指標,使用它可以不需要考慮記憶體釋放的問題; (2)、date_time/posix_tim
linux目錄結構介紹及重要目錄說明
內存信息 使用 cpu -h 超級用戶 全局環境變量 ifup 日誌 啟動命令 根節點:/,所有文件都掛載在這下面,目錄結構和分區設備是沒有關系的,不同的目錄可以跨越不同磁盤設備和分區1、查看分區:[root@yangxp Downloads]# ls /dev/sda*/
CMakeLists多目錄通用模板及Win&Linux相容動態庫編寫
CMakeLists多目錄通用模板 CMake不僅具有跨平臺(一次編寫,多次編譯)的特點,還有便於工程管理的特點,支援CMake的IDE也有很多(VS[MS],QT,CodeBlock等)。 以一個通用組織的工程(包含PCL,VTK,libLAS第三方庫)為
[Makefile]多目錄Makefile寫法
16px 間隔 ews pro images include 先來 文章 status 最近需要寫一個測試程序,這個測試程序需要集成一些功能,寫在同一個文件看上去很不好,多個文件的Makefile又不是很熟,於是分享下面這篇文章 轉自:http://blog.csdn.ne
多執行緒實現檔案在多層目錄中查詢及拷貝到多層目錄
在實現建立多級目錄後,遇到了檔案分類複製的問題。。。左思右想,最後覺得還是寫程式碼實現比較快,畢竟我比較懶。。。不要問我為要寫那麼多find方法來匹配路徑。。。畢竟腦子不夠用。如果是比較重要的檔案,不推薦多執行緒去實現,雖然用了同步,但還是有可能漏掉某個檔案。還是老老實實的
批量更新和打包多個Git庫目錄
# 批量更新多個Git庫建立一個專門存放git庫專案的目錄,例如D:\git。project專案的本地git庫目錄為D:\git\project\.git。更新(git pull)D:\git目錄下的所有Git/Hg專案,在該目錄下執行gitpullall.bat批處理檔案:
多檔案編譯的makefile編寫(附當前目錄下所有.c/.cpp檔案編譯makefile)
C程式碼是如何變成可以執行程式的過程: 1、由前處理器把程式設計師所編寫的C程式碼翻譯成標準C程式碼,可以得到以.i結尾的預處理檔案。 gcc -E code.c gcc -E code.c -o code.i 2、由彙編器
linuxSVN版本庫及同步檔案到WEB目錄
svn hooks位置一定要確定,即你的 版本庫位置,配置hooks更新到對應的網站目錄。 一 安裝與配置SVN 1.安裝subversion centos: yum install subversion ubuntu: apt-get install subv
包含目錄、庫目錄、附加包含目錄、附加庫目錄、附加依賴項如何使用? 及靜態庫,動態庫的建立與呼叫和vs裡引用的使用
引言:vs中怎麼新增外部標頭檔案?如過直接在專案標頭檔案處,新增一下,如下圖:則,依然會報錯,如下圖:有兩種方法,來解決(你不在vs上的新增它也沒事):(1) 直接把外部標頭檔案複製過來,放在此專案下即與該專案cpp檔案同一目錄,如下圖:(2)專案右鍵,屬性裡的C/C++
包含目錄、庫目錄、附加包含目錄、附加庫目錄、附加依賴項如何使用? 及靜態庫,動態庫的創建與調用和vs裏引用的使用
pragma 經驗 dll blog res 編譯器 rdquo 編譯期 靜態 https://blog.csdn.net/Young__Fan/article/details/80528740 引言:vs中怎麽添加外部頭文件?如過直接在項目頭文件處,添加一下,如下
sql server 2008 r2 無法定位到數據庫文件目錄
src logs 子目錄 數據 屬性 添加 文件目錄 無法定位 ges 像這樣,選擇數據庫文件時, 無法定位到文件夾目錄,子目錄下的都不顯示。明明選擇的這個文件夾裏還有很多子文件夾,卻顯示不了。 解決方法: 在此文件夾上右擊,屬性-安全 添加紅框中的用戶就可以
python2.7.13標準庫文件目錄操作與文件操作
mov abs 庫文件 shell htm .com 及其 rec lose 標準庫的中文參考文檔: http://python.usyiyi.cn/translate/python_278/library/index.html 官方標準庫文檔:https://docs.p
MYSQL Data目錄查找及如何遷移
sed 數據庫 and settings cat documents 復制 找到 ria MySQL數據庫安裝成功後,卻發現在MySQL安裝目錄下的Data目錄竟然沒有新建的數據庫?那麽如何查找真正的data目錄呢?下面3A網絡小錢今天就來教你如何查找真正的Data目錄並遷
subversion多版本庫及導入導出相關遷移
svn subversion visualsvn subversion在實際項目研發中被大量的應用,但是往往在實際的環境中大多數的人還僅僅把SVN僅用於創建一個SVN庫,當然在subversion也是支持一個SVN服務多個版本庫的,最近剛剛好在做SVN的跨系統平臺遷移工作,就此就簡單的說一說
NFS共享目錄,掛載及應用
nfs 服務 掛載 共享目錄 (1) nfs server導出/data/application/web,在目錄中提供wordpress; (2) nfs client掛載nfs server導出的文件系統至/var/www/html; (3) 客戶端(lamp),部署wordpress,並讓其正常訪問;要
HTML相對路徑相對目錄--上級目錄及下級目錄的寫法
ref wro 文件 pre -- 所在 表示 wow 文件的 如何表示上級目錄 ../表示源文件所在目錄的上一級目錄,../../表示源文件所在目錄的上上級目錄,以此類推。 假設info.html路徑是:c:/Inetpub/wwwroot/sites/blabla/in
Linux各目錄及每個目錄的詳細介紹
直接 系統引導 ilo 硬盤驅動 另有 升級 針對 更新 pool Linux各目錄及每個目錄的詳細介紹,包括linux常見核心目錄諸如/bin,/etc,/home,/usr,/root,/dev,/var,/proc等常見目錄詳細介紹及說明。 linux常見目錄說明 /
文件及Linux目錄結構
module 最好 win 對待 行修改 fstab size idc .html 什麽是文件 在linux系統上,所有的資源都是文件,Linux系統下的文件類型包括 普通文件(-) 目錄(d) 符號鏈接(l) 字符設備文件(c) 塊設備文件(b) 套接字(s) 命令管道
C#獲取IIS所有站點及虛擬目錄和應用程序(包含名稱及詳細信息)
local ren localhost rem ace rms 獲取 set 目錄 原文出處:傳送門 using System; using System.Collections.Generic; using System.ComponentModel; using Sy