目录

简略说明

什么是Scons

遗留疑问:Scons 和cmake 对比如何?

scons对比make

Scons使用

scons文件和命令

二、scons文件

三、scons的命令行参数

四、SConstruct提供的方法

scons报错记录


简略说明

(摘自:https://www.cnblogs.com/m-zhang-yang/p/13228299.html)

Scons命令

scons:进行代码文件编译

scons -Q:进行代码文件编译,不显示Scons内部操作打印的信息,只显示编译信息

scons -c:清除编译中间文件和可执行文件

Scons编译脚本

Scons对应的编译脚本名称为SConstruct,就如同make对应的编译脚本为makefile

SConstruct脚本编写

编译函数

Program():执行编译操作,生成可执行文件

Library():执行编译操作,生成静态库

StaticLibrary():执行编译操作,生成静态库

SharedLibrary():执行编译操作,生成动态库

Environment():编译环境

编译参数

target,生成的执行文件名字

source,编译文件

LIBS,依赖库

LIBPATH,依赖库路径,有环境变量的可不添加,针对用户库或第三方库

CPPPATH,头文件路径

CCFLAGS,编译参数

其他函数

Split():将字符串分隔为列表

Glob('*.cpp'):加入所有文件

编译参数可以以任意顺序加入编译函数,编译函数依据编译参数对代码文件进行编译。

一个简单例子

将文件放在当前目录,头文件放在上级目录。

str = Split('main.cpp display.cpp')
Program('main',str,CPPPATH = '../'i,LIBS = 'pthread')

一个复杂项目的例子

大多项目都可以套用的格式,Program内参数多个文件需要以python列表形式作为入参,这里可以用Split对文件字符串分隔为列表输入。直接用Glob('*.cpp')包含当前目录所有需要编译的cpp文件。

TARGETNAME = 'server'LIB = Split('jsoncpp logger ACE basetool tinyxml pthread dl rt')FILELIST = Glob('*.cpp')HEADFILEPATH = Split('../../common/include ../../3rd/ACE_wrappers ../../3rd/include/')LIB_DIR = Split('../../3rd/lib ../../common/lib')Program(target = TARGETNAME,source = FILELIST,LIBS = LIB,CPPPATH = HEADFILEPATH,LIBPATH = LIB_DIR)

src:
     |    SConstruct
     |    libstlport.a
     |    test.cpp
     |     include(目录):
          |    foo.h
     |    mA(目录):
          |    SConscript
          |    func.cpp

什么是Scons

make

make 工具可以增量编译,缩短编译的时间,但 make 规则复杂,即使老鸟也望而生畏。

Scons是它的同类产品,做的事情跟make一样,但更简单,更容易。

Scons

Scons是一个开源、Python编写的自动化构建工具,并且scons是跨平台的,只要scons脚本写的好,可以在Linux和Windows下随意编译。

SCons 的设计目标就是让开发人员更容易、更可靠和更快速的建造软件。

遗留疑问:Scons 和cmake 对比如何?

待研究。

SCons, CMake 算是第三代构建工具的两个代表。

第一代 DSL 型构建语言 Makefile,是描述构建的规则和依赖关系的绝对王者。

第二代 autotools(automake) 系列,几乎是是整个 Linux 的构建工具,能完成对环境依赖项的检测。但是不是能够轻松驾驭的。如果用 -j 用得比较多,肯定会遇到:出现链接错误,再次运行就能正确的情形。(gn 有 link pool 的支持优雅解决了这个问题)。

SCons, CMake 算是第三代构建工具的两个代表了。
链接:https://www.zhihu.com/question/276415476/answer/557715322

《构建工具之shell,configure,make,cmake,scons,xmake简析总结》:

https://blog.csdn.net/shixin_0125/article/details/78424747

scons对比make

与传统的 make 工具比较,SCons 具有以下优点:

1、 移植性:python能运行的地方,就能运行scons
 2、 扩展性:理论上scons只是提供了python的类,scons使用者可以在这个类的基础上做所有python能做的事情。比如想把一个已经使用了Makefile大型工程切换到scons,就可以保留原来的Makefile,并用python解析Makefile中的编译选项、源/目标文件等,作为参数传递给scons,完成编译。
 3、 智能:Scons继承了autoconf/automake的功能,自动解析系统的include路径、typedef等;“以全局的观点来看所有的依赖关系”

  • 使用 Python 脚本做为配置文件
  • 对于 C,C++ 和 Fortran, 内建支持可靠自动依赖分析 . 不用像 make 工具那样需要 执行"make depends"和"make clean"就可以获得所有的依赖关系。
  • 内建支持 C, C++, D, Java, Fortran, Yacc, Lex, Qt,SWIG 以及 Tex/Latex。 用户还可以根据自己的需要进行扩展以获得对需要编程语言的支持。
  • 支持 make -j 风格的并行建造。相比 make -j, SCons 可以同时运行 N 个工作,而 不用担心代码的层次结构。
  • 使用 Autoconf 风格查找头文件,函数库,函数和类型定义。
  • 良好的夸平台性。SCons 可以运行在 Linux, AIX, BSD, HP/UX, IRIX, Solaris, Windows, Mac OS X 和 OS/2 上。

Scons使用

安装

在 SCons 的官方网站上可以查每个平台的具体安装方法。

Win平台的下载和安装就不说了。

Linux下

方法1:

pip3  install scons

方法2:

下载tar包,执行以下命令即可:

tar -zxf scons-2.0.1.tar.gz
cd scons-2.0.1 
sudo python setup.py install

对于 Linux 来说,scons 会默认安装到 /usr/loca/bin 目录下,而在 Windows 平台上,则会被安装到 C:\Python25\Scripts 下。

使用

这里通过一个简单的示例来说明。

一个hello.c源文件,一个SConstruct文件,后面再解释。

SConstruct

Program("hello.c")

hello.c

#include <stdio.h>

int main(void)
{
    printf("hello, world!\n");

return 0;
}

运行Scons,得到如下:

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o hello hello.o
scons: done building targets.

$ ls
hello  hello.c  hello.o  SConstruct

$ ./hello 
hello, world!

就是这样,程序编译完成了。到这里Scons似乎与make没有什么两样,同样的操作,只是把scons换成make,SConstruct换成Makefile。

对,不同的地方就在于,下面的展示:

$ cat  SConstruct

Program("hello.c")

你没看错,就这一行,编译就完成了!!!

事实确实如此,它比传统的 Makefile 简单很多。SConstruct 以 Python 脚本的语法编写,你可以像编写 Python 脚本一样来编写它。

其中的 Program 是编译的类型,说明你准备想要建造一个可执行的二进制程序,它由 hello.c 文件来生成。

在这里,没有指定生成的可执行程序的名字,SCons 会把源代码文件名字的后缀去掉,用来作为可执行文件的名字。

我们甚至不需要像 Makefile 那样指定清理的动作,就可以执行清理任务。在 SCons 中,执行清理任务由参数 -c 指定,如下 :

$ scons -c

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Cleaning targets ...
Removed hello.o
Removed hello
scons: done cleaning targets.

$ ls
hello.c  SConstruct

相关命令

SCons 支持的编译(目标文件)类型有:

  • Program: Program("hello.c")编译成可执行程序(在 Windows 平台上即是 exe 文件),这是最常用的一种编译类型。
  • Object:Object("hello.c") 只编译成目标文件。使用这种类型,编译结束后,只会产生目标文件。在 POSIX 系统中,目标文件以 .o 结尾,在 Windows 平台上以 .OBJ 结尾。
  • Library: Library("hello.c") 编译成库文件。SCons 默认编译的库是指静态链接库。
  • StaticLibrary: StaticLibrary("hello.c") 显示的编译成静态链接库,与上面的 Library 效果一样。
  • SharedLibrary: SharedLibrary("hello.c") 在 POSIX 系统上编译动态链接库,在 Windows 平台上编译 DLL。

如果不想使用 SConstruct 为你设置的默认可执行文件的名字,而是选择你自己喜欢的名字,如 myhello,可以把 SConstruct 的内容修改为 :

Program('myhello', 'helloscons.c')

其中 myhello就是你想要的可执行文件的名字.

$ scons  -Q
gcc -o hello.o -c hello.c
gcc -o myhello hello.o

Scons入门简介(https://blog.csdn.net/guotianqing/article/details/92003258)

其中,-Q 参数是减少编译时的由 scons 产生的冗余信息。

显式的指定使用某些库:

指定一些编译的宏定义,显式的指定使用某些库:

例子: helloscons2 由 3 个源文件生成 : helloscon2.c, file1.c, file2.c,指定编译选项,同时指定使用哪些具体的库,SConstruct 文件 如下:

Program('helloscons2', ['helloscons2.c', 'file1.c', 'file2.c'], 
       LIBS = 'm', 
       LIBPATH = ['/usr/lib', '/usr/local/lib'], 
       CCFLAGS = '-DHELLOSCONS')

该 SConstruct 文件指出,它将生成名叫 helloscons2 的程序,该程序由 helloscons2.c, file1.c 和 file2.c 组成。

如果源程序代码文件很多,glob(’*.c’) 来代替源代码列表,如下 :

Program('helloscons2', Glob('*.c'))

配置文件中 LIBS,LIBAPTH 和 CCFLAGS 是 SCons 内置的关键字,它们的作用如下:

LIBS: 显示的指明要在链接过程中使用的库,如果有多个库,应该把它们放在一个列表里面。这个例子里,我们使用一个称为 m 的库。
LIBPATH: 链接库的搜索路径,多个搜索路径放在一个列表中。这个例子里,库的搜索路径是 /usr/lib 和 /usr/local/lib。
CCFLAGS: 编译选项,可以指定需要的任意编译选项,如果有多个选项,应该放在一个列表中。这个例子里,编译选项是通过 -D 这个 gcc 的选项定义了一个宏 HELLOSCONS。
CPPPATH:指定头文件的路径

运行 scons 命令的时候,可以看到这些变量如何被使用的,让我们执行一下 scons 命令 :

$ scons -Q 
gcc -o file1.o -c -DHELLOSCONS file1.c 
gcc -o file2.o -c -DHELLOSCONS file2.c 
gcc -o helloscons2.o -c -DHELLOSCONS helloscons2.c 
gcc -o helloscons2 helloscons2.o file1.o file2.o -L/usr/lib -L/usr/local/lib -lm

更多内容

以上只是入门,还有更多知识等待学习。

如,通过Environment指定编译环境,env = Environment(CC = 'g++'),指定使用g++编译程序。

示例如下:

env = Environment(CC = 'g++')
env.Program("client", "client.c", LIBS = 'm', CPPPATH = '../include', CCFLAGS = '-std=c++11')

摘抄自:https://blog.csdn.net/guotianqing/article/details/92003258

scons文件和命令

二、scons文件

scons中可能出现的文件:
        SConstruct,Sconstruct,sconstruct,SConscript

scons将在当前目录以下次序 SConstruct,Sconstruct,sconstruct 来搜索配置文件,从读取的第一个文件中读取相关配置。
    在配置文件SConstruct中可以使用函数SConscript()函数来定附属的配置文件。按惯例,这些附属配置文件被命名为”SConscript”,当然也可以使用任意其它名字。

三、scons的命令行参数

scons: 执行SConstruct中脚本
    scons -c   clean
    scons -Q  只显示编译信息,去除多余的打印信息
    scons -Q   --implicit-cache hello 保存依赖关系
                   --implicit-deps-changed   强制更新依赖关系
                   --implicit-deps-unchanged  强制使用原先的依赖关系,即使已经改变

四、SConstruct提供的方法

1、Program:生成可执行文件

Program('hello.c')  编译hello.c可执行文件,根据系统自动生成(hello.exe on Windows; hello on POSIX)
    Program('hello','hello.c') 指定Output文件名(hello.exe on Windows; hello on POSIX)
    Program(['hello.c', 'file1.c', 'file2.c']) 编译多个文件,Output文件名以第一个文件命名
    Program(source = "hello.c",target = "hello")
    Program(target = "hello" , source = "hello.c")
    Program('hello', Split('hello.c file1.c file2.c')) 编译多个文件

Program(Glob("*.c"))
    src = ["hello.c","foo.c"];Program(src)

2、Object:生成目标文件

Object('hello.c') 编译hello.c目标文件,根据系统自动生成(hello.obj on Windows; hello.o on POSIX)

3、Library:生成静态/动态库文件

Library('foo', ['f1.c', 'f2.c', 'f3.c']) 编译library
    SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c']) 编译 shared library
    StaticLibrary('bar', ['f4.c', 'f5.c', 'f6.c']) 编译 static library

库的使用:

Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.') 连接库,不需加后缀或是前缀

4、SourceSignatures:判断源文件是否修改

SourceSignatures('MD5')     根据内容是否改变,默认方式
    SourceSignatures('timestamp') 根据修改时间

5、TargetSignatures:判断目标文件是否改变

TargetSignatures('build')   根据编译结果
    TargetSignatures('content')  根据文件内容,如果只是加了句注释,将不会被重新编译

6、Ignore:忽略依赖关系

Ignore(hello, 'hello.h')  忽略某个依赖关系

7、Depends:明确依赖关系

Depends(hello, 'other_file') 明确依赖关系

8、SConscript:scons的配置文件。

源文件的目录结构如下:
    src:
    |    SConstruct
    |    test.cpp
    |    mA(目录):
         |     SConscript
         |     func.cpp
    其中test.cpp为主文件,中调用func.cpp中定义的函数
  
    SConstruct内容如下:

subobj = SConscript(['mA/SConscript'])

obj = subobj + Object(Glob("*.cpp"))

Program("test",list(obj))

SConscript内容 :

obj = Object(Glob("*.cpp"))

Return("obj")

上例中,在主目录中执行 scons就可以编译整个"工程"。SConstruct编译主目录中的test.cpp,并通过SConscript编译mA目录下的源文件,并最终生成可执行文件;SConscript用于编译mA中的func.cpp并把生成的func.o传递给主目录的SConstruct。

10.env:环境变量
     环境变量用于设置在编译过程中的各种参数,可以用下面的SConstruct打印环境变量的所有信息(实际上env就是一个python字典)
     可以使用如下的SConstruct查看环境变量的内容:

env = Environment()

dict = env.Dictionary()

keys = dict.keys()

keys.sort()

for key in keys:

print "construction variable = '%s', value = '%s'" % (key, dict[key])

环境变量的使用:

env = Environment()   #创建默认的环境变量,默认scons会按编译器的默认选项来进行编译
         import os
         env = Environment(CC = 'gcc',CCFLAGS = '-O2') #创建并设置环境 变量
         env.Program('foo.c')

环境变量的复制:

env = Environment(CC = 'gcc')
         opt = env.Clone(CCFLAGS = '-O2')
         dbg = env.Clone(CCFLAGS = '-g')

环境变量的替换:

env = Environment(CCFLAGS = '-DDEFINE1')
         env.Replace(CCFLAGS = '-DDEFINE2')
         env.Program('foo.c')

环境变量的输入输出:用于统一多目录源文件的编译选项,如:

src:
     |    SConstruct
     |    libstlport.a
     |    test.cpp
     |     include(目录):
          |    foo.h
     |    mA(目录):
          |    SConscript
          |    func.cpp

test.cpp和mA/func.cpp都引用了include/foo.h,test.cpp调用了mA/func.cpp的功能函数,其中include/foo.h中定义了一个包含string类型的类。

SConstruct如下:

env = Environment()

flags = env.ParseFlags(['-pthread -I/usr/include/stlport ',' -L .'])

env.MergeFlags(class_flags)

subobj = SConscript(['mA/SConscript'])

obj = subobj + env.Object(Glob("*.cpp"))

env.Program("test",list(obj),LIBS = ['libstlport.a'])

mA/SConscrip如下:

obj = Object(Glob("*.cpp"))

Return("obj")

不出意外的话上边的工程编译可以通过,但是运行的时候会Aborted。因为test.cpp,mA/func.cpp都使用了包含string类型的那个类,但是由于编译环境的不同,test.cpp认为string变量的大小是24字节, mA/func.cpp认为string变量的大小是4个字节(libstlport.a捣的鬼)。

解决问题的办法就是环境变量输出,修改SConstruct和mA/SConscript如下:
    SConstruct:

env = Environment()

flags = env.ParseFlags(['-pthread -I/usr/include/stlport ',' -L .'])

env.MergeFlags(class_flags)

Export('env')

subobj = SConscript(['mA/SConscript'],exports = 'env')

obj = subobj + env.Object(Glob("*.cpp"))

env.Program("test",list(obj),LIBS = ['libstlport.a'])

mA/SConscript:

Import('env')

obj = env.Object(Glob("*.cpp"))

Return("obj")

scons报错记录

现象:check for xxx……no

check for xxx……no,不一定是找不到xxx的错误,可能是生成某个库,或者设置导致的错误,具体原因可以查看config.log文件:/home/ceastor/config.log

【c++】Scons|scons对比make相关推荐

  1. [笔记分享] [SCons] SCons工具之Manipulation

    之前给同事培训的的ppt讲义,分享给大家.

  2. Scons构建C++项目

    旧博文,搬到 csdn 原文:http://rebootcat.com/2020/08/30/scons/ 前言 我是一个 linux c++ 开发者,但是一直对 Makefile 的语法很是头痛,每 ...

  3. 使用 SCons 轻松建造程序

    原文:http://www.ibm.com/developerworks/cn/linux/l-cn-scons/index.html 参考:http://www.flatws.cn/article/ ...

  4. SCons — 程序构建工具

    目录 文章目录 目录 SCons - a software construction tool 使用示例 SCons - a software construction tool SCons 类似于 ...

  5. c++构建工具之shell,configure,make,cmake,scons,xmake简析总结

    前言 说到编译工具,在windows下必言vs,在linux下必言make. 0.shell 如果编译一个库的命令太复杂或者为了方便,我们更愿意将编译命令写成一个shell脚本来执行,比如build. ...

  6. 使用 SCons 代替 Makefile 快速构建应用程序

    使用 SCons 代替 Makefile 快速构建应用程序 2012-03-22 01:37 2971人阅读 评论(5) 收藏 举报 makefilefilegccpython工具build 目录(? ...

  7. SCons: A software construction tool

    SCons: A software construction tool What is SCons? SCons is an Open Source software construction too ...

  8. python自动化构建工具_Python自动化构建工具scons使用入门笔记

    这段时间用到了scons,这里总结下,也方便我以后查阅. 一.安装sconsLinux环境(以CentOS为例) 1.yum安装 yum install scons 2.源码安装 下载scons:ht ...

  9. 随想录(scons编译)

    [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] scons是基于python的一种编译方法.所有编译脚本的编写,和编写python脚本是一样的 ...

最新文章

  1. Python学习之字典
  2. Python全栈(第一部分)day2
  3. elasticSearch6源码分析(3)cluster模块
  4. ngnix有版本要求吗_联想小新15 2020款值得入手吗?性能怎么样?不可不看的秘密...
  5. linux mysql 修改字符集_linux下mysql修改字符集,远程连接
  6. 判断是否为长按_如何判断电路中的IC是在工作?
  7. Hive-1.2.0学习笔记(四)Hive表管理
  8. 创业团队如何在低成本的情况下保护网站安全
  9. 用OpenCV制作一个低成本的立体相机
  10. php2.3.2,自动加载 - ThinkPHP3.2完全开发手册
  11. linux安装Hive(Hive-2.3.7)
  12. 曲苑杂坛--DML操作中如何处理那些未提交的数据
  13. 2022年01月最新 | 全国网络安全等级测评与检测评估机构目录,新增6家,共计224家...
  14. windows如何安装SVN
  15. Week 7 Homework
  16. 关于微信开发者平台移动应用(android)获取签名问题
  17. 花呗部分用户已接入央行征信系统,快看你被选中了没?
  18. MTK开发之cpu核开关与频率调节
  19. sso单点登录与Jsonp
  20. java实时获取汇率

热门文章

  1. 操作系统课后习题答案(作业题)
  2. ch06-物理系统与碰撞——Arrowshooting射箭小游戏
  3. EMNLP22评测矩阵:FineD-Eval: Fine-grained Automatic Dialogue-Level Evaluation
  4. SLAM入坑之一:用realsense D415跑一下ORB-SLAM在ROS-melodic上
  5. INTEL RealSense-D415 在 Ubuntu 16.04 开发流程 1
  6. segmentControl实现控制器的切换
  7. js巧用 ‘~‘运算符
  8. 精准医学:对治疗有特殊响应的肿瘤的分子特征|精准治疗
  9. MFC加载图标,位图。LoadImage LoadIcon, LoadBitmap
  10. Fabric-跨链码访问