[Scons-users] Non Construction steps in Scons

Duane Ellis duane at duaneellis.com
Sun May 15 12:15:32 EDT 2022


The sad/frustrating part here is this:
                I was hoping SCons would be a *good* cross platform replacement for Make.
                By Cross Platform I mean: Windows + Linux
                But it seems quite incomplete :-( in my opinion.

As Bill Deegan suggests – a “timestamp” file is a very good solution.

Sadly, I am surprised this type of thing is not a usable built in feature that is quite standardized.

Something like this .. a simple class that implements a stampfile you can extend.

class MyStampClass(basestampclass):
                def __init__(self):
                              basesampclass.__init__(self)
                def Clean( env ):
                                print(“Insert Clean Operations here”)
                def DryRun( env ):
                                print(“The ‘-n’ option was specified … do not execute cmds just print”)
                def Build( env ):
                                print(“Perform the build here”)

MyStampFactor = MyStampClass()

Env.StampFile( depends=”filename”,  result=”filename”,  builder=SomeClass )

Meanwhile, this is what I’m doing to make it work

import os
import sys
import subprocess

env = Environment()

ROOT_DIR = Dir('.').abspath
print("ROOT_DIR=%s" % ROOT_DIR)

# Assumptions:
#
# (root)
#  | -> src - holds a SConstruct file to build the library (called recursively)
#  | -> doxygen -> holds doxygen config file doxygen is built here.
#  | -> packager -> holds install(packager) details,
#
# Build order:
#   Step 1 - cd src, run scons
#   Step 2 - cd doxygen, run doxygen
#   Step 3 - (future) cd package, run packager (creates install package)
#
# About "packager" - this a custom solution.
#    (we don't use RPM, etc)
#

if GetOption('clean'):
    os.chdir( 'src' )
    subprocess.call( ['scons', '-c'] )
    os.chdir( ROOT_DIR )

def BuildTheLib( *PositionalParams,  **Keyword_Params ):
    for tmp in PositionalParams:
                print("Param: %s" % tmp )
    for n,v in Keyword_Params.items():
        print("name=%s -> value=%s" % (n,v))
    os.chdir( 'src' )
    if subprocess.call( ["scons"] ):
       print("SRC Build failed..")
       Exit(1)
    os.chdir( ROOT_DIR)
    with open( Keyword_Params['target'], "wt" ) as f:
                  f.write("Built")

lib_build = env.Command( "stamp.src", None, BuildTheLib )

Default( lib_build )

if GetOption('clean'):
    os.chdir('doxygen')
    subprocess.call(['echo', 'Do the cleaning'])
    os.chdir( ROOT_DIR )

def DoxyBuild( *PositionalParams,  **Keyword_Params ):
    for tmp in PositionalParams:
                print("Param: %s" % tmp )
    for n,v in Keyword_Params.items():
        print("name=%s -> value=%s" % (n,v))
    os.chdir( 'doxygen' )
    if subprocess.call( ["doxygen" ] ):
       print("Doxygen Build failed..")
      Exit(1)
    os.chdir( ROOT_DIR)
    with open( Keyword_Params['target'], "wt" ) as f:
                  f.write("Built")

doxy_build = env.Command( 'stamp.doxy', None, DoxyBuild )

Default( doxy_build )



From: Scons-users <scons-users-bounces at scons.org> on behalf of Bill Deegan <bill at baddogconsulting.com>
Date: Saturday, May 14, 2022 at 4:28 PM
To: SCons users mailing list <scons-users at scons.org>
Subject: Re: [Scons-users] Non Construction steps in Scons
I don't see any issues with steps 1-5.
Any set of commands which takes an input file (although other non-file info can work as well), and produces a target (generally) file can work.
step 1 - perfect fit, input file, output file command (you can use env.Command() for such)
step 2 - perfect fit, input file + other info (are flags variable, or fixed), outputs a package file(?) , env.Command()
step 3 - not quite perfect fit, but what I would do is create a output file with a timestamp after you flash the board, env.Command() can do this, you can list 2 command, one is flash the board, second is create a timestamp file.
step 4 - basically same as step 3, though if you don't want SCons to do dependency management here (building any targets for this), you could just handle with with python logic in your SConstruct/SConscript to see if that command is on the command line (https://scons.org/doc/production/HTML/scons-man.html#v-COMMAND_LINE_TARGETS)
step 5 - does this generate any output files? If not, then also use similar method as steps 3 & 4.

Curious why you think a generic builder is wrong for step 2?

BTW we do have a discord server if you want to discuss this real time. (https://discord.gg/pejaFYrD9n)

-Bill



On Sat, May 14, 2022 at 3:48 PM Mats Wichmann <mats at wichmann.us<mailto:mats at wichmann.us>> wrote:
On 5/14/22 16:18, Duane Ellis wrote:
> Hi – I am new to scons and I am trying to do something Know how to do in
> Make
>
> Example make rule is like this (I hope this shows up in email reasonably)…
>
> =============
>
> Many-things:   Step1. Step2. Step3 Step4 Step5
>
> TARGET=allthings
>
> MyApp.ELF:  $(OBJECT_FILES)
>                 $(LINK_STEP) ….
>
> Step1:  MyApp.ELF
>                 Cmd1
>
> Step2:
>                 Cmd2
>
> Step3:
>                 Cmd3
>
> Step4:
>                 Cmd4
>
> Step5:
>                 Cmd5
>
> Allthings:  MyApp.ELF  Step1  Step2 Step3
>
> =============
>
> In my case, I am working on an embedded platform.
>
> I am *NOT* always performing “Construction” – I want to do some other
> things.
>
> Scons can build my app wonderfully – but I can’t get it to do the next
> several steps – they are not “construction steps” they are procedural steps

On the whole (as you're finding out), this isn't really what SCons does
and so it's sometimes a bit tricky to set these things up.

The first one, however, is well supported;

> Step 1 – I need to post-process my ELF file to create a BIN file in a
> special way for my board (producing a type of BIN file)

the AddPostAction and AddPreAction methods can help with these needs.

> Step 2 – takes the BIN and ‘packages’ it with special flags unique to
> this application (A generic builder seems wrong here)

There is some "packaging" support - and usually those are indeed
builders - but often things under that term can end up quite
specialized, so that may or may not help you.

> Step 3 – runs a GUI tool in command line mode to “flash” my board, I
> have to specify on the command line the DEVICE address (either a
> comport, or a tftp server)
>
> Step 4 – runs a command to power cycle the board via a SCPI controlled
> power supply
>
> Step 5 – Launches a Python PyExpect test sequence with a rather
> complicated command line.

You can create a "phony" target which runs a script to do all these
things. I use the term phony because normally, to SCons, a target is
something that is tangible that it can construct.  This can be a bit
awkward but is certainly doable -  for example, people use this concept
to run unit tests.

> Other examples are “building both a Library, and a Doxygen package and
> running the library through a small regression test and “code-formatter”
> I know how to do that with make… but I don’t see a way of doing that with

There is a contributed doxygen tool in the scons-contrib repository.
For tests, see the comment above.  For other things, like code
formatting - consider whether you really want those done as part of the
scons process, or elsewhere. For example, you can set up pre-commit and
post-commit hooks in git (conceptually like AddPostAction in SCons), and
you can set up even more sophisticated tasks of this sort in GitHub and
Gitlab, should you be using either of those two platforms.  It's just a
thought, not telling you how to solve your problems.

> What I would like know how to do is:
>
>
>
> Create a list of arbitrary commands that I can execute in order, If one
> of those commands fail, I want further progress to stop
>
> I would like to say which step depends on the previous step – this is
> **SPECIFICALLY* not a filename extension thing*

You don't really get to do this: the underlying architectural concept is
that you tell SCons the relationship between things (e.g. a Builder
produces targets from the listed sources), it constructs a node graph of
all those things, and then walks that graph to decide how best to
complete the build.  If you need very specific ordering of certain
steps, you need to put them in an external script, or a Python function,
which applies the constraints you need.

> From the command line, I need to be able to reasonably execute one of
> the steps at will (ie: like I can do with  “make step4”, or “make
> allthings”)

Generally speaking you can use Alias to set up targets that are easy to
invoke from the command line, and aliases are quite flexible so they can
refer to few or many things, including other Aliases (although there's
an ordering consideration with chaining aliases).
_______________________________________________
Scons-users mailing list
Scons-users at scons.org<mailto: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/20220515/f95d183f/attachment-0001.htm>


More information about the Scons-users mailing list