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 .