Given that my Ada builder use a function ada_action which is registered by
static_obj.action(suffix, Action(ada_action, print_action_string)
which currently calls env.Execute() and further
def print_action_string(target, source, env):
print env.subst(env["ADACOMSTR"], target=target, source=source)
How can I control the verbosity levels so that if env["ADACOMSTR"] is defined it should only call print_action_string and inhibit echoing of the shell command currently done by env.Execute()?
You normally don't need to use Execute() in a builder action. Perhaps if you share that bit of code it might help. You could also look into using a generator, depending on what exactly you're looking for.
Related
For example, if I'm printing an interface by calling print(), and then, It will call printiface(), I'm wondering what does go actually between these two statements.
From what I could gather, print calls turn into printstring, printiface, etc. at compile time. If you want to look at how print code is generated, you could be interested in this code in src/cmd/gc/walk.c.
That method printiface() is mainly called by ifaceI2T(), ifaceI2I(), ifaceeq(), printinter().
So you can see more in runtime/iface.c
I'm struggling with the last pieces of logic to make our Ada builder work as expectedly with variantdir. The problem is caused by the fact that the inflexible tools gnatbind and gnatlink doesn't allow the binder files to be placed in a directory other than the current one. This leaves me with two options:
Let gnatbind write the the binder files to topdir and then let gnatlink pick it from there. This may however cause race conditions if we want to allow simulatenous builds for different architectures and compiler versions which we want.
Modify the calls to gnatbind and gnatlink to temporarily go down to the build directory, in our case build/$ARCH/src-path. I successfully fixed the gnatbind step as this is explicitly called using a env.Execute from within the Ada builder. To try to fix the linking step I've modified the Program env using
env["LINKCOM"] = SCons.Action.Action(ada_linkcom)
where ada_linkcom is defined as
def ada_linkcom(source, target,env ):
....
return ret
where ret is a string describing what should be done in the shell. I need this to be a function it contains a bit complicated logic to convert paths from being relative to top-level to just containing their basenames.
This however fails with an error in scons-2.3.1/SCons/Executor.py on line 347 in function do_execute. Isn't env["LINKCOM"] allowed to be a function with ada_linkcom's signature?
No, it's not. You seem to think that 'env["LINKCOM"]' is what actually calls/executes the final build command, and that's not quite correct. Instead, environment variables like LINKCOM get expanded by the Executor/Builder for each specified Action, and are then executed.
You can have Python functions as Actions, and also use a so-called "generator" to create your Action strings on-the-fly. But you have to assign this Action to a Builder, and can't set it as an environment variable directly.
Please also have a look at the UserGuide ( http://www.scons.org/doc/production/HTML/scons-user.html ), especially section 18.4 "Builders That Execute Python Functions". Our basic guide for writing Builders and Tools might also prove to be helpful: http://www.scons.org/wiki/ToolsForFools
In Haxe, is there a method in the Sys class (or some other class) that returns the output of a shell command (for example, the command "ls"), or will I need to implement this method myself for each target language? I'd like to find a method for invoking shell commands that works with every Haxe target language.
Yes, your own comment contain the answer, which is:
var output = new sys.io.Process("ls", []).stdout.readAll().toString();
Or the cross platform way: sys.FileSystem.readDirectory('')
It might also be faster, because it doesn't invoke an extra process.
As a continuation of this question and the subsequent answer, does anyone know how to have a job created using the Parallel Computing Toolbox (using createJob and createTask) access external toolboxes? Is there a configuration parameter I can specify when creating the function to specify toolboxes that should be loaded?
According to this section of the documentation, one way you can do this is to specify either the 'PathDependencies' property or the 'FileDependencies' property of the job object so that it points to the functions you need the job's workers to be able to use.
You should be able to point the way to the KbCheck function in PsychToolbox, along with any other functions or directories needed for KbCheck to work properly. It would look something like this:
obj = createJob('PathDependencies',{'path_to_KbCheck',...
'path_to_other_PTB_functions'});
A few comments, based on my work troubleshooting this:
It appears that there are inconsistencies with how well nested functions and anonymous functions work with the Parallel Computation toolkit. I was unable to get them to work, while others have been able to. (Also see here.) As such, I would recommend having each function stored in it's own file, and including those files using the PathDependencies or FileDependencies properties, as described by gnovice above.
It is very hard to troubleshoot the Parallel Computation toolkit, as everything happens outside your view. Use breakpoints liberally in your code, and the inspect command is your friend. Also note that if there is an error, task objects will contain an error parameter, which in turn will contain ErrorMessage string, and possibly the Error.causes MException object. Both of these were immensely useful in debugging.
When including Psychtoolbox, you need to do it as follows. First, create a jobStartup.m file with the following lines:
PTB_path = '/Users/eliezerk/Documents/MATLAB/Psychtoolbox3/';
addpath( PTB_path );
cd( PTB_path );
SetupPsychtoolbox;
However, since the Parallel Computation toolkit can't handle any graphics functionality, running SetupPsychtoolbox as-is will actually cause your thread to crash. To avoid this, you need to edit the PsychtoolboxPostInstallRoutine function, which is called at the very end of SetupPsychtoolbox. Specifically, you want to comment out the line AssertOpenGL (line 496, as of the time of this answer; this may change in future releases).
I'm trying to pick up ruby by porting a medium-sized (non-OO) perl program. One of my personal idioms is to set options like this:
use Getopt::Std;
our $opt_v; # be verbose
getopts('v');
# and later ...
$opt_v && print "something interesting\n";
In perl, I kind of grit my teeth and let $opt_v be (effectively) a global.
In ruby,the more-or-less exact equivalent would be
require 'optparse'
opts.on("-v", "--[no-]verbose", TrueClass, "Run verbosely") {
|$opt_verbose|
}
opts.parse!
end
where $opt_verbose is a global that classes could access. Having classes know about global flags like that seems ... er ... wrong. What's the OO-idiomatic way of doing this?
Let the main routine take care of all option-related stuff and have the classes just return things to it that it decides how to deal with?
Have classes implement optional behaviour (e.g., know how to be verbose) and set a mode via an attr_writer sort of thing?
updated: Thanks for the answers suggesting optparse, but I should have been clearer that it's not how to process command-line options I'm asking about, but more the relationship between command-line options that effectively set a global program state and classes that should ideally be independent of that sort of thing.
A while back I ran across this blog post (by Todd Werth) which presented a rather lengthy skeleton for command-line scripts in Ruby. His skeleton uses a hybrid approach in which the application code is encapsulated in an application class which is instantiated, then executed by calling a "run" method on the application object. This allowed the options to be stored in a class-wide instance variable so that all methods in the application object can access them without exposing them to any other objects that might be used in the script.
I would lean toward using this technique, where the options are contained in one object and use either attr_writers or option parameters on method calls to pass relevant options to any additional objects. This way, any code contained in external classes can be isolated from the options themselves -- no need to worry about the naming of the variables in the main routine from within the thingy class if your options are set with a thingy.verbose=true attr_writer or thingy.process(true) call.
The optparse library is part of the standard distribution, so you'll be able to use it without requiring any third party stuff.
I haven't used it personally, but rails seems to use it extensively and so does rspec, which I guess is a pretty solid vote of confidence
This example from rails' script/console seems to show how to use it pretty easily and nicely
The first hit on google for "processing command line options in ruby" is an article about Trollop which seems to be a good tool for this job.