在scons中,我试图建立一个UnitTest系统(见下面的代码),基于这里的一个很好的例子:http://spacepants.org/blog/scons-unit-test
然而,由于最近的scons 2.0.1及更新版本中存在问题,这会产生依赖性循环,如下所述:http://old.nabble.com/AddPostAction-executes-on-first-build-but-not-subsequent- td18360675.html(和其他地方).
有谁知道这个问题的良好解决方案或替代解决方案?
码:
def UnitTest(env, target, source, **kwargs):
curTest = env.Program(target, source, **kwargs)
env.AddPostAction(curTest, curTest[0].abspath)
env.Alias('unit_tests', curTest)
env.AlwaysBuild(curTest)
return curTest
SConsEnvironment.UnitTest = UnitTest
mandolineTest = env.UnitTest(target='./codeTest',
source = mix(['test.cc', 'base.cc'),
LIBS = default_libs + ['bgl',],
LIBPATH = default_libs_path,
CPPPATH = default_includes )
Run Code Online (Sandbox Code Playgroud) 我写了一个python函数,比如替换字符串,并在scons脚本中调用.
def Replace(env, filename, old, new):
with open(filename,"r+") as f:
d = f.read()
d = d.replace(old, new)
f.truncate(0)
f.seek(0)
f.write(d)
f.close()
env.AddMethod(Replace,'Replace')
Run Code Online (Sandbox Code Playgroud)
在SConscript中
lib = env.SharedLibrary('lib', object, extra_libs)
tmp = env.Command([],[],[env.Replace(somefile, 'A', 'b')] )
env.Depends(tmp,lib )
Run Code Online (Sandbox Code Playgroud)
我期望在lib构建之后运行Replace()方法.但是scons总是在第一轮脚本解析短语中运行Replace().似乎我错过了一些依赖.
我正在使用SCons来安装软件包,但是当我尝试使用mex(matlab编译器)进行编译时,它会运行来自pdfTeX的其他命令.要在bash上解决这个问题,我刚刚更改了.bashrc:
别名mex ="/ Applications/MATLAB_R2009b.app/bin/mex"
但我不知道如何在SCons环境中改变它.有人知道怎么做吗?
谢谢.
我的项目使用SCons来管理构建过程.我想支持多个编译器,所以我决定使用,AddOption这样用户就可以在命令行中指定使用哪个编译器(默认情况下是当前编译器所用的编译器).
AddOption('--compiler', dest = 'compiler', type = 'string', action = 'store', default = DefaultEnvironment()['CXX'], help = 'Name of the compiler to use.')
Run Code Online (Sandbox Code Playgroud)
我希望能够为各种编译器提供内置的编译器设置(包括特定编译器的最大警告级别等).这是我目前首次尝试解决方案的方式:
if is_compiler('g++'):
from build_scripts.gcc.std import cxx_std
from build_scripts.gcc.warnings import warnings, warnings_debug, warnings_optimized
from build_scripts.gcc.optimizations import optimizations, preprocessor_optimizations, linker_optimizations
elif is_compiler('clang++'):
from build_scripts.clang.std import cxx_std
from build_scripts.clang.warnings import warnings, warnings_debug, warnings_optimized
from build_scripts.clang.optimizations import optimizations, preprocessor_optimizations, linker_optimizations
Run Code Online (Sandbox Code Playgroud)
但是,我不确定该is_compiler()功能是什么样的.我的第一个想法是直接比较编译器名称(例如'clang ++')与用户传入的内容.但是,当我尝试使用时,这立即失败了scons --compiler=~/data/llvm-3.1-obj/Release+Asserts/bin/clang++.
所以我觉得我会变得更聪明并且使用这个功能
cxx = GetOption('compiler')
def is_compiler (compiler):
return cxx[-len(compiler):] == compiler
Run Code Online (Sandbox Code Playgroud)
这只会查看编译器字符串的结尾,以便忽略目录.不幸的是,'clang …
我在基于scons重构构建系统时遇到了一些问题.我们有一个C/C++源代码树,它包含几个不同的输出对象(dll,可执行文件,测试可执行文件),以及我们的源文件的某种异构布局(尽管它大多数位于带有src/和inc/目录的'module' 目录中).
当前设置的一个最大问题是我们真的希望所有这些构建产品默认使用一致的编译器选项构建.我们当前的布局有一个主SConstruct文件,在子目录中调用许多子SConscript文件,然后构建更大的构建产品(.a例如).默认情况下,SConscript()scons中的函数不会将当前构造环境对象传递或继承到被调用的SConstruct文件.这意味着目前所有这些子SConstript文件都使用自己不同的构造环境.
我正在尝试组合的新布局有一个主构建环境,它在源树根处放在一起,包含我们需要的所有必需的CFLAGS和构建定义.我想这样的施工环境要传递到子SConscript文件,使我知道,每一个.c和.cpp我们构建树文件正在建有相同的命令行.
不过,我不确定如何在scons中这样做.有Import()和Export()函数,但那些基本上是丑陋的全局变量 - 调用SConstruct文件没有很多控制子SConstruct文件使用全局变量做什么Export().是否有任何干净的方法基本上将子SConscript文件作为参数处理当前构造环境,而不必让它必须修改它?有点像:
master_env = Environment()
master_env.Append( CXXFLAGS=['-Wall', '-Werror', '-g', '-fPIC', ... ] )
### add other stuff that we want everything to use
SConscript( 'somelibrary/SConstruct', inherited_environment=master_env.Clone() )
### master_env has now been used to build a
### .dll in somelibrary/, but any variations
### made to somelibrary/SConstruct's inherited
### env haven't contaminated master_env
Run Code Online (Sandbox Code Playgroud)
我知道我可以做一些笨拙的事情,有点像这样:
clobber_env = Environment() …Run Code Online (Sandbox Code Playgroud) 我负责构建多个RPM.我为每个RPM包提供了pristine SPEC文件,我有BASH脚本,它们设置了必要的环境并构建了RPM.
我想使用实际的构建工具(如make)来构建这些RPM.通过这样做,我希望消除对自定义,混淆BASH脚本的需求,转而使用清晰,可维护的配置文件(类似于make的Makefile).但是,使用POSIX制作和保持make文件集是最新的可能与维护我目前用于构建RPM包的BASH脚本一样多.像cmake和automake这样的程序包含make命令的功能是有原因的 - 这些工具更具表现力,允许更小,更清晰的配置文件.
但是,使用autoconf/automake似乎也是一个糟糕的选择,因为它们似乎专门为C和C++开发而构建.有人建议我使用scons,但是这似乎是最好的选择(由于它的配置文件是实际的python脚本),它也适用于特定的语言.
使用我的SPEC文件作为"源代码"和环境作为"依赖项"(例如设置制作RPM所需的rpmbuild目录树结构),是否有一个很好的构建工具可以用来替换我的BASH脚本以获得更清洁,更多可维护的RPM构建解决方案?
编辑:当我说"构建工具"时,我似乎不清楚我需要什么.我已经使用rpmbuild作为'编译器',我使用SPEC文件(以及二进制文件的相关源代码)'编译'RPMs作为'源代码'.我要求一个可以协调这个过程的工具.
我有一个包含二进制文件和一组依赖的静态库的项目。我正在尝试建立每个库所花费的时间而没有成功。
我曾尝试使用它AddPreAction()/AddPostAction()来计算经过的时间,但是AddPreAction()一旦库所依赖的所有源文件都已编译(即有意义),就会被调用。
有一个与此问题有关的帖子:
但是我宁愿寻找一种更优雅的解决方案,而不是覆盖一些环境变量,然后不得不解析输出以计算时间。
提前致谢。
我正在尝试在Scons中定义一个预处理器宏来构建一个更大的C/C++项目.
我正在使用的其中一个库需要ALIGN定义.更具体地说,如果我添加
#define ALIGN(x) __attribute((aligned(x)))
Run Code Online (Sandbox Code Playgroud)
对于所述库的头文件,它编译得很好.但是,我应该能够在构建时指定它,因为这是库打算使用的方式.我知道在CMake中,我可以用类似的东西来定义宏
SET(ALIGN_DECL "__attribute__((aligned(x)))")
Run Code Online (Sandbox Code Playgroud)
像这样在Scons中定义常量
myEnv.Append(CPPDEFINES = ['IAMADEFINEDCONSTANT'])
Run Code Online (Sandbox Code Playgroud)
工作正常,但以这种方式定义宏不起作用.是什么赋予了?
编辑:修正错字
我正在为scons扩展命令,但是源代码不完整.一些xml pdf文档不存在.根据scons wiki,我可以使用
scons -i(--ignore-errors,忽略执行的命令中的所有错误来重建文件.)或
scons -k( - 保持运行,在出错后尽可能多地继续.失败的目标和那些取决于它将不会被重新制作,但命令行中指定的其他目标仍将被处理.)
我想这scons -k是我的目的的正确命令(测试后面的步骤,而一些第一步可能会失败)但我仍然想知道,何时使用-i,因为忽略错误应该导致构建越来越多的东西.或者-i忽略异常,只要所有目标文件仍然成功创建,如果没有创建文件,-k甚至会继续?
我有一个正在实例化一个对象的 sconstruct 脚本。该对象在内部调用一个方法而不是运行多处理模块。示例如下所示
该对象在调用函数之前会解封文件并将输入传递给多处理模块。
def run_scons(self,inpfile,outfile):
# Unpickle input parameter
fid=open(inpfile,'rb')
input_data=pkls.load(fid)
my_results=[]
#run solver in loop
for my_data in input_data:
work_ers=len(my_data)
pool = Pool(processes=work_ers)
a_result=pool.map_async(my_solver, my_data)
pool.close()
pool.join()
my_results.append(a_result.get())
fid.close()
fid_out=open(outfile,'wb+')
pkls.dump(rot_full_results,fid_out)
Run Code Online (Sandbox Code Playgroud)
通过 scons 执行相同的函数时出现以下错误。
pool = Pool(processes=work_ers)
File "C:\Python27\lib\multiprocessing\__init__.py", line 232, in Pool
return Pool(processes, initializer, initargs, maxtasksperchild)
File "C:\Python27\lib\multiprocessing\pool.py", line 138, in __init__
self._setup_queues()
File "C:\Python27\lib\multiprocessing\pool.py", line 232, in _setup_queues
from .queues import SimpleQueue
File "C:\Python27\lib\multiprocessing\queues.py", line 48, in <module>
from multiprocessing.synchronize import Lock, BoundedSemaphore, Semaphore, Condition …Run Code Online (Sandbox Code Playgroud)