一種基於Makefile的編譯系統架構實現及自動化

2021-08-01 17:16:45 字數 4173 閱讀 1959

一.     

我分享的是乙個簡化版的編譯架構,我要實現的目標是:對遵循以下組織結構的資料夾進行編譯:

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/sh

if [ ! -d "out" ];then

mkdir -p out/bin

mkdir -p out/obj

fiprogname=hsm_test

mak.pl

#!/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解決 如下,兩張表都是...