SCons使用说明

2023-11-01 12:48
文章标签 使用 说明 scons

本文主要是介绍SCons使用说明,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转自:http://550480286.blog.163.com/blog/static/99093247201077113029413/
介绍,scons用的是python语法。需要安装python和scons后才能运行,能够跨平台。比较automake自动生成makefile文件,scons可以认为直接是make的功能,因为只需要执行scons命令就等于执行了make的功能。
现在有一个hello.c的文件。
新建一个SConstruct文件,是一个python脚本文件。
Program('hello.c')   编译hello.c并生成.o文件和可执行文件
Object('hello.c')    编译hello.c但只生成生成.o文件
这两个方法都是python的method。
如果想执行clean操作,我们不需要再象makefile那样指名make clean语句,而是直接执行scons -c 或者scons -clean就可以。程序会根据SConstruct文件内容自动清除。
 
SConstruct的读取和执行顺序是彼此独立的,直接看以下例子。
SConstruct文件内容:
       print "Calling Program('hello.c')"     Program('hello.c')print "Calling Program('goodbye.c')"     Program('goodbye.c')print "Finished calling Program()"
执行结果:
 % sconsscons: Reading SConscript files ...Calling Program('hello.c')    (1)Calling Program('goodbye.c')   (2)Finished calling Program()scons: done reading SConscript files.scons: Building targets ...cc -o goodbye.o -c goodbye.c    (2)cc -o goodbye goodbye.o          (1)cc -o hello.o -c hello.ccc -o hello hello.oscons: done building targets.
由于在执行scons时一些输出信息反而会混淆我们,所以可以加参数  -Q来关闭一些输出提示。
Program('new_hello', 'hello.c') #第一个参数可以指定目标文件名字,默认为hello,第二个参数就是source files。
多源文件编译指定:
Program('program', ['prog.c', 'file1.c', 'file2.c']) #如果没有第一个参数,则以第二个参数(这是一个python list,用【】表示)的第一个元素为program的名字。
如果你觉得列表里面每个文件都需要带一个引号太麻烦,可以利用
Program('program', Split('main.c file1.c file2.c')) #这里的split函数是返回一个列表
也可以这么用来提高可读性
src_files = Split('main.c file1.c file2.c')    #中间多少个空格无所谓
Program('program', src_files)
也可利用Glob函数获得名字列表,Golb('*.c')返回规则匹配的string列表,就是类似上面的'prog.c', 'file1.c', 'file2.c'。
Program('program', Glob('*.c'))

两个关键字可以直接指明target和source,所以在Program

src_files = Split('main.c file1.c file2.c')
Program(target = 'program', source = src_files)
src_files = Split('main.c file1.c file2.c')
Program(source = src_files, target = 'program') #可以调换参数顺序

多工程共享source files的话:
       common = ['common1.c', 'common2.c'] #把共同的文件列表单独提取出来,以便维护foo_files = ['foo.c'] + commonbar_files = ['bar1.c', 'bar2.c'] + commonProgram('foo', foo_files)Program('bar', bar_files)
building library:
Library('foo', ['f1.c', 'f2.c', 'f3.c'])    #文件列表   #静态库
Library('foo', ['f1.c', 'f2.o', 'f3.c', 'f4.o']) #文件列表喝object文件
StaticLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])  #静态library,其实跟Library调用没区别,只是显示强调是静态库
SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c'])  #共享库,类似dll

The output on POSIX:

        % scons -Qcc -o f1.os -c f1.ccc -o f2.os -c f2.ccc -o f3.os -c f3.ccc -o libfoo.so -shared f1.os f2.os f3.os

link library:

     Library('foo', ['f1.c', 'f2.c', 'f3.c'])Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.')  #指定库,指定库的路径。
注意-l,-L,-i,-I的用法。
LIBPATH变量:
LIBPATH = '/usr/lib:/usr/local/lib'  #unix用:分开
 LIBPATH = 'C:\\lib;D:\\lib'   #windows用;分开
CPPPATH变量:类似 -I指定,指定编译目录     #声明了这个选项是用于隐式依赖,比如某些cpp文件包含了h文件,当这些h文件更改时,就会重编这些cpp对应的对象。每次编译的时候,会去搜索这些隐式依赖,所以会消耗一些时间
Program('hello.c', CPPPATH = '.')  #这里会让编译器同时关注hello.c里面include的h文件

Program('hello.c', CPPPATH = ['include', '/home/project/inc'])
编译结果:
% scons -Q hellocc -o hello.o -c -Iinclude -I/home/project/inc hello.ccc -o hello hello.o
--implicit-cache参数可让scons高速缓存哪些隐式依赖关系,这样能减少搜索隐私依赖的时间。如:
% scons -Q --implicit-cache hellocc -o hello.o -c hello.ccc -o hello hello.o% scons -Q helloscons: `hello' is up to date.
当你不想每次都输入这个参数时,可以在SConstruct文件中加入这个语句:SetOption('implicit_cache', 1)
有时scons扫描器检查不出一些文件的依赖性,可以利用Depends函数显示地的指明依赖性:
       hello = Program('hello.c')Depends(hello, 'other_file')
如果想让某个依赖文件改变时不重编,可以用Ignore函数设置忽略这些依赖性:
      hello_obj=Object('hello.c')hello = Program(hello_obj)Ignore(hello_obj, 'hello.h')
每次都想重编一个目标,可用AlwaysBuild函数设置:
      hello = Program('hello.c')AlwaysBuild(hello)
环境变量:有三种,外部环境变量(外部环境信息),scons环境变量(控制scons行为的变量),执行环境变量。变量是很多变量的集合,包括变量名和变量值。
env = Environment()   #创建默认的环境变量,默认scons会按编译器的默认选项来进行编译
import osenv = Environment(CC = 'gcc',CCFLAGS = '-O2') #创建并设置环境 变量env.Program('foo.c')
 % scons -Qgcc -o foo.o -c -O2 foo.cgcc -o foo foo.o
环境变量访问:env = Environment()
            print "CC is:", env['CC']
另一种访问环境变量的方法,试用环境变量的subst方法,而且它还对下面的变量不断展开直到无法继续展开,例如下面两个例子:
env = Environment(CCFLAGS = '-DFOO')print "CCCOM is:", env['CCCOM']          #输出 CCCOM is: $CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINC                                                   FLAGS -c -o $TARGET $SOURCES
       print "CCCOM is:", env.subst('$CCCOM')  #输出  CCCOM is: gcc -DFOO -c -o  #这里将上面的变量值展开了
默认环境DefaultEnvironment(); 试用方法跟上面的环境变量一样,不过控制范围是默认的所有配置。在默认环境中设置好一些变量,可以提高编译速度,比如在默认环境变量中制定了编译器的位置,这样的话可以省去搜索 默认编译器位置的 消耗。如:
env = DefaultEnvironment(tools = ['gcc', 'gnulink'], CC = '/usr/local/bin/gcc') #显式指定编译器位置
多环境变量:  opt = Environment(CCFLAGS = '-O2')
           dbg = Environment(CCFLAGS = '-g')opt.Program('foo', 'foo.c')dbg.Program('bar', 'bar.c')
复制环境变量:env = Environment(CC = 'gcc')
         opt = env.Clone(CCFLAGS = '-O2')dbg = env.Clone(CCFLAGS = '-g')env.Program('foo', 'foo.c')o = opt.Object('foo-opt', 'foo.c')opt.Program(o)d = dbg.Object('foo-dbg', 'foo.c')dbg.Program(d)
替换环境变量值:env = Environment(CCFLAGS = '-DDEFINE1')
            env.Replace(CCFLAGS = '-DDEFINE2')env.Program('foo.c')
替换注意事项: env = Environment(CCFLAGS = '-DDEFINE1')   #-DDEFINE1
         print "CCFLAGS =", env['CCFLAGS']    env.Program('foo.c')env.Replace(CCFLAGS = '-DDEFINE2')    #-DDEFINE2print "CCFLAGS =", env['CCFLAGS']env.Program('bar.c')
           #上面设置了两次,但当程序开始编译的时候,只会以最后一次配置的值为准,所以请看下面的结果:
 % sconsscons: Reading SConscript files ...CCFLAGS = -DDEFINE1CCFLAGS = -DDEFINE2scons: done reading SConscript files.scons: Building targets ...cc -o bar.o -c -DDEFINE2 bar.ccc -o bar bar.occ -o foo.o -c -DDEFINE2 foo.ccc -o foo foo.oscons: done building targets.

这篇关于SCons使用说明的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/323078

相关文章

Java中使用Java Mail实现邮件服务功能示例

《Java中使用JavaMail实现邮件服务功能示例》:本文主要介绍Java中使用JavaMail实现邮件服务功能的相关资料,文章还提供了一个发送邮件的示例代码,包括创建参数类、邮件类和执行结... 目录前言一、历史背景二编程、pom依赖三、API说明(一)Session (会话)(二)Message编程客

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

使用Python实现高效的端口扫描器

《使用Python实现高效的端口扫描器》在网络安全领域,端口扫描是一项基本而重要的技能,通过端口扫描,可以发现目标主机上开放的服务和端口,这对于安全评估、渗透测试等有着不可忽视的作用,本文将介绍如何使... 目录1. 端口扫描的基本原理2. 使用python实现端口扫描2.1 安装必要的库2.2 编写端口扫

使用Python实现操作mongodb详解

《使用Python实现操作mongodb详解》这篇文章主要为大家详细介绍了使用Python实现操作mongodb的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、示例二、常用指令三、遇到的问题一、示例from pymongo import MongoClientf

SQL Server使用SELECT INTO实现表备份的代码示例

《SQLServer使用SELECTINTO实现表备份的代码示例》在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误,在SQLServer中,可以使用SELECTINT... 在数据库管理过程中,有时我们需要对表进行备份,以防数据丢失或修改错误。在 SQL Server 中,可以使用 SE

使用Python合并 Excel单元格指定行列或单元格范围

《使用Python合并Excel单元格指定行列或单元格范围》合并Excel单元格是Excel数据处理和表格设计中的一项常用操作,本文将介绍如何通过Python合并Excel中的指定行列或单... 目录python Excel库安装Python合并Excel 中的指定行Python合并Excel 中的指定列P

浅析Rust多线程中如何安全的使用变量

《浅析Rust多线程中如何安全的使用变量》这篇文章主要为大家详细介绍了Rust如何在线程的闭包中安全的使用变量,包括共享变量和修改变量,文中的示例代码讲解详细,有需要的小伙伴可以参考下... 目录1. 向线程传递变量2. 多线程共享变量引用3. 多线程中修改变量4. 总结在Rust语言中,一个既引人入胜又可

golang1.23版本之前 Timer Reset方法无法正确使用

《golang1.23版本之前TimerReset方法无法正确使用》在Go1.23之前,使用`time.Reset`函数时需要先调用`Stop`并明确从timer的channel中抽取出东西,以避... 目录golang1.23 之前 Reset ​到底有什么问题golang1.23 之前到底应该如何正确的

详解Vue如何使用xlsx库导出Excel文件

《详解Vue如何使用xlsx库导出Excel文件》第三方库xlsx提供了强大的功能来处理Excel文件,它可以简化导出Excel文件这个过程,本文将为大家详细介绍一下它的具体使用,需要的小伙伴可以了解... 目录1. 安装依赖2. 创建vue组件3. 解释代码在Vue.js项目中导出Excel文件,使用第三

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s