一.
我分享的是乙個簡化版的編譯架構,我要實現的目標是:對遵循以下組織結構的資料夾進行編譯:
bb_***
_inc
_src
entry
………modules
module1
………module2
………………
_src
目錄下可以允許有遞迴目錄或者檔案,最大深度不超過
5,makefile
定義規則會去自動搜尋所有的
c原始檔,編譯出的所有
.o檔案會生成在
out/obj
目錄,可執行檔案會生成在
out/bin目錄
通常makefile
可能需要這樣寫:
rm=/bin/rm -f
cc= gcc
defs=
progname= out/bin/test
includes= -i./_inc
libs=
defines= $(includes) $(defs)-dsys_unix=1
cflags= -g $(defines)
srcs = src/entry/entry.csrc/modules/ module1/mytest.c src/modules/module2/test.c
objs = out/obj/entry.oout/obj/mytest.o out/obj/test.o
all: $(progname)
$(progname) : $(objs)
$(cc) $(cflags) -o $(progname) $(objs) $(libs)
out/obj/%.o:src/entry/%.c
$(cc) $(cflags) -c $< -o $@
out/obj/%.o:src/modules/module1/%.c
$(cc) $(cflags) -c $< -o $@
out/obj/%.o:src/modules/module2/%.c
$(cc) $(cflags) -c $< -o $@
clean:
$(rm)$(objs) $(progname) core *~
雖然以上
makefile
也可以工作,但是擴充套件性不佳,如果
_src
目錄下將來需要加入更多
module
或者其他**,就需要修改
makefile
裡面的srcs
以及依賴關係,假如
_src
目錄很深,底下的檔案眾多,這個工作量可能比較繁瑣
二、
再看看下面的
makefile:
# created with mak.pl v0.1 on frimay 26 19:43:38 2017
rm=/bin/rm -f
cc= gcc
defs=
progname= out/bin/test
includes= -i./_inc
libs=
defines= $(includes) $(defs)-dsys_unix=1
cflags= -g $(defines)
srcs_dir = $(
shell find _src -maxdepth 5 -type d)
objs_dir = out/obj
srcs = $(
foreach
d,$(srcs_dir),$(
wildcard
$(d)/*.c))
objs = $(
addprefix
$(objs_dir)/,$(
patsubst
%.c,%.o,$(
notdir
$(srcs))))
all: $(progname)
$(progname) : $(objs)
$(cc) $(cflags) -o $(progname) $(objs) $(libs)
define make-object
$1:$2
$(cc) $(cflags) -c $$< -o $$@
endef
$(foreach d,$(srcs_dir),$(
eval
$(call
make-object,$(objs_dir)/%.o,$(d)/%.c)))
clean:
$(rm) $(objs) $(progname) core *~
通過定義自己的規則,即使原始碼目錄發生改變
,makefile
也不需要做修改
,達到增強擴充套件性的目的
.大家有興趣可以看看
basa
編譯體系裡面的
project.mk,
它定義的規則更加複雜和龐大
三、
實現makefile
自動生成,以上
makefile
可以通過乙個
perl
指令碼自動生成,執行
run.sh即可(
請參考附件
),以下是
run.sh
指令碼的內容:
#!/bin/sh
if [ ! -d "out"];then
mkdir -p out/bin
mkdir -p out/obj fi
progname=hsm_test
./mak.pl
其中選項定義生成的可執行檔名
,_src
指定存放原始碼的目錄
(其實原始碼目錄也可以是其他名稱而不侷限於
」_src」)
run.sh
#!/bin/shmak.plif [ ! -d "out" ];then
mkdir -p out/bin
mkdir -p out/obj
fiprogname=hsm_test
#!/usr/bin/perl
use strict;
use getopt::long;
$|=1;
my %g_op=();
# -=version=-
rm=/bin/rm -f
cc= gcc
defs=
progname= -=prog=-
includes= -i./_inc
libs=
defines= \$(includes) \$(defs) -dsys_unix=1
cflags= -g \$(defines)
srcs_dir = \$(shell find -=srcs=- -maxdepth 5 -type d)
objs_dir = out/obj
srcs = \$(foreach d,\$(srcs_dir),\$(wildcard \$(d)/*.c))
objs = \$(addprefix \$(objs_dir)/,\$(patsubst %.c,%.o,\$(notdir \$(srcs))))
all: \$(progname)
\$(progname) : \$(objs)
\$(cc) \$(cflags) -o \$(progname) \$(objs) \$(libs)
define make-object
\$1:\$2
\$(cc) \$(cflags) -c \$\$< -o \$\$@
endef
\$(foreach d,\$(srcs_dir),\$(eval \$(call make-object,\$(objs_dir)/%.o,\$(d)/%.c)))
clean:
\$(rm) \$(objs) \$(progname) core *~
eof;
my $argc=$#argv+1;
my %g_options=(
"help" =>\$g_help,
);&do_it();
# show usage and exit
sub usage
{ print<
Makefile的一種通用寫法
管理linux環境下的c c 大型專案,如果有乙個智慧型的build system會起到事半功倍的效果,本文描述linux環境下大型工程專案子目錄makefile的一種通用寫法,使用該方法,當該子目錄內的檔案有增刪時無需對makefile進行改動,可以說相當的智慧型。下面先貼 為減小篇幅,一些非關鍵...
Makefile的一種通用寫法以及其中的字段含義
管理linux環境下的c c 大型專案,本文描述linux環境下大型工程專案子目錄makefile的一種通用寫法,使用該方法,當該子目錄內的檔案有增刪時無需對makefile進行改動,可以說相當的智慧型。下面先貼 為減小篇幅,一些非關鍵的 被去掉,本方法的侷限是用於乙個c檔案生成乙個可執行檔案的場合...
一種基於有序序列mapjoin的方法
在解決資料傾斜問題時,我們經常會採用一種方式 mapjoin,按照hive的實現,mapjoin是將其中一張表在map的過程中載入到記憶體中,但是如果在join的表中,最小的表的資料量也不小的情況下。我們該怎麼辦呢?其中一種解決的方式是 將兩張表需要實現排序 直接用hadoop解決 如下,兩張表都是...