#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.