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.