Scons还可以用Builder方法来自定义编译方法,工程目录如下
SConstruct中定义了Environment以及需要用到的编译参数,编译源文件
import sys
import os
from SCons.Script import *
from scons.SCons import *
risc_path='/home/sdk/toolchain/bin'
env = Environment()
env.PrependENVPath('PATH',risc_path)
env['CC']='riscv64-unknown-elf-gcc'
Progress('Evaluating $TARGET\n')
print("cc=%s" % env['CC'])
source=[]
source.append(Glob("*.c"))
scon=env.Program(source=source)
SConscript(os.path.join('src','SConscript'),{"env":env})
在src下的SConscript内容如下:定义了两个Builder, 分别调用函数build_test以及test.py。定义好了后设置BUILDERS并append进Environment。同时在调用的时候指示源文件名称。
import sys
import os
from SCons.Script import *
from scons.SCons import *
Import('env')
def build_test(target,source,env):
print('build test')
print("SConcscipt files")
env.Append(py_file=os.path.join(os.getcwd(),"test.py"))
bld=Builder(action=Action('python $py_file $SOURCES $TARGET'))
test=Builder(action=Action(build_test,"Generating $TARGET"))
env.Append(BUILDERS={'Foo':bld})
env.Append(BUILDERS={'Foo1':test})
env.Foo(target='1.txt',source='2.txt')
如果env.Foo中的target和source没有设置或者是个空值的时候,会报如下的错误。提示Tried to lookup Dir ‘src’ as a File,意思是把当前的src目录当做了一个文件,而在当前目录下找不到这个文件
在调用的时候传入了target和source后,在python文件中通过sys.argv[1]和sys.argv[2]提取出对应的参数
import sys
if __name__ == "__main__":
print(sys.argv[0],sys.argv[1],sys.argv[2])
print("hello world")
执行结果如下,sys.argv[0]是python文件的完整路径。也可以看到完整的Builder调用方式:
python /home/wuqi/c_prj/src/test.py src/2.txt src/1.txt
自定义宏:
宏定义一般都在.c或者.h文件中产生,在scons中也可以定义宏。在SConstruct中定义列表cppdefines, 首先append 宏定义TEST。然后从ARGLIST命令行中读取宏定义,如果key值=define,则将后面定义的宏定义添加进cppdefines。
cppdefines=[]
cppdefines.append("TEST")
for key,value in ARGLIST:
if key == 'define':
cppdefines.append(value)
SConscript(os.path.join('src','SConscript'),{"env":env})
env.Append(CPPDEFINES=cppdefines)
scon=env.Program(source=source)
同时在SConscript中在添加一个宏定义DEBUG
env.Append(CPPDEFINES='DEBUG')
最终在test.c中使用宏定义
#include<stdio.h>
void main()
{
unsigned i=0;
#ifdef DEBUG
i+=1;
printf("i=%d\n",i);
#endif
#ifdef TCP
i+=1;
printf("i=%d\n",i);
#endif
}
最后命令行调用scons define=TCP, 其中关于编译的部分执行结果如下:可以看到gcc命令中带有-DDEBUG -DTEST -DTCP,这就是我们在工程中添加的三个宏定义
Evaluating src/SConscript
Evaluating src
Evaluating test.c
Evaluating /usr/bin/gcc
Evaluating test.o
gcc -o test.o -c -DDEBUG -DTEST -DTCP test.c
Evaluating test
gcc -o test test.o
Evaluating .