env
查看所有的env 环境变量
for k, v in env.items():
print(k,v)
options
profiling
- –debug=time
http://nitrozark.free.fr/scons/bench1/benchmark-gfw-20090702.html
API
COMMAND_LINE_TARGETS
http://www.scons.org/doc/2.3.4/HTML/scons-user.html#sect-command-line-targets
ARGUMENTS
http://www.scons.org/doc/1.1.0/HTML/scons-user/x2361.html
builder
Command
官文手册上原文:
env.Command(target, source, action, [key=val, ...])
Executes a specific action (or list of actions) to build a target file or files. This is more convenient than defining a separate Builder object for a single special-case build.
As a special case, the source_scanner keyword argument can be used to specify a Scanner object that will be used to scan the sources. (The global DirScanner object can be used if any of the sources will be directories that must be scanned on-disk for changes to files that aren't already specified in other Builder of function calls.)
Any other keyword arguments specified override any same-named existing construction variables.
An action can be an external command, specified as a string, or a callable Python object; see "Action Objects," below, for more complete information. Also note that a string specifying an external command may be preceded by an @ (at-sign) to suppress printing the command in question, or by a - (hyphen) to ignore the exit status of the external command.
Examples:
env.Command('foo.out', 'foo.in',
"$FOO_BUILD < $SOURCES > $TARGET")
env.Command('bar.out', 'bar.in',
["rm -f $TARGET",
"$BAR_BUILD < $SOURCES > $TARGET"],
ENV = {'PATH' : '/usr/local/bin/'})
def rename(env, target, source):
import os
os.rename('.tmp', str(target[0]))
env.Command('baz.out', 'baz.in',
["$BAZ_BUILD < $SOURCES > .tmp",
rename ])
Note that the Command() function will usually assume, by default, that the specified targets and/or sources are Files, if no other part of the configuration identifies what type of entry it is. If necessary, you can explicitly specify that targets or source nodes should be treated as directoriese by using the Dir() or env.Dir() functions.
Examples:
env.Command('ddd.list', Dir('ddd'), 'ls -l $SOURCE > $TARGET')
env['DISTDIR'] = 'destination/directory'
env.Command(env.Dir('$DISTDIR')), None, make_distdir)
(Also note that SCons will usually automatically create any directory necessary to hold a target file, so you normally don't need to create directories by hand.)
千万注意:
Note that the Command() function will usually assume, by default, that the specified targets and/or sources are Files
如果是目录,一定要 :
you can explicitly specify that targets or source nodes should be treated as directoriese by using the Dir()
tar 打包
- 实现1
env.Append(BUILDERS = {'mPackage_' : Builder(suffix = '_' + env['mode'] + env['target'] + '.tar.gz',
action='tar czf ${TARGET} -C ${__ext} . --exclude=*.pyc --exclude=*.log* --exclude=*.LOG*') })
def mPackage(self, package_name, src_list, dir_in_package = None):
package_dir = os.path.join(env['ABS_BUILD_DIR'], 'package/')
content_dir = package_dir + 'temp/' + package_name + '/'
pg = self.mPackage_(target = package_dir + package_name, source=[], __ext = content_dir )
env.aDoNothing(package_dir + package_name, pg)
if type(src_list) == str:
src_list = [src_list]
for source in src_list:
if os.path.isdir(source):
dis = content_dir + dir_in_package + '/' if dir_in_package is not None else content_dir
t = dis + source.rstrip('/').split('/')[-1]
cmd = 'cp -pfr %s %s' % (source , dis)
env.Depends(pg, env.Command(source = Dir(source), target = t, action = cmd))
else:
t = dir_in_package if dir_in_package is not None else ''
env.Depends(pg, env.Install(target = content_dir + t, source = source))
#env.Alias('package', pg)
return pg
env.AddMethod(mPackage)
env.mPackage(env['package'], os.path.join(env['TOP_DIR'], 'libs'))
env.mPackage(env['package'], os.path.join(env['BIN_DIR'], 'msadmin'))
env.mPackage(env['package'], os.path.join(env['BIN_DIR'], 'ms_cli'))
- 实现2
def aPackage(self, target, sources, **kwargs):
temp_dir = os.path.join(env['PACKAGE_DIR'], 'temp/')
_tarflags = kwargs.get('TARFLAGS') # 支持tar的参数
if not _tarflags:
if isinstance(_tarflags, list):
_tarflags = ' '.join(_tarflags)
_tarflags = '-zc ' + _tarflags if _tarflags else '-zc'
pkg = self.Command(target = os.path.join(self['PACKAGE_DIR'], target), source = None,
action = 'tar {0} -C {1} -f $TARGET `ls {1}`'.format(_tarflags, temp_dir))
for s in sources:
# source 可能是str, 也可能是scons.Node, 所以用Entry().path 获取地址str
name = os.path.basename(Entry(s).path)
# scons 默认 source\target 都是文件, 这里*_factory=Entry 显式指定 s/t 可以是文件,也可以是目录
t = self.Command(source = s, target = temp_dir + name,
action = 'cp -a ${SOURCE} ${TARGET}',
source_factory=Entry, target_factory = Entry)
self.Depends(pkg, t)
# 在 clean pkg 的时候也清理掉安装在临时目录中的entry
Clean(pkg, t)
self.Alias('package', pkg)
return pkg
env.AddMethod(aPackage)
# 用法
env.aPackage(target = 'helloworld-1.0.tar.gz',
sources = [env['BUILD_DIR'] + '/version', '#helloworld', '#env'],
TARFLAGS = '--exclude=*.pyc --exclude=*.lock --exclude=*.mylock --exclude=*.log'
)
Link flags
ORIGIN
在b_lib 的 rpath 中使用 $ORIGIN
, 让其在bin可以所在位置搜索 a_lib
env.Literal(string) 的意思是 不展开特定的string
env.SharedLibrary(target = "b_lib",
source = ['test_b_lib.cpp'],
LIBS = ['a_lib'],
RPATH = [env.Literal('\\$$ORIGIN')]
)
参考:https://www.technovelty.org/linux/exploring-origin.html
自定义工具路径
工程中使用第三方的scons tool, 可以不用安装到 scons的安装路径下(e.g. /usr/local/lib/scons/SCons/Tool/) ,
可以放在代码工程(site_scons)中的site_tools 这个目录下, 参考https://scons.org/doc/3.1.2/HTML/scons-man.html
示例工程如下
├── SConscript
├── SConstruct
├── build
├── libs
├── src
└── site_tools
├── archive.py
└── documents.py
SConstruct 部分
env = Environment(variables=vars,
tools=['default',
'archive', # non-build-in tool
'documents',
],
toolpath=['site_tools'],
)
依赖检查
build 要用到一些机器上的工具、库等等, 可以使用 Configure.checkXXX(), 例如
conf = Configure(env)
if not conf.CheckLib('m'):
print 'Did not find libm.a or m.lib, exiting!'
Exit(1)
env = conf.Finish()
ref:
- https://scons.org/doc/3.1.2/HTML/scons-user/ch23s04.html
- https://scons.org/doc/3.1.2/HTML/scons-user.html - 23.4. Checking for the Availability of a Library
构建扩展
https://github.com/dholth/enscons
可以构建python wheel
Ref
- https://scons.org/doc/3.1.2/HTML/scons-man.html
- scons-time : https://linux.die.net/man/1/scons-time
- https://github.com/DLR-RY/scons-build-tools
- https://github.com/SCons/scons-contrib
- https://github.com/SCons/scons/wiki
- https://github.com/ptomulik/scons-tool-gcccov
- https://github.com/DLR-RY/scons-build-tools
- https://www.jianshu.com/p/c28609d9e559
- https://stackoverflow.com/questions/tagged/scons?tab=newest&page=5&pagesize=15
- https://scons-cookbook.readthedocs.io/en/latest/
- https://github.com/alberts/goscons