SCons: make Substfile depend on Install - scons

I generate some csharp wrappers using swig and install them to a directory.
After these files installed, I want to use env.Substfile to replace public enum with internal enum.
The thing is, no matter what I set the Substfile to depend on, it always executes before the wrappers are installed
Here is a part of the script:
install = Install(bins, wrapper_bins)
script_dict = {'public enum': 'internal enum'}
for f in Glob(wrapper_dir.abspath+'/*.cs'): # tried also without the filter
sub = env.Substfile(f, SUBST_DICT = script_dict)
Depends(sub, install)
How can I make sure the Substfile will always be executed only after Install was done?
Here is the updated code (still doesn't work)
env['WRAPPER_DIR'] = "c:\\dev\\test\\"
script_dict = {'public enum': 'internal enum'}
for f in Glob(wrapper_dir.abspath+"/*"):
sub = env.Substfile("${WRAPPER_DIR}/${SOURCE.file}", f, SUBST_DICT = script_dict)
Depends(installed_bins, sub)
SCons version 3.0.1

Try this:
installed_bins = Install(bins, wrapper_bins)
env['WRAPPER_DIR']='some path'
script_dict = {'public enum': 'internal enum'}
for f in Glob(source_path_for_cs_s+"*.cs"):
sub = env.Substfile("${WRAPPER_DIR}/${SOURCE.file}", f, SUBST_DICT = script_dict)
depends(installed_bins, sub)

Related

Asterisk dynamic Lua Dialplan

I am using the Asterisk PBX_LUA.so module to create a Test Dialplan, but I am not able to create a dynamic Dialplan, is it possible?
I changed parts of the module sample to test:
extensions = {}
extensions["demo"] = {}
extensions["demo"]["s"] = demo_start;
extensions["demo"]["2"] = function(c, e)
extensions.demo["1"] = function() demo_instruct() end --<<-- "it's possible?"
app.background("demo-moreinfo")
demo_instruct()
end
extensions["demo"]["3"] = function (c, e)
channel.LANGUAGE():set("fr") -- set the language to french
demo_congrats()
end
extensions["demo"]["i"] = demo_invalid;
but when I type 2 and then 1, option 1 is not recognized and throws me to the extension ["i"] (invalid).
is it possible to do this with Asterisk Lua Dialplan?
You should create ENOTHER context and use it.
You also can use X for any digit and check digit in LUA.

Library builder not triggering on modified file in SCons

I have to build a target using a two steps compilation.
The first step: .c -> .asm
The second step: .asm -> .o
I am creating a library from some .o files.
My implementation is the following:
The first step:
c_to_asm_builder = SCons.Builder.Builder(action = SCons.Defaults.CAction,
emitter = {},
suffix = '.asm',
src_suffix = ['.c','.cpp'],
src_builder = '',
source_scanner = SCons.Tool.CScanner
)
env['Builders']['CTOASM'] = c_to_asm_builder
The second step:
suffixesASM = ['.asm', '.s']
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
for suffix in suffixesASM:
static_obj.add_action(suffix, SCons.Defaults.ASAction)
I am then calling the builders as follows:
env.CTOASM(['file1.c', 'file2.c', 'file3.c'], CFLAGS = '-flag')
env.Object(['file1.asm', 'file2.asm', 'file3.asm'], ASFLAGS = '-flag')
I am creating a library like this:
env.Library('name', ['file1.o', 'file2.o'])
Everything works fine for the compilation.
The problem appers when:
I change file1.c content. I expect file1.c to pass trough these steps:
file1.c -> file1.asm -> file1.o and then name.a library to be recreated.
What happens:
Only c_to_asm_builder is retriggered by the change (file1.c -> file1.asm). The Object builder (file1.asm -> file1.o) is not retriggered and also the Library builder and Program builder are not retriggered.
I don't know what I am missing. I know that for a single step compilation that I configured in another project the Object builder and Library builder are somehow aware of each other.
How to make Library and Program builder aware of Object and CTOASM builders ?
You are not specifying an emitter, so either write one, or explicitly list your expected targets...
asm = env.CTOASM(['file1.asm', 'file2.asm', 'file3.asm'],
['file1.c', 'file2.c', 'file3.c'], CFLAGS = '-flag')
obj = env.Object(['file1.o', 'file2.o', 'file3.o'], asm, ASFLAGS = '-flag')
lib = env.Library('name', obj)
Here is a good reference on how to add an emitter to your builder.
https://bitbucket.org/scons/scons/wiki/ToolsForFools
Just scroll down to "Using Emitters".

How can I add the build version to a scons build

At the moment I'm using some magic to get the current git revision into my scons builds.. I just grab the version a stick it into CPPDEFINES.
It works quite nicely ... until the version changes and scons wants to rebuild everything, rather than just the files that have changed - becasue the define that all files use has changed.
Ideally I'd generate a file using a custom builder called git_version.cpp and
just have a function in there that returns the right tag. That way only that one file would be rebuilt.
Now I'm sure I've seen a tutorial showing exactly how to do this .. but I can't seem to track it down. And I find the custom builder stuff a little odd in scons...
So any pointers would be appreciated...
Anyway just for reference this is what I'm currently doing:
# Lets get the version from git
# first get the base version
git_sha = subprocess.Popen(["git","rev-parse","--short=10","HEAD"], stdout=subprocess.PIPE ).communicate()[0].strip()
p1 = subprocess.Popen(["git", "status"], stdout=subprocess.PIPE )
p2 = subprocess.Popen(["grep", "Changed but not updated\\|Changes to be committed"], stdin=p1.stdout,stdout=subprocess.PIPE)
result = p2.communicate()[0].strip()
if result!="":
git_sha += "[MOD]"
print "Building version %s"%git_sha
env = Environment()
env.Append( CPPDEFINES={'GITSHAMOD':'"\\"%s\\""'%git_sha} )
You don't need a custom Builder since this is just one file. You can use a function (attached to the target version file as an Action) to generate your version file. In the example code below, I've already computed the version and put it into an environment variable. You could do the same, or you could put your code that makes git calls in the version_action function.
version_build_template="""/*
* This file is automatically generated by the build process
* DO NOT EDIT!
*/
const char VERSION_STRING[] = "%s";
const char* getVersionString() { return VERSION_STRING; }
"""
def version_action(target, source, env):
"""
Generate the version file with the current version in it
"""
contents = version_build_template % (env['VERSION'].toString())
fd = open(target[0].path, 'w')
fd.write(contents)
fd.close()
return 0
build_version = env.Command('version.build.cpp', [], Action(version_action))
env.AlwaysBuild(build_version)

Have R look for files in a library directory

I am using R, on linux.
I have a set a functions that I use often, and that I have saved in different .r script files. Those files are in ~/r_lib/.
I would like to include those files without having to use the fully qualified name, but just "file.r". Basically I am looking the same command as -I in the c++ compiler.
I there a way to set the include file from R, in the .Rprofile or .Renviron file?
Thanks
You can use the sourceDir function in the Examples section of ?source:
sourceDir <- function(path, trace = TRUE, ...) {
for (nm in list.files(path, pattern = "\\.[RrSsQq]$")) {
if(trace) cat(nm,":")
source(file.path(path, nm), ...)
if(trace) cat("\n")
}
}
And you may want to use sys.source to avoid cluttering your global environment.
If you set the chdir parameter of source to TRUE, then the source calls within the included file will be relative to its path. Hence, you can call:
source("~/r_lib/file.R",chdir=T)
It would probably be better not to have source calls within your "library" and make your code into a package, but sometimes this is convenient.
Get all the files of your directory, in your case
d <- list.files("~/r_lib/")
then you can load them with a function of the plyr package
library(plyr)
l_ply(d, function(x) source(paste("~/r_lib/", x, sep = "")))
If you like you can do it in a loop as well or use a different function onstead of l_ply. Conventional loop:
for (i in 1:length(d)) source(paste("~/r_lib/", d[[i]], sep = ""))
Write your own source() wrapper?
mySource <- function(script, path = "~/r_lib/", ...) {
## paste path+filename
fname <- paste(path, script, sep = "")
## source the file
source(fname, ...)
}
You could stick that in your .Rprofile do is will be loaded each time you start R.
If you want to load all the R files, you can extend the above easily to source all files at once
mySource <- function(path = "~/r_lib/", ...) {
## list of files
fnames <- list.files(path, pattern = "\\.[RrSsQq]$")
## add path
fnames <- paste(path, fnames, sep = "")
## source the files
lapply(fnames, source, ...)
invisible()
}
Actually, though, you'd be better off starting your own private package and loading that.

scons: overriding build options for one file

Easy question but I don't know the answer.
Let's say I have a scons build where my CCFLAGS includes -O1. I have one file needsOptimization.cpp where I would like to override the -O1 with -O2 instead. How could I do this in scons?
update: this is what I ended up doing based on bialix's answer:
in my SConscript file:
Import('env');
env2 = env.Clone();
env2.Append(CCFLAGS=Split('-O2 --asm_listing'));
sourceFiles = ['main.cpp','pwm3phase.cpp'];
sourceFiles2 = ['serialencoder.cpp','uartTestObject.cpp'];
objectFiles = [];
objectFiles.append(env.Object(sourceFiles));
objectFiles.append(env2.Object(sourceFiles2));
...
previously this file was:
Import('env');
sourceFiles = ['main.cpp','pwm3phase.cpp','serialencoder.cpp','uartTestObject.cpp'];
objectFiles = env.Object(sourceFiles);
...
Use Object() builder for fine-grained control over compilation, and then pass these objects to Program() builder.
E.g. instead of:
env = Environment()
env.Program(target='foo', source=['foo.cpp', 'bar.cpp', 'needsOptimisation.cpp'])
You need to use following:
env = Environment()
env_o1 = env.Clone()
env_o1.Append(CCFLAGS = '-O1')
env_o2 = env.Clone()
env_o2.Append(CCFLAGS = '-O2')
# extend these lists if needed
SRC_O1 = ['foo.cpp', 'bar.cpp']
SRC_O2 = ['needsOptimisation.cpp']
obj_o1 = [env_o1.Object(i) for i in SRC_O1]
obj_o2 = [env_o2.Object(i) for i in SRC_O2]
env.Program(target='foo', source=obj_o1+obj_o2)
You can avoid creation of separate clone of env variable if you provide CCFLAGS='-O2' right in the Object() call:
obj_o2 = [env.Object(i, CCFLAGS=env['CCFLAGS'] + ['-O2']) for i in SRC_O2]
Avoiding creating of a separate env variable requires (ref: bialix's answer) needs something like this.
obj_o2 = env.Object(SRC_O2, CCFLAGS=env['CCFLAGS'] + ['-O2']);
If you just do this (or in the for loop like bialix does)
obj_o2 = env.Object(SRC_O2, CCFLAGS='-O2');
then you lose all the builtin flags.

Resources