[Scons-users] Dependencies and Pseudo Builders

Bill Deegan bill at baddogconsulting.com
Tue Sep 8 11:13:21 EDT 2020


Pasted from below..

I would like to start unit tests, grab the outputs (which is useless
without processing), analyze them, and convert them to XML and HTML
formats.

Correct me if I'm wrong: 1. I should use Builder instead of PseudoBuilder
 2. So my Builder should take a list of Program compiled before as a
$SOURCE
 3. My Builder may call a Python function instead of calling any app
(following https://scons.org/doc/production/HTML/scons-user/ch18s04.html),
that function does all that Pythonic things


Do you want to collectively grab the outputs from running the tests, or
individually?
Regardless.. I'd redirect the output (or tee) to a file in the
builder/command where you run the test programs.
Then as a separate command/builder where the source is the output file from
running the tests process the outputs.
But DO NOT process those files in process (with a python builder) as
generally it's a bad idea to do anything non-trivial in process for many
reasons including ease of testing, but rather write a script to process the
output files from the test runs and generate the output XML/HTML files so
that could look something like

env.Command(output_from_test_run, test_program, "$SOURCE > $TARGET")
env.Command(xml_output, output_from_test_run, "my_processing_script $SOURCE
$TARGET")

(or if you have N of these then it's worth creating a builder for each to
run the test program and to process the outputs)

On Tue, Sep 8, 2020 at 8:56 AM Michał Palczewski <
michal.palczewski at gmail.com> wrote:

> Hi!
> Thank You! You're great!
> I've started my journey across the Scons again, from scratch.
> I've read the article (https://github.com/SCons/scons/wiki/ToolsForFools)
> that you have mentioned and I've replaced my PseudoBuilders by Builder
> packed into Tool. I think my SCons understanding is far better than
> yesterday, but I still have a bunch of questions...
>
> Also thank you for your patience and teaching me "how to fish" :-)
>
> Point 3)
>>> There a problem appears, I've written following pseudo builder:
>>>
>>>     def run_test(env, path):
>>>         try:
>>>             process_output = subprocess.run([path], check=True,
>>> stdout=subprocess.PIPE, universal_newlines=True).stdout
>>>         except subprocess.CalledProcessError as e:
>>>             process_output = e.output
>>>
>>>         return process_output
>>>
>>> As you can see there is no created any files, all results of the call is
>>> stored in memory. So I just need to return that results.
>>> But if I add it to env:
>>> test_result = env.RunTest(path)
>>> env.Depend(test_result, program)
>>> then that builder is called too early (before source code is built) and
>>> I have no idea how to make a correct dependency between Program from Point2
>>> and it's run in Point3. I suppose that builder should return something from
>>> SCons env but I have no idea what it should be.
>>>
>>
>> What do you want to do with the results?
>> Be explicit.
>>
>
> I would like to start unit tests, grab the outputs (which is useless
> without processing), analyze them, and convert them to XML and HTML
> formats.
>
> Correct me if I'm wrong:
>  1. I should use Builder instead of PseudoBuilder
>  2. So my Builder should take a list of Program compiled before as a
> $SOURCE
>  3. My Builder may call a Python function instead of calling any app
> (following https://scons.org/doc/production/HTML/scons-user/ch18s04.html),
> that function does all that Pythonic things
>
> Again
> Enormous Thank You!
>
>
>
>
>
>
>
> pon., 7 wrz 2020 o 17:05 Bill Deegan <bill at baddogconsulting.com>
> napisał(a):
>
>> Greetings,
>>
>> You've got a lot of things not correct.. ;)
>> But as a newbie.. to be expected.
>>
>
> So true :-)
>
>
>> What documents have you read?
>> Did you read the users guide?
>> (That's a good place to start)
>> *Don't just start googling stuff and follow random stackoverflow pages..
>> you'll end up with a giant mess that probably doesn't work, probably isn't
>> correct even if it does work and zero understanding of how to do it
>> correctly.*
>>
>>
> So true, again.
>
> See comments inline below.
>>
>>
>> On Sun, Sep 6, 2020 at 7:31 PM Michał Palczewski <
>> michal.palczewski at gmail.com> wrote:
>>
>>> Hi Everybody!
>>> At the very beginning, I would like to say Hello! to everybody, I'm a
>>> newbie here :-D
>>>
>>> But let's go to the point. Frankly speaking I need some help to write
>>> correct and SConsy idiomatic SConstruct to generate, build, and run unit
>>> tests. The entire flow is as follows:
>>>
>>> 1) Generate Unity 'test_runner' code - I use provided Unity test runner
>>> generator, it's Ruby script
>>> 2) Build Program, where the code generated in point 1 is one of the
>>> input source files
>>> 3) Run the Program that has been build in point 2
>>> 4) Get the results and start Python script to analyze the results.
>>>
>>> Generally, I think I know (or not....) how to perform each action, but I
>>> cannot ling all of them together to force the correct order of those steps.
>>>
>>> Let's describe my ideas:
>>>
>>> Point 1)
>>> To do Point1 I've made a PseudoBuilder (basing on:
>>> https://scons.org/doc/production/HTML/scons-user/ch20.html)
>>>
>>>     def generate_runner(env, test, test_runner):
>>>         os.makedirs(os.path.dirname(test_runner), exist_ok=True)
>>>         env.Execute(f"ruby
>>> {env['UNITY_DIR']}/auto/generate_test_runner.rb {test} {test_runner}")
>>>         return SCons.Node.FS.FS().File(test_runner)
>>> ...
>>> env.AddMethod(generate_runner, "GenerateRunner")
>>>
>>> Is it Execute correct here?
>>>
>>
>> All the above is completely incorrect.
>>
>
> Yeah.
>
>
>> You want to create a builder here and not a psuedo builder.
>> You should (Almost) never use Execute.
>> You should (Almost) never have to explicitly create a File node.. Not
>> sure how you went down that path.
>> If there's some scons docs that lead you that way please let us know so
>> we can revise them.
>>
>> See the user guide,  the man page, and also this wiki page
>> https://github.com/SCons/scons/wiki/ToolsForFools
>>
>> Do you have to create many test running source files? (or just one, if
>> just one, then env.Command() will likely do the trick)
>>
>>
>>
>>> Point 2)
>>> To do Point2 I've used build-in Builder combined by dependency with my
>>> own one:
>>>
>>> runner = env.GenerateRunner('test_case_source", "test_case_runner.c")
>>> program = env.Program(name="test_case_name",
>>> souces=['test_case_source.c', 'test_case_runner.c']
>>>
>>> env.Depends(program, runner)
>>>
>>> And until this Point everything seems to be working correctly.
>>> In fact, all files from Point 1 are generated in single run but it
>>> always happens before Point 2,
>>>
>>> .e.g.:
>>> ruby
>>> ruby
>>> ruby
>>> gcc
>>> gcc
>>> gcc
>>>
>>> when I would expect (doubtfully?):
>>> ruby
>>> gcc
>>> ruby
>>> gcc
>>> ruby
>>> gcc
>>>
>>> but I stop thinking about that because it generally works
>>>
>>
>> Another important point. DONT try to force order. The correct way to use
>> SCons (and really any build system), is to list dependencies. The tools
>> should connect the dots for you.
>>
>> And if you have to use Depends() you're probably doing something wrong.
>>
>> If you have a builder (which you should) which generates
>> test_case_runner.c from test_case_source, and you have
>> a Program() which has test_case_runner.c as a source. No need to do
>> anything else. SCons will figure that out.
>>
>>
>>> Point 3)
>>> There a problem appears, I've written following pseudo builder:
>>>
>>>     def run_test(env, path):
>>>         try:
>>>             process_output = subprocess.run([path], check=True,
>>> stdout=subprocess.PIPE, universal_newlines=True).stdout
>>>         except subprocess.CalledProcessError as e:
>>>             process_output = e.output
>>>
>>>         return process_output
>>>
>>> As you can see there is no created any files, all results of the call is
>>> stored in memory. So I just need to return that results.
>>> But if I add it to env:
>>> test_result = env.RunTest(path)
>>> env.Depend(test_result, program)
>>> then that builder is called too early (before source code is built) and
>>> I have no idea how to make a correct dependency between Program from Point2
>>> and it's run in Point3. I suppose that builder should return something from
>>> SCons env but I have no idea what it should be.
>>>
>>
>> What do you want to do with the results?
>> Be explicit.
>>
>> _______________________________________________
>> Scons-users mailing list
>> Scons-users at scons.org
>> https://pairlist4.pair.net/mailman/listinfo/scons-users
>>
> _______________________________________________
> Scons-users mailing list
> Scons-users at scons.org
> https://pairlist4.pair.net/mailman/listinfo/scons-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://pairlist4.pair.net/pipermail/scons-users/attachments/20200908/952f5698/attachment-0001.html>


More information about the Scons-users mailing list