Makefile和scons快速转换
makefile是传统C/C++开发项目中最常用的工程管理工具,而现在随着python的日益流行,基于python的代码编译工具scons使用越来越广泛。在一些比较大项目中,可能需要把makefile转换成scons,或者反过来把基于scons转换成makefile,本文结合了笔者碰到的一些项目,总结了一些常用的模式在两种不同工具中的实现。
1.
include 头文件
makefile中的实现:
通过-I指定,比如:-I./
-I/usr/include
scons中的实现:
通过CPPPATH来指定,比如:
cpppath
= Split(‘../include‘)
CPPPATH
= env[‘CPPPATH‘] + cpppath
env.CPPPATH=Split(‘../include‘)
2.修改编译选项
makefile中的实现:
直接跟编译选项:比如-Wall -O3
scons中的实现:
CCFLAGS
= env[‘CCFLAGS‘] + ccflags
env.CCFLAGS=Split(‘-Wall
-O3‘)
修改宏定义:
makefile中的实现:
-DDEBUG
-DRELEASE
scons中的实现:
CPPDEFINES=env[‘CPPDEFINES‘]
+ local_cppdefines
3.文件安装和删除
makefile中的实现,通过定义.PHONY
clean , .PHONY install实现:
.PHONY:
clean
clean:
-rm
$(TARGET) $(TESTCASE)
.PHONY:
install
install:
-cp
desmon /bin/
-cp
libdes.a /lib/user64/
echo
"Install done!"
scons中的实现:
env.Install(‘/bin‘,
source = [‘desmon‘])
env.Clean(‘/bin‘,
[‘desmon])
4.链接静态库
makefile中的实现:
放在object文件依赖列表里面,depobj=target.o
libdep.a
scons中的实现:
放在.o文件依赖列表里面:例如depobj=Split(‘target.o
libdep.a‘)
5.链接动态库
makefile中的实现:
在链接的阶段指定库的名称,比如-lpthread,表示依赖libpthread.so
scons中的实现:
放在LIBS列表里面,比如指定动态链接libpthread.so:
env.LIBS=Split(‘pthread‘)
6.指定生成的.o文件
makefile中的实现:
gcc
-c -o name.o name.c
scons中的实现:
env.StaticObject()
7.指定生成静态库
makefile中的实现:
ar
rcs -o libtest.a name1.o name2.o name3.o
scons中的实现:
env.StaticLibrary(target
= ‘libtest‘, source = [‘name1.o name2.o name3.o‘], CPPPATH =
env[‘CPPPATH‘] + cpppath, CCFLAGS = env[‘CCFLAGS‘] + ccflags)
8.指定生成动态库
makefile中的实现:
gcc
-shared -o libtest.so name1.o name2.o name3.o
scons中的实现:
env.SharedLibrary(‘libtest‘,
[‘name1.o‘,
‘name2.o‘,
‘name3.c‘])
9.指定生成可程序文件:
makefile中的实现:
gcc
-o dest.o name1.o name2.o name3.o,再如:
$(TESTCASE):%:%.o
$(CC)
-o [email protected] $^ $(CFLAGS) $(LIBS) $(INCLUDEPATH)
scons中的实现:
env.Program(target
= item, source = [item + (".o")] + Split(‘libsms.a‘),
CPPPATH = env[‘CPPPATH‘] + cpppath, CCFLAGS = env[‘CCFLAGS‘] +
ccflags, LIBS = locallibs)
10.编译多个目录:
makefile中的实现:
SUBDIRS
= \
Sub1 \
Sub2
all:
$(SUBDIRS)
for
i in $(SUBDIRS); do $(MAKE) -C $$i all; sleep 2; done
@echo
scons中的实现:
在每个子目录中实现对应的SConscript,在最顶层目录实现SConsctruct,在里面include各个子目录的SConscript
11.编译多个文件
Makefile中,利用makefile自多推导原则:
TESTCASE=a_test
b_test c_event
$(TESTCASE):%:%.o
$(CC)
-o [email protected] $^ $(CFLAGS) $(LIBS) $(INCLUDEPATH)
scons中,利用python
for语句:
testapps
= Split(‘a_test b_test c_event‘)
for
item in testapps:
itemsrc
= item + (".c")
env.StaticObject(itemsrc,
CPPDEFINES = ccflags)
env.Program(target
= item, source = [item + (".o")] + Split(‘libsms.a‘),
CPPPATH = env[‘CPPPATH‘] + cpppath, CCFLAGS = env[‘CCFLAGS‘] +
ccflags, LIBS = locallibs)
12.导入环境变量
makefile中的实现:
可以在shell下export一个环境变量如:
export WKDIR=`pwd`,在makefile里面export之后,之后的子目录的makefile里可通过$(WKDIR)来使用
scons中的实现:以WKDIR为例
在最上层定义env的时候,加入WKDIR到env列表里去,然后export
env。子目录需要用的时候,用Import
(‘env‘)后可以使用WKDIR
13.
scons中调用makefile混用
利用python中sys.Execute()系统命令,在里面执行makefile。