Scons 六:构建自己的Builder

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 ')

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 ",i);

#endif

 

#ifdef TCP

    i+=1;

    printf("i=%d ",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 .

原文地址:https://www.cnblogs.com/zhanghongfeng/p/14168316.html