Page 1 of 2
DaemonR's assorted tricks
Posted: Sat Aug 16, 2014 8:56 am
by Wajideu
These are just some suggestions for the wiki's tutorial on building a GCC cross compiler.
1. Building an x86_64 compiler
If you're building an x86_64 compiler on a 32-bit pc, make sure you pass the option '--enable-64-bit-bfd' to the configure scripts for both binutils and the gcc
2. Removing the program prefixes
- Export variables for all of your host tools (the ones being used to compile your toolchain) like so
Code: Select all
export SDK_PATH=/C/MinGW
export CPP=$SDK_PATH/bin/cpp
export CC=$SDK_PATH/bin/gcc
export CXX=$SDK_PATH/bin/g++
export AS=$SDK_PATH/bin/as
export LD=$SDK_PATH/bin/ld
export NM=$SDK_PATH/bin/nm
export READELF=$SDK_PAth/bin/readelf
export OBJCOPY=$SDK_PATH/bin/objcopy
export OBJDUMP=$SDK_PATH/bin/objdump
export DLLTOOL=$SDK_PATH/bin/dlltool
export AR=$SDK_PATH/bin/ar
export RANLIB=$SDK_PATH/bin/ranlib
export STRIP=$SDK_PATH/bin/strip
export WINDMC=$SDK_PATH/bin/windmc
export WINDRES=$SDK_PATH/bin/windres
This is to prevent the build process from confusing the host toolchain with the target toolchain. If you don't do this, your build process will probably halt with a linking error; probably something about libiberty or libiconv.
- Pass the option '--program-prefix=""' to the configuration scripts for both binutils and gcc
3. How to change the architecture path.
When you build your toolchain, you'll notice that the architecture dependent files are stored in a subdirectory that has the same name as the target. Like:
Code: Select all
cross
+- bin
+- i686-pc-elf
+- include
+- lib
'- share
However, this looks rather unsightly. To change "i686-pc-elf" to something else, in both binutils and gcc open up config.sub and below where it says "# Recognize the various machine names and aliases" add:
Code: Select all
arch)
basic_machine=i686-pc
os=-elf
;;
Where "arch" is what you want the directory to be called and the variables 'basic_machine' and 'os' are set to the appropriate parts of the target architecture. Then, configure your binutils and gcc with '--target="arch"'. I like consistency, so I just leave the "arch" part the same and change the later 2 for whatever I'm compiling.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sat Aug 16, 2014 10:08 am
by sortie
Hi,
Thanks for compiling this list. Unfortunately, I fear many of these suggestions are bad. I'll try to explain why:
I really don't think --enable-64-bit-bfd is required when making a cross-compiler for a 64-bit system on a 32-bit system. Do you have evidence for this? I would consider it a serious bug in binutils if it is the case. --target should be sufficient. That option only sounds like it would have any effect when making a 32-bit compiler where 64-bit additional targets are not included by default, and this option includes them anyway. I am not absolutely certain here, I'll need to install a 32-bit system in a virtual machine (as all my computers run 64-bit operating systems) and verify.
Why would you possibly want your cross-tools to not be prefixed with a target triplet or something unique? That is mad and causes conflicts with the local toolchain as you discovered. Always prefix your cross-tools.
Lastly what you see in the directory tree is the obscure `tools directory'. You can't override it from the configure line, but it's fairly simple to override the toolsdir variable in the makefile. This is really of no concern when cross-compiling, you don't want to actually use the programs in that directory directly, just use the regular ones in the bin directory that have the target triplet prefixed.
These suggestions should not be added to the wiki for these reasons. --enable-64-bit-bfd might need to, if there is a bug like you claim, but I'm not convinced that's true.
Please explain why you wish to have your cross tools not prefixed with the target tripled. I think you are misguided and I might be able to advise you on a better way to proceed.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sat Aug 16, 2014 10:37 am
by xenos
DaemonR wrote:Export variables for all of your host tools (the ones being used to compile your toolchain) like so
This is to prevent the build process from confusing the host toolchain with the target toolchain. If you don't do this, your build process will probably halt with a linking error; probably something about libiberty or libiconv.
This linking error never happened to me, and I don't know of anyone else who encountered this problem. I dare to say that a linking error is a lot less probable than you assume.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sat Aug 16, 2014 12:06 pm
by Wajideu
sortie wrote:I really don't think --enable-64-bit-bfd is required when making a cross-compiler for a 64-bit system on a 32-bit system. Do you have evidence for this?
I'm not sure if it's reproducible, but I've tried building the gcc numerous times for x86_64-pc-elf, and while binutils would compile fine the gcc itself would often crash towards the end. I was using a 32-bit MinGW as a host. According to the documentation, the option was made specifically for targeting 64-bit architectures using 32-bit hosts.
sortie wrote:Why would you possibly want your cross-tools to not be prefixed with a target triplet or something unique? That is mad and causes conflicts with the local toolchain as you discovered. Always prefix your cross-tools.
Actually, it doesn't. I use multiple toolchains, so I don't have any of them added to my environment path. I've gotten in the good habit of always typing:
Every time I open my bash shell. Which is a lot better than having to type "x86_64-pc-linux-gnu-gcc" or "mips64el-none-elf-gcc".
Code: Select all
Lastly what you see in the directory tree is the obscure `tools directory'. You can't override it from the configure line, but it's fairly simple to override the toolsdir variable in the makefile. This is really of no concern when cross-compiling, you don't want to actually use the programs in that directory directly, just use the regular ones in the bin directory that have the target triplet prefixed.
It is of concern when you're making a canadian cross-compiler or finalizing a toolchain for your operating system. I highly doubt the people who have already ported the gcc to their operating system where it is the primary toolchain would like to see it in their face all the time. The main reason I suggested these things (in particular, the 3rd one most of all) is because I myself had scoured the internet for hours on end and nowhere could I find a straight answer for these kind of things. In the end, I just had to experiment by building the gcc a few dozen times with different arguments and tinkering with the configuration files until I figured it out.
XenOS wrote:This linking error never happened to me, and I don't know of anyone else who encountered this problem. I dare to say that a linking error is a lot less probable than you assume.
The error only occurs when you're using --program-prefix="". It happens because the programs in your target toolchain and your host toolchain are both named exactly the same. Alternatively, you could probably get away with changing
to
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sat Aug 16, 2014 3:51 pm
by xenos
DaemonR wrote:The error only occurs when you're using --program-prefix="". It happens because the programs in your target toolchain and your host toolchain are both named exactly the same.[/code]
The obvious solution is not to use --program-prefix="" - it was not in the GCC cross compiler tutorial anyway, so it is not a problem of the tutorial at all. In fact it would be stupid to use it for a cross compiler, exactly because of the problems it would cause.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sat Aug 16, 2014 4:11 pm
by Combuster
64-bit-bfd is mentioned where 64-bit toolchains are created - see for example
UEFI
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sat Aug 16, 2014 5:06 pm
by jnc100
As far as I understand --enable-64bit-bfd is required to enable internal 64-bit support within binutils. In particular it makes the resolved vma addresses of symbols/relocations be 64 bit rather than 32 bit (although these may be converted back to 32-bit symbols/relocations depending on the output file format and relocation type). It is enabled by default, however, if the --target option specifies a 64-bit target, and sometimes is enabled if the host is 64-bit. The only times you should need to specify it explicitly is if the --target is a 32-bit target, but you also specify a 64-bit target with an additional --enable-targets= option.
Regards,
John.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sat Aug 16, 2014 5:24 pm
by Wajideu
jnc100 wrote:The only times you should need to specify it explicitly is if the --target is a 32-bit target, but you also specify a 64-bit target with an additional --enable-targets= option.
That could have something to do with it. Two of the toolchains I've built use i686-pc-elf and i686-w64-mingw32 as the primary target, and use x86_64-pc-elf and x86_64-w64-mingw32 as additional targets.
@XenOS, As I stated before, the information is necessary to those who are building native toolchains for their operating systems.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sat Aug 16, 2014 9:32 pm
by bluemoon
Why do you want to have those compilers having exactly same names and managed by search path? The rest of the world choose to identify them by different names.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sun Aug 17, 2014 2:52 am
by Wajideu
bluemoon wrote:Why do you want to have those compilers having exactly same names and managed by search path? The rest of the world choose to identify them by different names.
As I've already said, it's so that I can easily switch between my toolchains by typing:
Rather than having to add the following to all of my makefiles:
Code: Select all
export PREFIX=x86_64-pc-elf-
export CC=$PREFIXgcc
export CXX=$PREFIXg++
export AS=$PREFIXas
export LD=$PREFIXld
export AR=$PREFIXld
export RANLIB=$PREFIXranlib
export OBJDUMP=$PREFIXobjdump
export OBJCOPY=$PREFIXobjcpy
And again, what I just said in my previous post:
DaemonR wrote:...the information is necessary to those who are building native toolchains for their operating systems.
I don't understand why so many people here are acting like I'm insane saying there are reasons a person would want "gcc" to actually be called "gcc".
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sun Aug 17, 2014 2:57 am
by xenos
DaemonR wrote:@XenOS, As I stated before, the information is necessary to those who are building native toolchains for their operating systems.
No, see
OS Specific Toolchain. Also in this case there is no need to rename the tools
built to run on your build system, i.e., the cross compiler, using --program-prefix. Just use the correct target triplet prefix when invoking your tools. If you build tools to run
natively on your OS, this problem does not appear because they should not end up in an executable path on your build system anyway.
If you want to compile stuff for different targets, and choose the correct target triplet prefix automatically each time, use a configure script or autotools, which will generate the correct makefile for you.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sun Aug 17, 2014 3:05 am
by Wajideu
Oh, I see. I've haven't gotten that far, so I was misunderstanding how the gcc is ported other operating systems. Thanks for the clarification.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sun Aug 17, 2014 3:06 am
by Combuster
As I've already said, it's so that I can easily switch between my toolchains by typing
Bogus argument, really. My build needs to call multiple instances of gcc/ld during the entire process. one for the EFI code, one for the actual OS, and the host compiler for building all the tools the build process needs. If I can only use "gcc" this process become nigh impossible.
Claiming you need to set those in
each makefile implies you're unnecessarily duplicating code as well. In the end I don't believe there's practical effort differences between coercing the compiler to use a different scheme compared to setting it once in your project. Usability differences are that people will have problem building your project, and will most likely accuse you of not using a cross compiler for failing the sanity checks listed in the
Posting Checklist.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Sun Aug 17, 2014 3:10 am
by Wajideu
Combuster wrote:Usability differences are that people will have problem building your project, and will most likely accuse you of not using a cross compiler for failing the sanity checks listed in the
Posting Checklist.
Thanks
I wasn't aware there were guidelines for these kind of things.
Re: GCC Cross Compiler Tutorial Suggestions
Posted: Mon Sep 01, 2014 10:00 pm
by Wajideu
I'm not advocating for it to be added to the wiki, but here is how to change the default output file extension for the gcc.
Open up binutils-X.XX/ld/ldmain.c and search for
Code: Select all
If the --force-exe-suffix is enabled, and we're making
It should be around line 450. Just below this, you'll see:
Code: Select all
if (! link_info.relocatable && command_line.force_exe_suffix)
Remove the "&& command_line.force_exe_suffix" part. I also use a custom file extension for relocatable files, so I just change this entire statement to "if (1)". Then, shortly below this you'll see:
Code: Select all
if (len < 4
|| (strcasecmp (output_filename + len - 4, ".exe") != 0
&& strcasecmp (output_filename + len - 4, ".dll") != 0))
and
Change the extensions here to what you want. A tip, if you want shared object files to have a specific extension, there is a value called "link_info.shared" that you can check. eg. Mine is set up like:
Code: Select all
if (!link_info.shared)
{
if (!link_info.relocatable)
strcat (dst_name, ".eo");
else
strcat (dst_name, ".ro");
}
else
strcat (dst_name, ".so");
Next, open binutils-X.XX/ld/emultempl/elf32.em and search for
In this function, add the line:
Code: Select all
output_filename = "${EXECUTABLE_NAME:-a.exe}";
changing ".exe" to whatever your executable file extension is.
Lastly, before you configure gcc, do:
Code: Select all
export CFLAGS=-DTARGET_EXECUTABLE_SUFFIX='".exe"'
export CXXFLAGS=$CFLAGS
again replacing ".exe" with your executable suffix. GCC will only add this suffix if the output file doesn't have one, but LD will force it to have one. So if you output a file with an invalid extension, like "-o test.derp", you will actually get 2 output files, "test.derp" (from GCC) and "test.derp.exe". (from LD)
-----------------
Note: Be sure to adjust the len appropriately if you're using a file extension that is longer or shorter than 4 characters. eg.Code: Select all
if (len < 4
|| (strcasecmp (output_filename + len - 4, ".exe") != 0
&& strcasecmp (output_filename + len - 4, ".dll") != 0))
and
Code: Select all
char *dst_name = (char *) xmalloc (len + 5);
in mine are
Code: Select all
if (len < 3
|| (strcasecmp (output_filename + len - 3, ".eo") != 0
&& strcasecmp (output_filename + len - 3, ".ro") != 0
&& strcasecmp (output_filename + len - 3, ".so") != 0))
and
Code: Select all
char *dst_name = (char *) xmalloc (len + 4);