Source: http://www.mingw.org/wiki/RelocatableHOWTOforMinGW
Timestamp: 2019-04-24 09:55:34+00:00

Document:
Target of this document: trying to better understand the effect of build time options on the resulting MinGW GCC's default paths. This is done testing the effect of some configuration options. These tests target the wish to have a multi-arch singled-versioned and relocatable installation directory. Comments and analysies given in this document, all goes to this direction. This document may not fullfill expectations from peoples with other wishes.
Test builds are done on Windows (XP or whatever below and above will probably give the same result) using MinGW as the C compiler and mSys as the build environnement (this is mandatory to run configuration and make scripts).
The document is divided into two main parts: tests at build time and tests with a relocated installation directory (the bigest part), followed by two chapter acting as a kind of annexes : §8 which deals with some troubles you may meet during the build process or later with the produced MinGW GCC environnement, and §9 which help you to solve default include path troubles with the produced MinGW GCC environnement.
A native compiler will be built the same way as if it was a cross compiler, to have a cleaner installation (each archs beside of each others, even the native one).
You will see these test1, test2, test3 in some paths list later. Do not forget what it is standing for (see above).
The build was started frm a build directory beside the source directory, with an installation directory bside the two laters, the a make and a make install was runned. The installation directory initially only contains <arch> and <arch>/test1 and <arch>/test2 and <arch>/test3.
Some thing was then deduced from error messages during the build process.
This mingw/include directory is mandatory during the build process, but it may be empty (the build process can terminates normally with an empty mingw/include).
The build process obviously complains about missing includes. Some test were done to list all directory where theses includes may be found.
The <install-dir> did not contained any libs. The build still terminates normally.
Includes needed for the build process, are searched only in <arch>/include and in <build-sysroot>/mingw/include. It is worth to notice that <sysroot>/mingw/include is not searched nor is <sysroot>/include.
Next, <install-dir> is renamed into an <reloc-dir>, to test how install relocation works.
Note: this list was obtained with “./gcc --print-search-dirs” and “./gcc -v -c test.c”, after reformating and canonicalization of paths, followed by some symbolic substitutions.
Suspected bug: Did you notice the first include path ? It seems there is a bug here. Two absolute paths are appended. I've meet it every time during all the teste I've made. I've also found some buggy paths concatenation in some Configure.log files. I dunno if it is a MinGW GCC bug or a configuration script bug or an mSys bug.
Note: some paths were printed with “/” as the path separator while some other was printed with “\” as the path separator. I've substitued all with “/” as MinGW GCC accept both.
Notice that <arch>/include only exist with the <install-dir> prefix. This may be a trouble (we will see later for the reason why).
Notice that the directory test3, which stands for --build-sysroot does not exist any more in the default search paths. It is only used at build time.
Note: this list is obtained removing all paths starting with <install-dir> and paths which are POSIX paths (ex. “/usr/libexec”), thus keeping only paths starting with <reloc-dir>. The first include buggy path was removed too (unusable anyway).
It seems the directory mingw in expected in test1 (unlike at build time, where it was expected in test3).
Remind that test1 stands for sysroot.
Note: this list was obtained removing all paths containing <version>.
In the purpose of a multi-arch single versioned and relocatable installation, we notice there gonna be a trouble with the default include paths : it only looks in <reloc-dir>/<arch>/test1/mingw/include.
-prefix, which was <reloc-dir>/lib/gcc/<arch>/<version>/ (see §3.3 and §3.4), use a versioned directory only.
The favorite path for programs would probably be <reloc-dir>/<arch>/bin/, the favorite paths for libs would probably be <reloc-dir>/lib/ and <reloc-dir>/<arch>/lib/. There are no good candidates for includes (an <arch>/include would be nice).
A special specs file may be needed to workaround the default include paths problem (see §9 later).
In §2.2, we've seen that the build process expect a mingw/include directory in build-sysroot, while it does not expect it in sysroot. Further more in §2.3, we've seen that sysroot/include and sysroot/mingw/include were not searched for includes and in §3.1 and §3.2, that the build-sysroot does not exist in default search paths. As this seem a bit weird that sysroot was not working the same way as build-sysroot, another test was runned, using the same path for both --with-sysroot and --with-build-sysroot and run all the same tests as for from §2 to §3. Note: to not be too much borring, only the differences will be given.
The context can be sumarized like this : test3 does not exist any more and --with-build-sysroot has the same value as --with-sysroot.
The build process now expect mingw/include in test1.
Do not not forget that test3 does not exist anymore in this context.
The item initial item #4 is now at position #5 and the initial item #5 is now at position #4. The only difference is the permutation of <reloc-dir>/<arch>/test1/mingw/include and <reloc-dir>/lib/gcc/<arch>/<version>/include which are still the last in the search list.
Paths are the same as in §3.3, excepting that two include paths are swaped, what is a very important thing.
All paths are exactly the same as in §3.5 (there was only one include path, so we can forgot about the permutation).
The comment about the include path is the same as in §3.6, that is to say “ There are no good candidates for includes ”.
The latter tests in §4 were made using the same path for sysroot and build sysroot. It was interresting to test weither or not the result would be the same whith no build sysroot, providing in this case, build sysroot is supposed to be defaulted to the value of sysroot. So we may expect the result to be the same, but it is not exactly : the two last include search paths are swaped again, thus the order is back to the same as in §3.1.
Although this seems funny at first sight, using a build sysroot with the same value as sysroot or using no build sysroot at all, has an impact on the default include search paths ordering.
For a multi-arch single versioned installation, the sole default include path is the same as for §3 and §4.
All the remaining stuff is the same as the whole of §4.
Surprizingly, the --with-local-prefix option does not seems to be used (at least, to have any impact) at build time nor at run time. It does not appears in any include search paths at build time, and it does not appears in any default paths at run time.
To check if it is has any effect or not, a test was done, giving the local prefix option, the same value as the sysroot option.
The result is a bit like the as with §5, that is to say that there is a swap of the two last default include search paths, which are in this case, the same as in §4, that is to say the same than the case where both sysroot and build sysroot was the same. This may seems strange : local prefix had not any effects so far, but it has one on the ordering of the default include paths when its value is the same as the one given for sysroot.
A second test was made, giving no local prefix option at all (i.e. there is a lonely sysroot option). The result is exactly the same as above, when the local prefix was assigned to the same value as the sysroot option (the order here is the same as in §4.3).
Now back to a context similar to the one of §2. The difference will be that we will use <install-dir>/<arch> as the argument for the three options (no more test1, test2 and test3).
The results of the tests done here was predictable, while it was in the mean time better to ensure about it.
After the tests are done, as you may have guessed, the ming/include path is now expected in <install-dir>/<arch> and includes required during the build are now searched in <install-dir>/<arch>/include and in <install-dir>/<arch>/mingw/include.
The resulting MinGW GCC has the same installation and program paths as in §2 (and all the others up to §6 by the way). The main part of the libs paths is the same, while beeing different at the end of the list. Which is obvious, beceause test1 does not exist any more. The default include paths list is different as well, mainly for the same reason as the one of the default lib paths.
This is just that test1 has disappeared, there are not more impact.
One again, the only difference is that test1 has dissapeared.
Notice that the last two include path, excepting the fact that test1 is not there in the second list, are swaped. The last two elements of the default include paths are indeed easily swaped and the order is very sensitive to the options. No test were made about the swap condition this time (to not to be too much long), but we may guess it is swaped in the same conditions as in §4, §5 and §6.
Notice that the first default include path still shows the same concatenation bug. This bug is indeed very persistant. This concatenation may have sense if the <install-dir> could be a relative path, but it cannot : the configuration script expect --prefix to be assigned with an absolute path.
Notice that there is still no good canditates for the default include path in the context of a single versioned relocatable installation.
There are still both relocatable, but only -isysroot is not versioned.
If one scrupulously check the rules given is this document to predict the effects of its own paths configuration options and although he/she give all the necessary include files for MinGW in the mingw/include directory (a nice choice, indeed), he/she may still face some failures at build time.
What is noticable here, is that <install-dir>/<arch>/mingw/include is not search for includes.
This only appens during the configuration/build of libssp (a library for stack smashing protection). If the creation of this library is disabled by the configuration option --disable-libssp, then the trouble does not express any more.
This seems to be a bug in the pre-build configuration script of libssp. This may be useful to check if weither or not this bug is specific to all versions of MinGW GCC sources or not.
As shown the options given to the command which is in failure, the file “stdio.h” was not found, beceause the directory mingw/include was not searched. But the directory <arch>/include is searched.
Using <arch>/include temporarly and then moving its content in mingw/include after “make install” is done.
To put ANSI C include files in <arch>/include and left MinGW specific includes in mingw/include (the include files which cause the failure are all standard ANSI C include files). See later comment.
Do not build libssp (but do not make this choice just due to this bug, as there are workarounds).
If you choose to split include files, moving standard C files in <arch>/include and specific MinGW include files in <arch>/mingw/include, you will have to move all ISO C include files in <arch>/include (see the list later), plus the includes fcntl.h, io.h and all of the sys/*.h (which are not part of ANSI or ISO C) and the _mingw.h as well. The file _mingw.h is referenced by all include files, even ANSI/ISO C include files.
Remember that this is more a bug than a MinGW GCC configuration property ! The remaining of the libssp build process cleanly make reference to mingw/include. Only the pre-build configuration seems to be broken.
Although all of this is about a bug, it is still nice to split include files with ANSI/ISO C files on one side and MinGW include files on an other.
The trouble during the build of libIberty is the same as the one with libSSP : it does not search in <arch>/mingw/include for includes file and fails to find the file windows.h. Unfortunately, there is not a nice work around here, like the one to separate ANSI/ISO C files in a folder and MinGW files in an other. But there is a moderately nice solution : create an <arch>/sys-include directory and copy all the content of <arch>/mingw/include in this directory. This will work beceause even if we did not specify any sys-include path in the configuration options, the build of libIberty for MinGW GCC will anyway look in <arch>/sys-include.
This sys-include directory will have to be deleted after make install has been run.
Building the GCC suite, requires to specify an installation directory. For a relocatable MinGW GCC, a temporary installation directory will be used. We must take care that this temporary installation directory may ends in hard coded built-in paths. The place where GCC will be installed, may or may not use the same path as the temporary installation directory. If it is the same, GCC will behave differently than when it is not. This may ends up in unconstant behaviour. Another kind of trouble may occur specially when building the compiler it self with a previous version of the compiler we've build ourself : if we always use the same name for the temporary installation directory, during the compiler build process, the compiler gonna use the temporary installation directory to look for include and libraries. This will most of time ends into errors.
Let give an example : a first build is made using directory A the temporary installation directory. Let this version of the build be B1. Then, the B1 replace the working MinGW GCC. Then, if a second build of the same compiler, let call it B2, is done using the same directory A as the temporary installation directory. The working MinGW GCC, which is B1, will have built in paths pointing to A, thus, during the build process of B2, it will look in A. Which will turns into trouble.
To avoid this, it is recommanded to use a unique and preferably non-common directory name for the temporary installation directory. This name must be different for each build. A simple way to achieve this is to create a directory name base on the actual date time, including seconds.
We simply get the result of the command "date" and replace every thing which is not a digit by nothing.
This is just an exemple. You may use any other solution with the required property of uniqueness for each build and beeing a non-common directory name.
Building MinGW using a MinGW installation which was previously builded by you own, may ends up in errors during the build of libssp.
It seems this is a bug which has already occured in MinGW in 2004, and was solved. Perhpas its back again. I do not know any workaround, and the only solution was to use the option --disable-libssp when building GCC.
It seems there are some bugs during the configuration process, with path concatenation. Thus, some include files may not be found during the build process. Or else, if your installation use no version directories (ex. gcc/<version>/lib), some libraries may not be found during the build process as well. Testing <build-dir>/gcc/xgcc will give you some hints about the place where the requested files may belongs. With these tips in hands, you may be tempted to duplicate some include or librarie files in one of these places. This is indeed a good idea, but there are some recommanded rules. The first hint, is to avoid doing so in the source directory. You should prefer the build directory for this purpose. Then you must take care to not confuse between host and target files. For this reason, you should only duplicate target file from a folder which explicitely states that its content is a target content (ex. i386-pc-mingw32 from the temporary installation directory) to another subfolder of the build directory which as well explicitely states that its content is a target content (same exemple as the prior one). To give one more hint, experience shows that if the target is ming32, then you may copy <install-dir>/<arch>/include and <install-dir>/<arch>/mingw/include to <build-dir>/<arch>/mingw/include (all mixed in <build-dir>/<arch>/mingw/include), and the same with the lib directories.
Any way and what ever will be your choice, keep in mind it is not a good idea to modify the content of the source directory (for this purpose only, there may be some good reason for other purposes) and to not confuse between host and target files.
As seen before, in some circumstances, the set of paths we may rely on, depending on requirements, may left us with a single default include path which will only search for include files in <reloc-dir>/<arch>/mingw/include. Adding a default path to <reloc-dir>/<arch>/include would be nice there, as well as an include path pointing to <reloc-dir>/include, for plateforme independant includes (there are a few exemples in C, but it is much more common with portable langage like Ada).
The best way to do so, for any one who want to avoid invokation-time parameters and make it working like a default search path, is to update your specs file. If you don't have any specs file, you may create an initial one before you may expect to modify one. Do so with the command “gcc -dumpspecs >specs”. You will then have to move the specs file in one of your library search paths. The most common default location for the specs file is <reloc-dir>/lib/gcc/<arch>/<version>, but believe me, <reloc-dir>/<arch>/<lib> is also a very nice idea. Do not forgot to ensure the path is in you libraries search path (if there are any doubts, run a “gcc -v” to be sure).
The idea is to add two “-idirafter” options to the default CPP invokation parameters. This option fulfill all what we need : it works like the well known “-I” option, with the difference that it will add the path in the system include directory set. This is exactly what we want.
For more information about this option, see GCC Manual: Options Controlling the Preprocessor.
So we will have to add an “-idirafter” option for our <reloc-dir>/<arch>/include path and another one, after (it is important to put it after), for our <reloc-dir>/include path.
All remaining needs so far, is thus a way to have the <reloc-dir>/<arch> string.
Depending on the version of (MinGW) GCC you've build, there are two different options. From GCC 4.3.3, new improvement were added in the way to pass parameters to the GCC's command line, which will help us. But for GCC with prior version number, we will need another trick.
Let start with what's new as of GCC 4.3.3. It adds the capabilities to pass path parameters as paths relative to the actual isysroot, using the “=” sign as a prefix of the path. Let me explain with an exemple: the path “=/abc” would turn into “/test/abc” providing that your isysroot is “/test”.
So we just need to have a GCC which was configured with <install-dir>/<arch> as the sysroot. Fortunately, when the sysroot is a subdirectory of the installation directory, GCC will see it as a relative path, so that the sysroot will automatically evaluated from the actual location of GCC. Thus, sysroot will be <reloc-dir>/<arch>, what ever will be <reloc-dir>.
To update your specs file with GCC_4.3.3 or above, you will have to search for the “*cpp:”, then to append the two options to the line just below.
You will have to apply the exact same modification for all of your specs file for each of you targets.
One more step forward to the core default stuff: to achieve a real default effect, we may also modify the builting specs source for GCC, before we build it, with a modification of the file <src-dir>/gcc/cp/lang-specs.h . This way, it would be a real built-in specs.
Unfortunatly, an attempt to apply the latter solution with a GCC whose version is less than 4.3.3, will turn into an error : these versions of GCC do not know about this new meaning of “=” when it occurs as a path prefix, as you may check in GCC 4.2.4 Preprocessor-Options. Facing an attempt to use something like “=/include”, GCC will simply complains that “=/include” does not exist.
Things gonna be less nice, beceause this will not be relocatable. But we may at least try to make things as simple as possible. The modification to apply to the specs file will be very similar to the latter one, with the difference that we will need one more thing, to workaround the lack of beeing able to express paths relatively to the actual sysroot. We may also not be able to make it a default built-in specs, beaceause as you will see later, we will need an hard coded path string.
Do not forget to add an empty line juste after !
These two lines will act as a convenient variable we will use later.
As you see, <arch> appears in the text. This means you will have to modifiy all the specs files for each of your targets specifically. And as the <reloc-dir> appears in the string, this means you will have as well to update this whenever you move your GCC environnement installation directory.
Do not forget to put a space before.
The latter modification will be the same for all of your specs files of each of your targets (arch). The sole thing which will differ for each of your target, will be the path we've added at the begining of the specs file. If you do a copy past, take care of the <arch> part !
You will have to update these paths whenever you move your installation directory, as it is obviously not relocatable (hard coded absolute paths).
There are no way to make it a built in specs in MinGW GCC lower than _4.3.3 (as explained before).

References: §8
 §9
 §3
 §3
 §9
 §2
 §2
 §3
 §3
 §2
 §3
 §3
 §3
 §3
 §4
 §3
 §3
 §4
 §4
 §5
 §4
 §4
 §2
 §2
 §6
 §4
 §5
 §6