Chinaunix首页 | 论坛 | 博客
  • 博客访问: 33290
  • 博文数量: 4
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-04 12:11
文章分类

全部博文(4)

文章存档

2016年(1)

2015年(2)

2014年(1)

我的朋友

分类: 系统运维

2015-04-20 17:31:53

原文链接:http://blog.csdn.net/sealyao/article/details/6402257


点击(此处)折叠或打开

  1. 一、概述

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

  6.  

  7. 二、scons文件

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

  10.   

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

  13.  

  14. 三、scons的命令行参数
  15.     scons: 执行SConstruct中脚本
  16.     scons -c clean
  17.     scons -Q 只显示编译信息,去除多余的打印信息
  18.     scons -Q --implicit-cache hello 保存依赖关系
  19.                    --implicit-deps-changed 强制更新依赖关系
  20.                    --implicit-deps-unchanged 强制使用原先的依赖关系,即使已经改变

  21.  

  22. 四、SConstruct提供的方法

  23. 1、Program:生成可执行文件

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

  30.     Program(Glob("*.c"))
  31.     src = ["hello.c","foo.c"];Program(src)
  32.   
  33. 2、Object:生成目标文件

  34.     Object('hello.c') 编译hello.c目标文件,根据系统自动生成(hello.obj on Windows; hello.o on POSIX)
  35.  
  36. 3、Library:生成静态/动态库文件

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

  40.     库的使用:

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

  42.  

  43. 4、SourceSignatures:判断源文件是否修改
  44.     SourceSignatures('MD5') 根据内容是否改变,默认方式
  45.     SourceSignatures('timestamp') 根据修改时间

  46.  

  47. 5、TargetSignatures:判断目标文件是否改变
  48.     TargetSignatures('build') 根据编译结果
  49.     TargetSignatures('content') 根据文件内容,如果只是加了句注释,将不会被重新编译
  50.  
  51. 6、Ignore:忽略依赖关系

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

  53.  

  54. 7、Depends:明确依赖关系

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

  56.  

  57. 8、SConscript:scons的配置文件。

  58.     源文件的目录结构如下:
  59.     src:
  60.     | SConstruct
  61.     | test.cpp
  62.     | mA(目录)
  63.          | SConscript
  64.          | func.cpp
  65.     其中test.cpp为主文件,中调用func.cpp中定义的函数
  66.   
  67.     SConstruct内容如下:

  68.        
  69. [cpp] view plaincopy
  70. subobj = SConscript(['mA/SConscript'])
  71. obj = subobj + Object(Glob("*.cpp"))
  72. Program("test",list(obj))
  73.   
  74.     SConscript内容 :
  75.        
  76. [cpp] view plaincopy
  77. obj = Object(Glob("*.cpp"))
  78. Return("obj")
  79.     
  80.     上例中,在主目录中执行 scons就可以编译整个"工程"。SConstruct编译主目录中的test.cpp,并通过SConscript编译mA目录下的源文件,并最终生成可执行文件;SConscript用于编译mA中的func.cpp并把生成的func.o传递给主目录的SConstruct。

  81.   
  82. 10.env:环境变量
  83.      环境变量用于设置在编译过程中的各种参数,可以用下面的SConstruct打印环境变量的所有信息(实际上env就是一个python字典)
  84.      可以使用如下的SConstruct查看环境变量的内容:
  85.        
  86. [cpp] view plaincopy
  87. env = Environment()
  88. dict = env.Dictionary()
  89. keys = dict.keys()
  90. keys.sort()
  91. for key in keys:
  92.     print "construction variable = '%s', value = '%s'" % (key, dict[key])
  93.       
  94.      环境变量的使用:
  95.          env = Environment() #创建默认的环境变量,默认scons会按编译器的默认选项来进行编译
  96.          import os
  97.          env = Environment(CC = 'gcc',CCFLAGS = '-O2') #创建并设置环境 变量
  98.          env.Program('foo.c')

  99.      环境变量的复制:
  100.          env = Environment(CC = 'gcc')
  101.          opt = env.Clone(CCFLAGS = '-O2')
  102.          dbg = env.Clone(CCFLAGS = '-g')

  103.      环境变量的替换:
  104.          env = Environment(CCFLAGS = '-DDEFINE1')
  105.          env.Replace(CCFLAGS = '-DDEFINE2')
  106.          env.Program('foo.c')
  107.      环境变量的输入输出:用于统一多目录源文件的编译选项,如:
  108.      src:
  109.      | SConstruct
  110.      | libstlport.a
  111.      | test.cpp
  112.      | include(目录)
  113.           | foo.h
  114.      | mA(目录)
  115.           | SConscript
  116.           | func.cpp
  117.    

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

  119.      SConstruct如下:
  120.       
  121. [cpp] view plaincopy
  122. env = Environment()
  123. flags = env.ParseFlags(['-pthread -I/usr/include/stlport ',' -L .'])
  124. env.MergeFlags(class_flags)
  125. subobj = SConscript(['mA/SConscript'])
  126. obj = subobj + env.Object(Glob("*.cpp"))
  127. env.Program("test",list(obj),LIBS = ['libstlport.a'])
  128.     mA/SConscrip如下:
  129.       
  130. [cpp] view plaincopy
  131. obj = Object(Glob("*.cpp"))
  132. Return("obj")
  133.   


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

  136.      解决问题的办法就是环境变量输出,修改SConstruct和mA/SConscript如下:
  137.     SConstruct:
  138.        
  139. [cpp] view plaincopy
  140. env = Environment()
  141. flags = env.ParseFlags(['-pthread -I/usr/include/stlport ',' -L .'])
  142. env.MergeFlags(class_flags)
  143. Export('env')
  144. subobj = SConscript(['mA/SConscript'],exports = 'env')
  145. obj = subobj + env.Object(Glob("*.cpp"))
  146. env.Program("test",list(obj),LIBS = ['libstlport.a'])
  147.  
  148.     mA/SConscript:
  149.       
  150. [cpp] view plaincopy
  151. Import('env')

阅读(1649) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~