Scons是依賴於python寫的編譯腳本,相對makefile來說,用起來更簡單一些,不需要記太多的makefile語法。
安裝方法:
1 安裝python3。有些電腦上可能已經內置了python2。這個時候需要將python3設置為默認的python版本。
cd /usr/bin
sudo rm python
sudo ln -s python3 python
通過python -V校驗版本是否大於3.0
2 更新pip程序
通過pip3 -V校驗版本是否大於3.0
3 執行sudo python -m pip install scons。
4 執行命令:sudo ln -fs /usr/local/lib/python3.6/site-packages/scons /usr/local/lib/scons
這個的目的是執行scons命令時規避如下的錯誤:
SCons import failed. Unable to find engine files in: /usr/local/lib/scons-3.1.2 /usr/lib/scons-3.1.2 /usr/local/lib/scons-3.1.2 /usr/lib/python2.7/site-packages/scons-3.1.2 /usr/lib64/scons-3.1.2 /usr/local/lib/scons /usr/lib/scons /usr/local/lib/scons /usr/lib/python2.7/site-packages/scons /usr/lib64/scons Traceback (most recent call last): File "/usr/local/bin/scons", line 195, in <module> import SCons.Script ImportError: No module named SCons.Script
這個錯誤的原因是pip3 安裝 SCons,默認安裝位置是 /usr/local/bin/scons, 庫(engine)的默認安裝位置是 /usr/local/lib/python3.6/site-packages/scons,
但在運行時默認的搜索 engine 的路徑不包含安裝路徑,導致錯誤。(顯然 SCons 沒有處理好 Python2 和 Python3,只搜索了 Python2)。因此用上面的命令建立scons到python3
的軟鏈接
和makefile需要一個Makefile文件一樣,Scons同樣需要一個 Sconstruct文件。里面用來寫編譯腳本,語法和python一樣的。為了驗證Scons是否安裝正確,可以新建一個Sconstruct文件,里面什么都不用寫。進入到和Sconstruct同目錄的地方。打開終端執行scons
出現下面的打印代表Scons已經安裝OK。
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
scons: `.' is up to date.
scons: done building targets.
來編寫一個測試文件,test.c
int
main()
{
printf("Hello, world!\n");
return 1;
}
編譯這么一個文件,在Sconstruct中只需要Program(‘test.c’)一條語句就可以了
執行scons命令。可以看到如下輸出,其實執行過程和Makefile沒什么差別。但是語法相對簡單了很多
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o test.o -c test.c
gcc -o test test.o
scons: done building targets.
執行scons -c就可以清理掉所有的目標文件,效果等同於make clean.
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Cleaning targets ...
Removed test.o
Removed test
scons: done cleaning targets.
如果只想出.o文件,可以用命令Object(‘test.c’)
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o test.o -c test.c
scons: done building targets.
SConstruct中的語法雖然是python格式的。但是執行順序和在代碼中調用的順序是不一樣的。比如下面的SConstruct文件
print("Generate test.c")
Program('test.c')
print("Generate test1.c")
Program('test1.c')
下面是執行結果,可以看到首先是打印的print中的語句,然后是再執行Build的步驟。
scons: Reading SConscript files ...
Generate test.c
Generate test1.c
scons: done reading SConscript files.
scons: Building targets ...
gcc -o test.o -c test.c
gcc -o test test.o
gcc -o test1.o -c test1.c
gcc -o test1 test1.o
scons: done building targets.
鏈接library:
在代碼開發中,經常會import其他團隊或者是已經存在的模塊中的函數。這就需要鏈接其他的目標文件。
在src中文件中有func.o文件。Func中代碼如下:
#include <stdio.h>
void print_in()
{
printf("print_info\n");
}
在main.c中引用了print_in函數
#include <stdio.h>
void main()
{
print_in();
printf("hello world\n");
}
Sconstruct腳本如下
from SCons.Script import *
from scons.SCons import *
env = Environment()
env.Append(LIBPATH=['./src']) //設置LIBPATH,告訴scons去哪個路徑找library
env.Program('scon_test.c',LIBS=['func']) //在設置要import的LIBS, 告訴scons找哪個library
執行腳本如下。在gcc中設置了-L和-l的配置
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o scon_test.o -c scon_test.c
scon_test.c: In function 'main':
scon_test.c:7:5: warning: implicit declaration of function 'print_in'; did you mean 'printf'? [-Wimplicit-function-declaration]
print_in();
^~~~~~~~
printf
gcc -o scon_test scon_test.o -Lsrc -lfunc
scons: done building targets.
同樣的如果我們要去其他路徑查找.h的頭文件,也可以通過設置CPPATH參數。
Main.c中include了var.h
#include <stdio.h>
#include "var.h"
void main()
{
printf("var=%d\n",para);
printf("hello world\n");
}
var.h在inc路徑下面
#ifndef __var_h__
#define para 3
#define __var_h__
#endif
Sconstruct文件,通過設置CPPPATH就可以告訴scons去哪查找頭文件
from SCons.Script import *
from scons.SCons import *
env = Environment()
print("cc=%s" % env['CC'])
env.Program('scon_test.c', CPPPATH=['./inc'])
執行結果如下:可以看到添加了-I的配置
scons: Reading SConscript files ...
cc=gcc
scons: done reading SConscript files.
scons: Building targets ...
gcc -o scon_test.o -c -Iinc scon_test.c
gcc -o scon_test scon_test.o
scons: done building targets.