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 $@ $^ $(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 $@ $^ $(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。
本文转自存储之厨51CTO博客,原文链接:http://blog.51cto.com/xiamachao/1865648 ,如需转载请自行联系原作者