scons 简要说明

文章目录

  • scons 简要说明
    • 写在前面
      • scons和make有什么不同
      • scons 安装
    • scons 的基本使用
      • 1. 编译单个文件和常用的操作介绍
      • 2. 指明编译目标
      • 2. 编译多个文件和文件的自动搜索
      • 3. 拆分出汇编阶段和各个编译阶段的选项控制
      • 4. 分离编译文件
      • 5. 防止一些分支处理被忽略(env.Depends)(往下写不动了)
      • 6. 目标换名和闭环依赖链条env.Alias(目标名,源目标)
      • 7. command 编译
    • scons 进阶
      • 1. 防止环境变量冲突
      • 2. 导入外部环境变量
      • 3. 如多个项目编译方法一致,可使用参数文件方式带入差异
      • 3. 不在依赖链条上的项目会执行0次或者执行两次

写在前面

scons和make有什么不同

make中使用了目标和为伪目标相互依赖的方法将需要编译的项目和
依赖的目标链接起来。比如一个.bin文件依赖.o ,而.o文件依赖于
.s 或者.c。

对于编译项目,需要处理的基本问题就是如上的需求。
而scons的编译函数中都有一个编译目标 和编译来源的入参,因此scons
在编译过程中会自动推导依赖关系,而不用显示的去指明依赖链条.

scons 安装

pip install scons

scons 的基本使用

1. 编译单个文件和常用的操作介绍

  1. 如何编译一个单文件
    1.1 比如现在需要编译一个main.cpp,在main.cpp所在目录执行下边命令

    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ echo Program\(\"main.cpp\"\) > Sconstruct
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cat Sconstruct
    Program("main.cpp")
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    g++ -o main.o -c main.cpp
    g++ -o main main.o
    scons: done building targets.
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ ls
    main  main.cpp  main.o  Sconstruct
    

    1.2 分析上边的过程Program函数是用来生成最终的执行目标,可以自动推导默认的编译方法编译出最终目标

  2. 清理项目
    2.1 清理命令是 scons -c

    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ ls
    main  main.cpp  main.o  Sconstruct
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -c
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Cleaning targets ...
    Removed main.o
    Removed main
    scons: done cleaning targets.
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ ls
    main.cpp  Sconstruct
    

    2.2 scons 上不用去专门编写项目的清理方法,scons会自动由最终结果往前的这个链条上所有中间文件,并删除掉

  3. 打印依赖树
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons --tree=all
    scons: Reading SConscript files ...
    scons: done reading SConscript files.
    scons: Building targets ...
    g++ -o main.o -c main.cpp
    g++ -o main main.o
    +-.+-Sconstruct+-main| +-main.o| | +-main.cpp| | +-/usr/bin/g++| +-/usr/bin/g+++-main.cpp+-main.o+-main.cpp+-/usr/bin/g++
    scons: done building targets.
    
  4. 静默编译
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -Q
    g++ -o main.o -c main.cpp
    g++ -o main main.o
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -c -Q
    Removed main.o
    Removed main
    
  5. 为输出目标命名
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ echo Program\(\"nice\",\"main.cpp\"\) >      Sconstruct
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cat Sconstruct
    Program("nice","main.cpp")
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -Q
    g++ -o main.o -c main.cpp
    g++ -o nice main.o
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ ls
    main.cpp  main.o  nice Sconstruct
    

2. 指明编译目标

  1. 项目中常遇到一个工程下有多个编译目标,但有时只想生成其中一个,全量编译会消耗很多时间

    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cp main.cpp main2.cpp
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ echo Program\(\"main2.cpp\"\) >> Sconstruct
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -Q
    g++ -o main.o -c main.cpp
    g++ -o main main.o
    g++ -o main2.o -c main2.cpp
    g++ -o main2 main2.o
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -c -Q
    Removed main.o
    Removed main
    Removed main2.o
    Removed main2
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -Q main2
    g++ -o main2.o -c main2.cpp
    g++ -o main2 main2.o
  2. 前三个命令可以看出如果有多个目标在Sconstruct 文件内时不指定目标时会生成全部目标,指明目标时只生成目标

2. 编译多个文件和文件的自动搜索

  1. 参数2位置可以是一个列表

    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cat Sconstruct
    Program("nice",["main.cpp","res/help.cpp"])
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -Q
    g++ -o main.o -c main.cpp
    g++ -o res/help.o -c res/help.cpp
    g++ -o nice main.o res/help.o
    
  2. 使用Glob函数搜索源文件
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cat Sconstruct
    file=Glob("*.cpp") + Glob("*/*.cpp")
    print(file)
    Program("nice",file)
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -Q
    [<SCons.Node.FS.File object at 0x56510efe8698>, <SCons.Node.FS.File object at 0x56510efe9b08>]
    g++ -o main.o -c main.cpp
    g++ -o res/help.o -c res/help.cpp
    g++ -o nice main.o res/help.o
    

    这里看到Glob函数能做模糊匹配的方式匹配到源文件,并且搜到的源文件可以参与到编译中

  3. Glob 的结果可以转化成字符串再进行编译,这个方法主要是针对比如并非所有源文件可以使用统一参数编译,或者要分步编译时.cpp替换成.o 或者.s
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cat Sconstruct
    file=Glob("*.cpp") + Glob("*/*.cpp")
    tmp_file = []
    for item in file:tmp_file.append(str(item))
    print(tmp_file)
    Program("nice",file)
    ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons -Q
    ['main.cpp', 'res/help.cpp']
    g++ -o main.o -c main.cpp
    g++ -o res/help.o -c res/help.cpp
    g++ -o nice main.o res/help.o

3. 拆分出汇编阶段和各个编译阶段的选项控制

工程应用中经常会遇到各个阶段编译参数不一致的情况,需要拆分出单个步骤进行编译

ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cat Sconstruct
env = Environment()
env2 = env.Clone()
env3 = env.Clone()
#1. 设置汇编阶段
env["CC"] = "g++"
env["CCFLAGS"] = ["-DCCFLAG","-S"]
env["OBJSUFFIX"] = [".s"]
#2. 设置编译阶段
env2["AS"] = "g++"
env2["ASFLAGS"] = ["-DASFLAGS","-c"]
env2["OBJSUFFIX"] = [".o"]
#3. 设置链接阶段
env3["LINK"] = "g++"
env3["LINKFLAGS"] = ["-DLINKFALGS",]outfile1 = env.Object("main.s","main.cpp")
outfile2 = env2.Object("main.o","main.s")
env3.Program("aaa", "main.o")ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o main.s -c -DCCFLAG -S main.cpp
g++ -DASFLAGS -c -o main.o main.s
g++ -o aaa -DLINKFALGS main.o
scons: done building targets.

4. 分离编译文件

Sconstruct 文件是一个工程的编译入口,一般在大型工程中不能将所有编译过程全部放到入口文件中,这样会导致工程可读性变差。


ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ tree
.
├── build
│   └── file1
├── Sconstruct
└── source└── pro1└── main.cpp4 directories, 6 files
ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cat Sconstruct
file1 = "build/file1"
SConscript(file1)
ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ cat build/file1
import os
env = Environment()
#这里路径最多退到Sconstruct 这一层
soruce_dir = "../source/pro1"
srcfile = ["main.cpp",]
usefile = [os.path.join(soruce_dir,f) for f in srcfile]
env.Program("aaa", usefile)ggg@ggg-X550JX ~/test_demo/test_demo/pro1 $ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o source/pro1/main.o -c source/pro1/main.cpp
g++ -o build/aaa source/pro1/main.o
scons: done building targets.

根据命令输入目标缩小搜查范围,并只做部分编译(待完善)

5. 防止一些分支处理被忽略(env.Depends)(往下写不动了)

6. 目标换名和闭环依赖链条env.Alias(目标名,源目标)

7. command 编译

comd="md5sum $SOURCE > $TAEGET"target2 =env.Command("output.md5",srcfile,comd)

scons 进阶

1. 防止环境变量冲突

env.Clone()
#单个环境下如果重复给同一个环境进行环境变量替换,那么最终编译时候都会按最后一次赋值进行编译

2. 导入外部环境变量

pipe=os.open("%s 2>&1;echo ---;env" %cmd,"r")text=pip.read()sts=pipe.close()最终解析出需要的环境变量添加到os.environ[k] =v

3. 如多个项目编译方法一致,可使用参数文件方式带入差异

# 在编译文件内进行区别的进行import 导入参数文件(python 格式的变量)

3. 不在依赖链条上的项目会执行0次或者执行两次

# 部分打印信息令人迷惑,实际上可能会被执行两次以上

scons的使用方法和进阶相关推荐

  1. 串口显示数字文本的巧妙使用方法3进阶版

    如何去除(串口显示数字文本的巧妙使用方法2进阶版)数字前面的0 如下图 去除方法还没写哈哈哈

  2. C语言三个数排序,普通方法及进阶(不引入第三变量交换数值法)

    输入 三个整数a,b,c 输出 按从大到小的顺序输出 普通方法:将三个数大小情况全部列出 #include<stdio.h>int main() {int x,y,z;scanf(&quo ...

  3. kvc实践一:核心方法和进阶

    kvc概念和核心方法 NSObject类中,有一个显示的类别名NSKeyValueCoding(缩写kvc),所以继承自NSObject的类都可以使用kvc,下面是kvc的4个主要方法: - (nul ...

  4. IntelliJ IDEA使用技巧(七)——恢复代码的方法(进阶篇)

    2019独角兽企业重金招聘Python工程师标准>>> 在上一篇文章中,咱们已经了解了如何将代码恢复至某一版本,但是通过Local History恢复代码有的时候并不方便,例如咱们将 ...

  5. 2-jQuery - AJAX load() 方法【进阶篇】

    第一篇的AJAX load() 方法过于简单,补充一下,完整的. 格式 $(selector).load(URL,data,callback); 源码 <!DOCTYPE html> &l ...

  6. android对象序列化的方法,Android 进阶-两种序列化方式 Serializable 和 Parcelable

    [导读]序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.在序列化期间,对象将其当前状态写入到临时或持久性存储区.以后,可以通过从存储区中读取或反序列化对象的状态 ...

  7. python魔术方法(进阶)斐波那契数列

    文章目录 特殊属性 查看属性 实例化 可视化 hash bool 运算符重载应用场景 容器相关方法 可调用对象 上下文管理 上下文管理的安全性 方法的参数 contextlib.contextmana ...

  8. SCons 构建工具

    SCons 简介 SCons 是一套由 Python 语言编写的开源构建系统,类似于 GNU Make.它采用不同于通常 Makefile 文件的方式,而是使用 SConstruct 和 SConsc ...

  9. Kaggle知识点:数据扩增方法

    在Kaggle视觉竞赛中,数据扩增(Data Augmentation)是不可少的环节.数据扩增可以增加训练集的样本,同时也可以有效环节模型过拟合的情况,也可以给模型带来的更强的泛化能力.本文将全面介 ...

最新文章

  1. Tricky Sum
  2. 【ijkplayer】编译 Android 版本的 ijkplayer ⑥ ( 进入 ijkplayer-android/android 目录 | 执行 compile-ijk.sh 脚本完成编译 )
  3. URAL 1091. Tmutarakan Exams
  4. 阿里面试经历JAVA总结
  5. 最受Linux程序员欢迎的7个代码编辑器的介绍及下载地址
  6. 大剑无锋之flume面试题【面试推荐】
  7. SQL实战篇:SQL基础及执行顺序
  8. elasticsearch集群搭建-windows
  9. 浪潮K1 Power通过ISO/IEC 20243标准认证
  10. centos 6.2升级6.5遇到的问题及解决方法
  11. CSS3 响应式布局实例
  12. Postman中对报文进行AES+Base64加密请求
  13. MegaCli查看RIAD相关信息
  14. json转为tfrecord格式文件怎么转_JPG图片怎么转换成PDF?图片转PDF的免费软件有这些...
  15. 2022金属非金属矿山(露天矿山)安全管理人员考试练习题模拟考试平台操作
  16. 两组的数据平均值合并_数据平均值合并计算 合并计算求平均值
  17. python伪原创工具开发_现在有哪些好用的伪原创工具?
  18. 苹果序列号查询api查询序列号和苹果产品信息
  19. 【工具】Typora 自定义快捷键
  20. jquery徽章_城市需要能够获得数字徽章

热门文章

  1. 数字货币量化分析[2018-05-27]
  2. 纽扣电池常识——以CR2450为例
  3. python英汉互译 谷歌翻译 免费实现调用
  4. 企业数据中心“云化”转型解决方案
  5. Mac电脑上如何关闭屏幕时间
  6. 新一配:iPod及其配置介绍【转载】
  7. mysql查询IN索引无效的问题【已解决】
  8. oracle 结果集已耗尽_SQLException:耗尽结果集
  9. 如何实现一款好用的云图(word-cloud)生成工具?
  10. 秒针计时器 html,JS实现一个秒表计时器