linux下使用Scons构建自己的项目程序

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shitangdejiaozi/article/details/51499591

原来简单介绍了一种项目自动编译的工具cmake,不过它基本是针对与c++程序而设计的,我感觉cmake已经很方便了,比写Makefile要舒服多了,最近又看到一个scons,瞬间感觉scons才是真爱啊。

scons简介

SCons 是一个开放源代码、以 Python 语言编写的下一代的程序建造工具。它最初的名字是 ScCons, 基于由 perl 语言编写的 Cons 软件开发而成,它在 2000 年 8 月获得了由 Software Carpentry 举办的 SC 建造比赛的大奖。现在 ScCons 已经被改名为 SCons,目的是为了表示不再与 Software Carpentry 有联系,当然,还有一个目的,就是为了更方便的输入。

使用

先安装:
最简单粗暴

sudo apt-get install scons

当然你也可以去下载压缩包再自己安装。

一,SConstruct 文件

它是scons用来控制编译的文件,类似MakeFile,是一个Python脚本,它告诉scons做什么,而不是严格的规定scons做这件事的步骤。

二,scons 运行选项

运行:scons
1,-c 就是清理你创建的文件,就是make clean
2, -Q 就是省略自带的一堆废话,只显示编译过程

三,SConstrcut文件编写基础

1.scons支持的编译类型

  • scons支持的编译类型有
  • Program: 编译成可执行程序
  • Object :只编译成目标文件,使用这种类型,编译结束后,只会产生目标文件,.o文件。
  • Library :编译成库文件,scons默认编译的库是指静态链接库
  • StaticLibrary :显式的编译成静态链接库,与上面的Library效果一样
  • SharedLibrary :编译成动态库

    2.指定目标名,且编译多个文件

Program('hello',['file.c','file2.c']),  //生成可执行文件hello

3,可以使用Glob编译所有匹配的文件

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

4,使用Split,以空白字符为分割符,将字符串分割。

Program('hello',Split("main.c file1.c file2.c")),

5,文件中的关键字

CCFLAGS 指定编译选项
LINKFLAGS 指定链接选项
CPPDEFINES指定预编译器
LIBS 指定所需要链接的库文件
LIBPATH 指定库文件(lib)的搜索路径
CPPPATH 指定[.h,.c,.cpp]等文件的搜素路径

Program('hello',['hellosons.c','file.c'],
        LIBS = 'pthread',
        LIBPATH = ['/usr/lib','/usr/local/lib'],
        CCFLAGS = ['-g ','-Wall'],
        CPPPATH = ['/usr/include','hello/src'])

6,使用Environments

一个environment是一个影响程序执行的值的集合。
1,外部环境 External Environment
外部环境是运行Scons时,用户的环境变量,他们可以通过os.environ获取

6.1构建环境

Construction Environment :它包含一些变量,这些变量会影响Scons构建目标的行为。

env = Environment()   //创建,(name,value)集合
for item in env.Dictionary():
    print '(%s:%s)' %(item,env[item]) //查看内容
env['cc']  //查看变量
env.subst('$CC')  //查看变量,如果subset变量不存在时报告错误。
//修改环境变量
env.Clone   //拷贝一个环境变量
env.Replace  //替换一个已经存在的环境变量
env.SetDefault  //为一个没有被定义的变量设置默认值
env.Append(CCFLAGS = '-g')  //为一个已存在的环境变量增加一个值
env.AppendUnique  //为一个环境变量添加一个唯一的值
flags = {'CCFLAGS':'-option -O3 -O1'}
env.MergeFlags(flags)  //合并环境变量
6.2 执行环境

Execution Environment:用于Scons执行外部命令,以构建一个或多个目标。当Scons构建一个目标文件时,它说使用的外部环境和执行Scons 时的环境变量是不同的。scons 使用$ENV构建变量中存储的目录作为它执行命令的外部环境变量

//在构建环境中显示初始化PATH
path = ['usr/local/bin','/bin','/usr/bin']
env = Environment(ENV = {'PATH':path}) //只设置了ENV
env['ENV']['PATH'] = ['usr/local/bin','/bin','/usr/bin']
//从外部环境初始化PATH
import os
env = Environment(ENV = {'path':os.environ['PATH']})
//使用env.PrependENVPath 和env.AppendENVPath
env.PrependENVPath('PATH','/usr/local/bin') //插入到'$PAHT'第一个位置

7.控制目标文件的路径

使用Install:

test = env.Program('test.cpp')
env.Install('bin',test)  //放入到bin目录

在指定目标名的时候指定其目录

env.Program('bin/test','test.cpp')

//将目标放到其他目录下,并修改名字
test = env.Program('test.cpp')
env.InstallAs('bin/testapp',test)   //执行文件改为testapp

8.一份代码构建多个版本的Target

一份源码,要构建它的debug版本,又要构建release版本

//需要为不同的版本指定不同的obj名字,否则会冲突
opt = Environment(CCFLAGS ='-O2')
dbg = Environment(CCFLAGS = '-g')

o = opt.Object('foo-opt','foo.c')   //生成foo-opt.o
opt.Program(o)

d = dbg.Object('foo-dbg','foo.c'//生成foo-dbg
dbg.Program(d)

这只是一些简单介绍,如果你熟悉Python,就可以随心所欲的编写你要的效果,以前学的python早忘光了。

9,范例参考

这里我贴上实验室大神的SConstruct文件,大家做个简单参考,我也在学习。

#SConstuct file for Shelf

libs = Split("Ice IceUtil pthread boost_program_options boost_filesystem " +
             "boost_regex boost_system pqxx log4cxx dl ENM"),


env = Environment(CCFLAGS = ["-g", "-Wall"],
                  LINKFLAGS = ["-rdynamic"],
                  CPPPATH = ["#src", "/usr/local/include/coral"],
                  LIBS = libs,
                  SLICEPATH = ["/usr/share/Ice-3.5.1/slice"])

#check library
from SCons.SConf import *

def check_flags():
    e = Environment()
    conf = Configure(e)
    for lib in libs[0]:
        if not conf.CheckLib(lib):
            print "Can't find library ", lib, " exiting..."
            Exit(1)
    conf.Finish()

check_flags()

obj = env.Object(["src/ConfigLoader.cpp",
                  "src/Service.cpp",
                  "src/Template.cpp",
                  "src/Resource.cpp",
                  "src/Persistent.cpp",
                  "src/Plugin.cpp",
                  "src/Main.cpp"])


import os

def build_slice2cpp(target, source, env):

    cmd = "slice2cpp"
    for src in source:
        cmd += " " + str(src)

    tdir = str(source[0]).rpartition("/")[0]
    if tdir:
        cmd += " --output-dir " + tdir

    if "SLICEPATH" in env:
        for path in env["SLICEPATH"]:
            cmd += " -I" + path

    return os.system(cmd)

builder = Builder(action = build_slice2cpp, src_suffix = ".ice")

env.Append(BUILDERS = {"Slice": builder})
env.Slice(["src/Shelf.h", "src/Shelf.cpp"], "src/Shelf")
ice_obj = env.Object("src/Shelf.cpp")

env.Program("slf", [obj, ice_obj])

Export('env')
SConscript('src/plugins/SConscript')

Export('ice_obj')
SConscript('src/tests/SConscript')
阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页