[Scons-users] adding text to compile line

Jeremy Elson jelson at gmail.com
Sun Jan 21 16:40:07 EST 2024


This is a lot more than what OP asked for, but I'll describe the custom
output code I wrote for one of my Scons-based build systems.(It's not
open-source, so I can't link to the full code.)

My goal was to replace all the raw command-line output with something like:

Compiling src/app/foo.c
Compiling src/app/bar.c
Linking build/libs/libfoo.a
Linking build/output/foo.elf
Signing build/output/foo.elf

In this case, "Compiling" and "Linking" are standard scons rules; "Signing"
is a custom builder. The trick is that for some of the outputs, such as
Compiling, should show the name of the source. Others, such as Linking,
show the name of the target.

First, I defined a class called SpinnerPrinter that looks sort of like this:

class SpinnerPrinter:
SPINNER = '<<spinner>>'
SOURCE = 'src'
TARGET = 'trg'

def spin_source(s):
return SpinnerPrinter.SPINNER + SpinnerPrinter.SOURCE + s

def spin_target(s):
return SpinnerPrinter.SPINNER + SpinnerPrinter.TARGET + s

Then, in my function that sets up the scons build env, I have code that
looks like the examples below. I call spin_source to indicate the build
output should use the source filenames, and spin_target to show it should
be target. The COMSTRs all end up being configuration strings for the
custom output function.

if not build_options.verbose:
env['PRINT_CMD_LINE_FUNC'] = SpinnerPrinter().spinner_print
# Overrides to standard builders
env['CCCOMSTR'] = SpinnerPrinter.spin_source("Compiling")
env['ASPPCOMSTR'] = SpinnerPrinter.spin_source("Assembling")
env['LINKCOMSTR'] = SpinnerPrinter.spin_target("Linking")
env['ARCOMSTR'] = SpinnerPrinter.spin_target("Creating library")

# locally defined builders
env['PROTOBUFCOMSTR'] = SpinnerPrinter.spin_source("Creating protobuf")
env['SIGNCOMSTR'] = SpinnerPrinter.spin_source("Signing")

The SpinnerPrinter class has a function spinner_print that uses the config
string to generate the output based on the config
string generated by spin_source and spin_target:

def spinner_print(self, s, target, source, env):
# Regular (non-spinner-aware) strings just get emitted as
# usual
if not s.startswith(self.SPINNER):
sys.stdout.write(s + "\n")
return

# take off the marker
s = s[len(self.SPINNER):]

# figure out if we are supposed to print the source or target
which = s[0:3]

# Generate the prefix (the part printed before the filename).
print_prefix = s[3:]
# Find out what filename to print as part of the output. We'd
# rather print the name of the source, but steps such as
# library creation have a zillion sources and one target, so
# we'll print the target instead for those.
if which == SpinnerPrinter.SOURCE:
file_to_print = source[0]
else:
file_to_print = target[0]
fn_to_print = os.path.realpath(str(file_to_print))

# Combine the directive we were given (e.g. "Compiling")
# with the filename
sys.stdout.write(f"{print_prefix} {fn_to_print}\n"

This can be made much fancier; I've elided various details. For example,
the real spinner senses if stdout is a tty. If it is a tty, it uses ANSI
escape sequences so the output lines overwrite themselves, and it prints
only the part of the filename that fits on a single terminal line (after
sensing its width). So when our team builds from the command-line, a normal
build does not use any terminal space at all! When running from a script,
the "Compiling" and "Linking" lines all appear as separate lines. And
without the --verbose option, the entire custom output block is skipped and
full command-lines get printed (the default scons behavior).

Hopefully this helps someone! We've been very happy with how it works (and
with scons in general).

-Jeremy

On Sun, Jan 21, 2024 at 1:07 PM Bill Deegan <bill at baddogconsulting.com>
wrote:

> Dagg,
>
> What Mats said.. with more detail.
>
> So if your compiling c++, the relevant variables are
> CXXCOM, CXXCOMSTR
> SHCXXCOM, SHCXXCOMSTR
>
> The *STR variables are what is output to the screen, the non *STR are
> what's used to build the command line and execute.
> replace CXX with CC for C compiles..
> You can see the complete list of such variables in the manpage:
> https://scons.org/doc/production/HTML/scons-man.html
>
> Hope this helps~!
> -=Bill
>
> On Sun, Jan 21, 2024 at 11:07 AM Mats Wichmann <mats at wichmann.us> wrote:
>
>> On January 21, 2024 5:40:14 AM MST, daggs via Scons-users <
>> scons-users at scons.org> wrote:
>> >Greetings,
>> >
>> >I want to add a prefix the compile line scons is displaying, is it
>> possible?
>> >
>> >Thanks,
>> >
>> >Dagg
>> >_______________________________________________
>> >Scons-users mailing list
>> >Scons-users at scons.org
>> >https://pairlist4.pair.net/mailman/listinfo/scons-users
>>
>> yes.
>>
>> sorry not at a place I can answer more fully, but can modify the relevant
>> COMSTR (command string), or supply your own $PRINT_CMD_LINE_FUNC
>> --
>> Sent from my Android device with K-9 Mail. Please excuse my brevity.
>> _______________________________________________
>> 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/20240121/c2b4c825/attachment-0001.htm>


More information about the Scons-users mailing list