#3351 closed enhancement (fixed)

libbsd: Introduce buildsets that allow to enable or disable parts of libbsd to get for example smaller or faster configurations.

Reported by: Christian Mauderer Owned by: Christian Mauderer
Priority: normal Milestone: Indefinite
Component: network/libbsd Version: 5
Severity: normal Keywords: libbsd waf IPSec
Cc: Blocked By:
Blocking:

Description

I'll start in the next few days to add IPSec (client) support to the libbsd. Because IPSec is quite deeply integrated into some parts of the network stack it would have quite a performance impact on every system and not only the ones using IPSec. Therefore it is necessary to compile this support only conditionally.

From my point of view that means that the build system needs two new capabilities:

  1. For IPSec the whole stack has to be compiled with certain defines. If I understood the FreeBSD build system correctly these defines would be set via generated header files. In RTEMS we have static files for that (like rtemsbsd/include/rtems/bsd/local/opt_inet6.h). I see two possibilities:
    1. Generate the headers depending on a configure option.
    2. Use empty headers like we already do it for a lot of options. Depending on a configure option then add a '-DSOME_OPT=1' to the modules that need it. That one would be my preferred way.
  1. IPSec adds a number of source files that most likely only work if the rest of the stack is compiled with the correct configuration. We already have modules in the libbsd.py. But currently they are added or removed by commenting the matching line in libbsd.py. My approach would be to make it possible to enable or disable the modules depending on a command line switch during configure.

I'm open for any suggestions regarding better solutions.

Change History (16)

comment:1 Changed on Mar 19, 2018 at 8:57:53 AM by Chris Johns

Do we have a single build which creates variant libraries and a user selects which variant they want or do we have a single library built for a specific purpose?

I feel building variant libraries is better solution because every build by a developer checks all variants, and it aids deployment because you do not have users needing to manage specific build instances.

If we can establish how we want to package libbsd in light of this change and the need to have a difference the details will be must easier to manage.

comment:2 Changed on Mar 19, 2018 at 9:39:54 AM by Christian Mauderer

If we build multiple variants in one go we might have a lot of different variants soon because every option would double the variants.

The IPSec is one option but we already had an application where we disabled IPv6 for one specific use case due to size reasons. Another option could be WiFi? or no WiFi? (which adds quite some code which isn't used by many applications). So it would be already eight different versions.

My long-time direction would be to provide options via a configuration file (for example some ini). With that it would be possible to use different default configuration for some BSPs (for example the ones with / without WiFi?). A user could provide his own config that matches his application. I still have to have a more detailed look over the option parser used in waf but I would expect that it can be somehow convinced to read options via a file too.

comment:3 Changed on Mar 19, 2018 at 1:14:23 PM by Christian Mauderer

Just noted: A partial support for setting defines via a waf-option is already there: The --freebsd-option switch for the waf configure call. That one can already set a define. Most likely it would be useful to extend or replace that.

comment:4 in reply to:  2 Changed on Mar 20, 2018 at 2:00:14 AM by Chris Johns

Replying to Christian Mauderer:

If we build multiple variants in one go we might have a lot of different variants soon because every option would double the variants.

Yes. A way to configure and build does not diminish the obligation on all developers making changes to build all possible variants or at least an agreed number. Over the years we have added options to RTEMS's configure and has become a problem. If you add on to the possible configure options the possible BSP_OPTS we have something we can never ever test build not even once. I am attempting to control the issue with the rtems-bsp-builder and it's 1600+ lines of Python. If you review a recent build from Joel (1) you will see the minimal set of 13 build variants I could come up with generates over 1500 build jobs or separate builds of RTEMS. I would like to avoid this as much as possible but recognize it is difficult or impossible to do without limiting the features we want.

(1) https://lists.rtems.org/pipermail/build/2018-March/000553.html

The IPSec is one option but we already had an application where we disabled IPv6 for one specific use case due to size reasons. Another option could be WiFi? or no WiFi? (which adds quite some code which isn't used by many applications). So it would be already eight different versions.

Yes, and while we have used options for this I feel that method may not scale. It has been useful up to now but I think we need to consider something else.

My long-time direction would be to provide options via a configuration file (for example some ini). With that it would be possible to use different default configuration for some BSPs (for example the ones with / without WiFi?). A user could provide his own config that matches his application. I still have to have a more detailed look over the option parser used in waf but I would expect that it can be somehow convinced to read options via a file too.

I would prefer this be a near-term direction and we develop Python code and support so we can define a set of agreed "variant builds" . I see a "variant" consisting of compile options, ie -Os etc, specific defines and specific sets of files. The base build would be a bare stack, for example no IPv6, SSL, etc, and an IPV6 with SSL would be IPV6-SSL = base + IPV6 + SSL.

I am OK with INI files because it is built into Python. YAML would be nice but it requires extra host packages and that creates user support issues. Please take a look at tester/rt/check.py and rtemstoolkit/configuration.py in the rtems-tools repo. It is fine to copy down to this project the configuration file support from the rtemstoolkit.

I think it would be best to leave libbsd.py as it is for now. I would like to move that configuration to an INI format and remove the intermediate step of generating libbsd_waf.py. There is no real need to generate the file other than the former support of Makefile builds. This means we work on a top level INI design and we can flesh out the migration from libbsd.py later. The rtemstoolkit/configuration.py supports includes which allows a tree structure to be formed letting us clip below the needed file sets when that change happens.

The key requirement I would like to have is being able to configuring a build for libbsd that builds all variants we agree are important before submitting a patch. I do not want to have to write another rtems-bsp-builder, I would like that functionality built in.

comment:5 Changed on Mar 20, 2018 at 9:37:37 AM by Christian Mauderer

Thanks for the input. Let me summarize how I understood you.

  1. We try to find an officially supported set of build variants for the library. That list should ideally not grow to more than 20 to 30 variants over time. At the moment I would see the following three (of course we can discuss the exact variants but maybe we should keep that for later (see also note at the end regarding SSL and WiFi?)):
    • Size optimized with about the same functions as the classic stack: no IPv6, no IPsec, maybe no <something else>; -Os
    • Normal functionality that should cover most use cases: basically everything that is available now; -O2
    • IPSec: Normal + IPsec; -O2
    • Debug build: Everything; -Og or -O0
  1. We want to use ini files for configuring the variants.
  1. The system should be build in a way that if the user really wants to build an unsupported variant, he can use some own configuration file.

If that's what you meant I would be OK with this direction. Otherwise please correct me.

Now some more guesswork about the implementation:

  1. The top configuration files would include the following information:
    • The modules to include into the build. That would replace the part that is currently done in libbsd.py in the def sources(mm) with the mm.addModule(...) lines.
    • Extra compiler flags (like -DINET6 or -Og) that should be added to the ones already used for the modules. Some of them would have to be removed from the modules and put here instead (INET6, ...)
  1. Later the rest of the libbsd.py should be migrated to a ini too. But that is not necessarily in the scope of this ticket.
  1. When I'm already busy with changing the build process, it would be good to remove the generated libbsd_waf.py completely (which most likely needs quite some thought).

Is that about what you have thought?

How should we deliver the variants? Install them all and tell the user to use -lbsd_small or -lbsd_ipsec when he links?

Note for the build variants:

Regarding SSL: I hope that this does not influence how other code is built in libbsd. So it should be OK to put it into the base set. It would be only linked in if some application uses it. Of course the installed headers might have an influence on the user application.

Regarding WiFi?: Maybe it's possible to deactivate it by default without an extra build variant. I have already removed quite some big parts by re-defining mainly the _bsd_ifconfig_ieee80211_ctor() as an empty function. If that doesn't work another variant might could be useful.

comment:6 Changed on Mar 22, 2018 at 11:46:18 PM by Chris Johns

Nice summary, thank you.

Yes to 1, 2, and 3. The variants will evolve and I suspect will be driven by user demands. Your initial list is really nice. I really like the first one as an easy step for those migrating from the legacy stack.

I think the 4, 5, and 6 sum up what I was thinking. I am currently swinging between the build details being in an INI file or in a waf script and so Python. I am concerned moving all the build to INI format creates a new build system based on INI files which I would consider a mistake. The configuration management of the parts can be an INI file.

I will take a look at moving the current build to just waf and to remove the generate stage and then report back on how this looks and what I find. I feel time invested in doing this will benefit how we proceed.

comment:7 Changed on Mar 23, 2018 at 6:02:50 AM by Chris Johns

Should libbsd.py we split up into multiple files?

comment:8 Changed on Mar 23, 2018 at 6:52:11 AM by Chris Johns

I think the simplest solution is to:

  1. Leave libbsd.py as is for now. I feel this file can be split into parts after an initial refactoring has been completed.
  1. Create waf_libbsd.py which is a copy of libbsd_waf.py and convert all the self.add('') calls into actual code. I thnk freebsd-to-rtems.py can use the builder.py base class because all it needs to call is processSource() which is all in builder.py.
  1. Add class methods to match the required waf functions:
    1. init
    2. options
    3. bsp_configure
    4. configure
    5. build
  1. Update wscript to create a Modules instance and hold globally. It then uses it for each of it's calls.
  1. Update freebsd-to-rtems.py to use waf_libbsd.py and remove the generate code.

This conversion is not too difficult. The INI configuration support can be built on opt of this. The result is:

  1. List of modules to build
  2. Defines
  3. Compile flags

comment:9 Changed on Mar 23, 2018 at 7:07:16 AM by Christian Mauderer

Thanks for the feedback. I had a look at that yesterday and had a similar course of action in mind. Good to know that you have about the same idea about it. Also I didn't expect that on my initial estimation for that work, removing the generated script will simplify the task a lot so I agree that it is a good idea. It will also make it simpler to understand the build system for anyone looking at it and future adaptions will be easier.

comment:10 Changed on Mar 26, 2018 at 1:44:57 AM by Chris Johns

I have posted a patch to devel for review. It has a couple of issues:

  1. No changes to libbsd.txt
  2. The headers need to all be parse for @CPU@ as bld.env['RTEMS_CPU'] was taken out and replaced with @CPU@.

If you are happy with the direction I can clean up these two issues and push to master.

Note, I have moved a range of configuration pieces from builder.py to waf_libbsd.py._defaults to form the basis of the configuration data. After loading the configuration is updated to reflect the variant being built.

The next step is to add a module level enable control and to default it to True then un-comment the modules which are commented defaulting them to disabled. This will give us 2 more entries in the configuration dict, modules and modules-enabled and by default modules-enabled is copied to modules-build and that list is the modules to build. If we add 'archive-name and defines you are close to supporting build variants. It becomes a simple matter or looping over a config creating a builder` instance for each variant to build a number of variants. All this is done before the first build job is run.

comment:11 Changed on Mar 26, 2018 at 3:06:15 AM by Chris Johns

Enable control requires all the functions in libbsd.py are converted to classes.

comment:12 Changed on Mar 26, 2018 at 8:17:14 AM by Christian Mauderer

Thanks for the work. I had started with a similar patch on Friday and most likely would have posted a first version today if you wouldn't have been faster. So I'm quite OK with that direction. I'll take a more detailed look at your patches and write some more feedback on the mailing list in a few hours.

comment:13 Changed on Apr 10, 2018 at 7:07:54 AM by Christian Mauderer <christian.mauderer@…>

In 854427b/rtems-libbsd:

waf: Add configurations with different modules.

Update #3351

comment:14 Changed on Apr 27, 2018 at 11:47:21 AM by Christian Mauderer

Summary: libbsd: Add support for conditional compilation of modules and compiler flagslibbsd: Introduce buildsets that allow to enable or disable parts of libbsd to get for example smaller or faster configurations.

To make things more user friendly I dropped the original intend to allow to set the compiler flags with the configuration. Otherwise a user would have to know that he has to drop for example the netinet6 module and remove the INET6 compiler flag.

Instead, I now generate a header file that has defines for all enabled modules. That also allows to (for example) simply switch off the constructor for wifi in ifconfig. Without the header, it would have been necessary to enable a "no_wifi" module that provides an empty implementation of that constructor when the wifi-modules are disabled.

comment:15 Changed on May 3, 2018 at 5:22:14 AM by Christian Mauderer

Resolution: fixed
Status: assignedclosed

comment:16 Changed on Jun 5, 2018 at 8:00:35 AM by Christian Mauderer <christian.mauderer@…>

In f8cf074/rtems-libbsd:

beagle: Disable WiFi? if libbsd is build without it.

Update #3351.

Note: See TracTickets for help on using tickets.