Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor build system, remove hvt compile-time specialization #345

Merged
merged 3 commits into from
Mar 28, 2019

Conversation

mato
Copy link
Member

@mato mato commented Mar 27, 2019

This is step 1 of #326. Note that as I'll be offline for about two weeks starting this Friday, I am going to merge this at the latest by tomorrow morning. As far as I know there are no major showstoppers and the shortcomings can be fixed later.

/cc @ricarkol @djwillia @hannesm (FreeBSD) @adamsteen (OpenBSD) @Kensan (Muen) @ehmry (Genode).

Note that I have not tested Muen or Genode beyond build-testing. I have also not tested the result of this with downstream Mirage/Solo5 on anything other than Debian (which is also being done by the E2E CI now).

@ehmry There was some confusion in "which set of CFLAGS / LD / LDFLAGS" was used for Genode in the old build system, I think I've picked the right ones in the new version but you might want to double-check.


This is a large change, and the majority of it is effectively a full
re-write of the build system. The actual removal of hvt compile-time
specialization is fairly straightforward.

User-visible changes:

  • 'configure.sh' now needs to be run manually before running 'make',
    this is consistent with POLA.
  • conversely, 'make clean' no longer cleans Makeconf. Use 'distclean' or
    'clobber' for that.
  • 'configure.sh' will now print the targets that can (will) be built on
    this system. The strategy is still "build everything we can", however
    I have disabled Genode on all systems except Linux due to toolchain
    issues.
  • You can now build a subset of targets from the top-level 'make', by
    specifying 'CONFIG_XXX=' (disable) or 'CONFIG_XXX=1' (enable) either
    on the command line, or editing the generated Makeconf.
  • Makefiles use silent rules by default. To get the old verbose ones
    back, use 'make V=1'.
  • The 'solo5-hvt' tender is no longer "specialized" to the unikernel.
    We build two tenders, 'solo5-hvt' with all non-debug modules
    configured and 'solo5-hvt-debug' with additional debug modules (gdb,
    dumpcore where available).
  • 'solo5-hvt-configure' is kept around for now for backward
    compatibility with OPAM/MirageOS but is essentially a NOP.

Developer-visible changes:

  • The build system now has proper support for auto-generation of
    dependencies. This means you can safely edit source files, run make
    and be sure you will get a complete incremental build.
  • Makefiles have been refactored to use common best practices, remove
    repetition, consistent variable names and clear interfaces between
    configure.sh/Makeconf/Makefiles, all the while keeping them simple
    enough to understand for me on a Monday morning before coffee. I.e.
    limit use of macros, eval, etc.
  • hvt tender modules are no longer defined by compile-time flags,
    instead a dynamic array is placed into a special ELF section
    (.modules). This means that a hvt tender binary can be combined from
    an arbitrary set of hvt_module_XXX object files, which is the right
    way to do things going forward and also simplifies the build system
    (not needing to build multiple targets from the same set of sources).

Shortcomings / TODOs:

  • Dependency files (*.d) are stored in-tree. I spent several days on
    trying to figure out how to get them to work out of tree, but in
    combination with the non-recursive use of subdirectories in 'bindings'
    I could not figure out the required Makefile magic.
  • HVT_DROP_PRIVILEGES=0 is non-functional with the new modules
    arrangement, but needs a re-design anyway.

Other changes included as part of this PR:

This is a large change, and the majority of it is effectively a full
re-write of the build system. The actual removal of hvt compile-time
specialization is fairly straightforward.

User-visible changes:

- 'configure.sh' now needs to be run manually before running 'make',
  this is consistent with POLA.
- conversely, 'make clean' no longer cleans Makeconf. Use 'distclean' or
  'clobber' for that.
- 'configure.sh' will now print the targets that can (will) be built on
  this system. The strategy is still "build everything we can", however
  I have disabled Genode on all systems except Linux due to toolchain
  issues.
- You can now build a subset of targets from the top-level 'make', by
  specifying 'CONFIG_XXX=' (disable) or 'CONFIG_XXX=1' (enable) either
  on the command line, or editing the generated Makeconf.
- Makefiles use silent rules by default. To get the old verbose ones
  back, use 'make V=1'.
- The 'solo5-hvt' tender is no longer "specialized" to the unikernel.
  We build two tenders, 'solo5-hvt' with all non-debug modules
  configured and 'solo5-hvt-debug' with additional debug modules (gdb,
  dumpcore where available).
- 'solo5-hvt-configure' is kept around for now for backward
  compatibility with OPAM/MirageOS but is essentially a NOP.

Developer-visible changes:

- The build system now has proper support for auto-generation of
  dependencies. This means you can safely edit source files, run make
  and be sure you will get a complete incremental build.
- Makefiles have been refactored to use common best practices, remove
  repetition, consistent variable names and clear interfaces between
  configure.sh/Makeconf/Makefiles, all the while keeping them simple
  enough to understand for me on a Monday morning before coffee. I.e.
  limit use of macros, eval, etc.
- hvt tender modules are no longer defined by compile-time flags,
  instead a dynamic array is placed into a special ELF section
  (.modules).  This means that a hvt tender binary can be combined from
  an arbitrary set of hvt_module_XXX object files, which is the right
  way to do things going forward and also simplifies the build system
  (not needing to build multiple targets from the same set of sources).

Shortcomings / TODOs:

- Dependency files (*.d) are stored in-tree. I spent several days on
  trying to figure out how to get them to work out of tree, but in
  combination with the non-recursive use of subdirectories in 'bindings'
  I could not figure out the required Makefile magic.
- HVT_DROP_PRIVILEGES=0 is non-functional with the new modules
  arrangement, but needs a re-design anyway.

Other changes included as part of this PR:

- Revert privilege dropping on FreeBSD (see discussion in Solo5#282).
- The build system changes effectively implement option 1 in Solo5#292, i.e.
  on x86_64 -m no-red-zone is only used for bindings, not for
  application code.
- tests/tests.bats has been refactored for DRY as it was getting totally
  unmaintainable.
@mato
Copy link
Member Author

mato commented Mar 27, 2019

Note that the failures for 13-basic-x86_64-Debian10 and 14-basic-x86_64-OpenBSD64 are in the tests, I am not going to attempt to fix those at this time. Will open separate issues for those once merged.

@mato
Copy link
Member Author

mato commented Mar 27, 2019

(This PR is intended mainly as a heads up and to document the changes made, I'm not actually asking people to review the build system changes, unless you feel particularly masochistic...)

This is the equivalent of Solo5#342, required for OpenBSD 6.5+.
Copy link
Collaborator

@ricarkol ricarkol left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All good, just a nit and a suggestion.

Tested it on a rhel7 (gcc 5), an ubuntu 16.04 (gcc 7), and an ubuntu 18.04 (gcc 7).

configure.sh Outdated
;;
aarch64-*)
TARGET_ARCH=aarch64
aarch64-linux*)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to have it as x86_64-*linux*. My rhel:

$ cc -dumpmachine
x86_64-redhat-linux

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, thanks!

*/
extern struct hvt_module *hvt_core_modules[];
struct hvt_module {
const char *name;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use const char name[32]; (the compiler will complain if 32 is too small) then the modules section can contain the name like below:

[kollerr@oc6638465227 solo5]$ readelf -x modules tenders/hvt/solo5-hvt
Hex dump of section 'modules':
 0x00606180 636f7265 00000000 00000000 00000000 core............
 0x00606190 90184000 00000000 00000000 00000000 ..@.............
 0x006061a0 00000000 00000000 00000000 00000000 ................
 0x006061b0 00000000 00000000 00000000 00000000 ................
 0x006061c0 626c6b00 00000000 00000000 00000000 blk.............
 0x006061d0 202e4000 00000000 e02d4000 00000000  .@......-@.....
 0x006061e0 d02d4000 00000000 00000000 00000000 .-@.............
 0x006061f0 00000000 00000000 00000000 00000000 ................
 0x00606200 6e657400 00000000 00000000 00000000 net.............
 0x00606210 40344000 00000000 20384000 00000000 @4@..... 8@.....
 0x00606220 30324000 00000000                   02@.....

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh, yeah, the .modules stuff is a bit raw. I'm not going to change it now, will revisit when I get back.

Handles e.g. RHEL which uses 'x86_64-redhat-linux'.

Thanks to @ricarkol.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants