[haiku-bugs] Re: [Haiku] #8730: Improve the build system for building on Haiku

  • From: "bonefish" <trac@xxxxxxxxxxxx>
  • Date: Sun, 15 Jul 2012 13:26:00 -0000

#8730: Improve the build system for building on Haiku
----------------------------+----------------------------
   Reporter:  mmadia        |      Owner:  mmadia
       Type:  enhancement   |     Status:  assigned
   Priority:  normal        |  Milestone:  R1
  Component:  Build System  |    Version:  R1/Development
 Resolution:                |   Keywords:
 Blocked By:                |   Blocking:
Has a Patch:  0             |   Platform:  All
----------------------------+----------------------------

Comment (by bonefish):

 First of all let me repeat the disclaimer: This is a lot of tedious work.
 Moreover, it may turn out that the approach doesn't even work. E.g. I
 haven't fully thought through how to deal with code that uses the STL --
 there are a few options but neither may work in the end.

 Here's the goal we're aiming at: The build tools written for Haiku (like
 addattr, xres,...) need to be built for the build platform in such a way
 that the environment (i.e. the headers that are included when compiling)
 closely resembles the Haiku environment (the working directory version).
 And obviously the tools built this way must also work on the build
 platform.

 To achieve this goal any header that is included by the build tools
 (recursively) must be provided by the build system. We do that already for
 the Haiku headers (headers/build/os), but it must also be done for the
 POSIX headers (not yet existent: headers/build/posix) with a few
 exceptions for headers provided by the compiler (e.g. stddef.h and
 stdarg.h). The headers BeOSBuildCompatibility.h and
 HaikuBuildCompatibility.h twist the build platform environment so that it
 looks more like Haiku's. Consequently they will no longer be needed, since
 we will provide a Haiku environment.

 Providing the headers is only half of the deal. The build system must also
 provide the implementation for the stuff the headers declare. The current
 build system already does that for the Haiku specific part. There's a
 libbe_build.so (src/build/libbe) which implements the libbe API. There's
 also a libroot_build.so (src/build/libroot) which implements the Haiku
 specifics of the libroot API (attribute functions, find_directory(),
 etc.). libbe_build will remain mostly unchanged, but the libroot_build
 part will need to be extended to also cover all the POSIX functionality.

 Obviously a lot of this functionality cannot be implemented from the
 scratch or it is at least not desirable to do so. Instead we want to map
 it to the build platform's implementation. And that's where things get
 tricky. You can't call the build platform's `vfprintf()` from the build
 system's `vfprintf()` implementation, since they have the same name.
 Moreover, if the build platform supports symbol preemption, we'd actually
 override the build platform's libc/libroot symbols. Hence the functions
 must be named differently. In fact all macros, types, and global variables
 need to be named differently, too, since otherwise they would clash with
 the ones from the build platform header which needs to be included to be
 able to call the build platform function.

 This means that the build system headers must be designed to be included
 in two different ways. When included from the build tools' code they must
 define the standard functionality but at the same time map it to new
 names. When included from the libroot_build code that implements the
 functionality, they must define the functionality only with the new names.

 As mentioned in the ticket description the FS shell does something
 similar. It needs to provide a Haiku kernel environment, so that the BFS
 (or other FSs) code can be built on the build platform. It provides a
 headers for the functionality to be emulated (e.g.
 headers/private/fs_shell/fssh_stat.h) where everything is defined with a
 `fssh_`/`FSSH_` prefix. Furthermore it provides a header
 (headers/private/fs_shell/fssh_api_wrapper.h) that maps all prefixed names
 to the standard names via macros. The latter header is included in the BFS
 code (when built for the FS shell). Only the former header is included in
 the implementation of the functionality (e.g.
 src/tools/fs_shell/stat.cpp). That the headers don't have the standard
 names and that a single wrapper header was used, is just because it was
 simpler to do that in this context. The mapper macros could just as well
 have been defined in the individual headers, guarded by an #ifndef.

 Basically that's the approach I was thinking of for the build tools as
 well. The mapping via macros should be done only for macros, though, since
 that potentially maps stuff one doesn't want to map (e.g. the macro for
 `stat` not only maps the `stat()` function and the `stat` structure, but
 also anything else with that name -- like the `stat()` method of some STL
 class). Instead structures and typedefs should just be defined with the
 respective name depending on the context of inclusion. Functions should be
 mapped via the asm name feature. That should be aided as much as possible
 via helper macros. Example of how that would look in a header:
 {{{
 // types/enums/...
 typedef enum {
    _HAIKU_BUILD_IDENTIFIER(B_DESKTOP_DIRECTORY) = 0,
    _HAIKU_BUILD_IDENTIFIER(B_TRASH_DIRECTORY),
    ...
 } _HAIKU_BUILD_IDENTIFIER(directory_which);

 // functions
 _HAIKU_BUILD_DECLARE_FUNCTION(
        status_t, find_directory,
                (_HAIKU_BUILD_IDENTIFIER(directory_which) which,
                 _HAIKU_BUILD_IDENTIFIER(dev_t) volume, bool createIt,
                 char* pathString, _HAIKU_BUILD_IDENTIFIER(int32) length))
 // Note: To make things a bit shorter, for standard types like int32 or
 dev_t
 // _haiku_build_* could always be defined and be (conditionally) mapped
 via
 // typedef to the unprefixed type, so that _haiku_build_int32 could be
 // written here.

 // macros
 #define FOO 0
 #if __INTEL__
 #  define LITTLE_ENDIAN 1
 #endif

 #ifndef _HAIKU_BUILD_LIBROOT_FUNCTION_WRAPPER
 #  define _HAIKU_BUILD_FOO FOO
 #  ifdef LITTLE_ENDIAN
 #    define _HAIKU_BUILD_LITTLE_ENDIAN LITTLE_ENDIAN
 #  endif
 #endif // _HAIKU_BUILD_LIBROOT_FUNCTION_WRAPPER
 }}}

 In order to be able to include both the build system and the equally named
 build platform headers in the libroot_build sources, it is probably
 easiest to provide two build system headers for each standard header. E.g.
 there would be a headers/build/posix/stdio.h that only includes
 headers/build/posix_haiku/haiku_stdio.h which contains the actual stuff.
 The headers in headers/build/posix_haiku only include other haiku_*
 headers. Consequently the libroot_build code would not have the
 headers/build/posix path in the include search paths, so that it can
 include the build platform's stdio.h and haiku_stdio.h at the same time.

 The libroot_build implementations should be pretty similar to the ones in
 the FS shell. I.e. they need to map types and values of parameters and
 (opposite direction) return values. In some cases more has to be done
 (like the attribute functions) but mostly the code for that should already
 be present in the current build system.

 Regarding how to proceed, I'd recommend the following:
  * Get rid of {BeOS,Haiku}BuildCompatibility.h.
  * Add empty headers for all POSIX headers in headers/build/posix
 (simplifications may be possible, e.g. in the stdio* case -- stuff that
 exposes internals should best be omitted) and adjust the build system that
 they are included in the right contexts.
  * Try building libroot_build. It will fail. Add the
 headers/build/posix_haiku headers and include them from the respective
 headers in headers/build/posix. Eventually everything will compile but
 fail to link. Implement the needed functions.
  * If there is any, try building a build tool that only uses libroot
 functionality. Add the missing headers and libroot_build implementations
 it requires. Once it builds it should also work.
  * Try building libbe_build. More POSIX headers and libroot_build
 functionality will be needed. Note that only libroot_build itself
 (possibly not even all files of it) should be built in
 `_HAIKU_BUILD_LIBROOT_FUNCTION_WRAPPER` mode.
  * Try building the remaining build tools and add all missing stuff.

 I left out the STL issue. Code that needs a Haiku environment might also
 need the STL. This may or may not be a bigger problem. First of all, the
 STL headers must be prevented from including any build platform POSIX
 headers, so any that aren't in headers/build/posix yet need to be added.
 The purely templatized code that doesn't have an instantiation in
 libstdc++ will probably be fine. Other stuff may clash with the Haiku
 build environment, though (possibly only noticed when the tools using it
 crash). It probably also depends what parts of the STL are actually used.
 So I'm still hoping for the best. If that doesn't work, things get tricky.
 We could either try to provide a mini STL ourselves or build a complete
 one for our Haiku build environment from the build tools sources. Either
 approach may fail as well.

 I'll attach a patch of the branch I was using for working on the issue. It
 isn't in any useful state. I had worked on one approach, decided not to go
 with it, and experimented with another one. So use as reference only. E.g.
 there's a definition of the `_HAIKU_BUILD_DECLARE_FUNCTION()` macro you
 can probably recycle and maybe you find other stuff that could be helpful
 as well.

-- 
Ticket URL: <http://dev.haiku-os.org/ticket/8730#comment:2>
Haiku <http://dev.haiku-os.org>
Haiku - the operating system.

Other related posts: