Post

Building gcc 4.1.2 on Solaris 10

Building gcc 4.1.2 on Solaris 10

Compiling gcc 4.1.2 on Solaris to over come compilation and linking issues faced during porting my C++ application from RHEL.

Background

I was working on porting an C++ Application from RHEL to Solaris 10. I was getting too many compile time errors when recompiling the application on Solaris. Initially I tried fixing those errors without thinking that language also has progressed and we might need a new compiler. After a few days finally I started comparing the build environment and closed on compiler version being different.

Upgrading Compiler

Initially like anybody else, we took the latest version of gcc available on Solaris 10 and tried compiling my code. It never worked out. I realized that language standard have progressed much further and gcc use to throw new errors which would have taken long time for me to fix.

1
pkg install gcc-45

Compiling the Compiler

After my failed attempt to compile my code using latest gcc compiler, I started searching for pre-built packages for gcc 4.1.2 on Solaris 10 without any luck.

Finally we made a decision to compile the compiler ourself. I immediately downloaded gcc 4.1.2 from gcc’s website. I saw that there is a configure script and Makefile. Looking at the documentation I ran configure script with bare minimum options followed by gmake. The compiler worked and I was able to compile my code. The testing cycle could start now.

1
2
3
4
5
6
7
pkg install gcc-3

cd gcc_source_dir
mkdir objdir && cd objdir
../configure --enable-languages=c,c++
gmake
gmake install

Next day, while reviewing my colleague’s code I found that there is a security issue with the compiler which we compiled. All the private methods were accessible in our library and anybody could call those methods.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
nm /path/to/library.a

...
00000000000021b0 T CLIF_arg_double
00000000000021e0 T CLIF_arg_func
0000000000002190 T CLIF_arg_int
0000000000002140 T CLIF_arg_string
00000000000021a0 T CLIF_arg_uint
00000000000021c0 T CLIF_call_func
0000000000001600 T CLIF_current_help
0000000000001670 T CLIF_parse
0000000000000fb0 T CLIF_print_arguments
0000000000000e00 T CLIF_print_options
0000000000001100 T CLIF_print_usage
0000000000002180 T CLIF_set_double
00000000000020e0 T CLIF_set_flag
0000000000002160 T CLIF_set_int
0000000000002120 T CLIF_set_string
0000000000002170 T CLIF_set_uint
0000000000002100 T CLIF_unset_flag
00000000000020a0 T CLIF_version_handler
...

Upon debugging the library, I found that all the public/private functions which we wrote had a T denoting that the functions are public. We again started compiling gcc with different arguments. After many attempts there was a time when all of the functions even the public ones became private.

Now many iterations later we were able to compile gcc for our use case using following steps:

  1. Install gcc 3.4.3
1
pkg install gcc-3
  1. By default Solaris 10 comes with gcc 3.4.3 and binutils 2.15. We need to compile binutils 2.18 in order gcc compiled correctly.
  2. Prepare the shell for compiling gcc:
1
2
3
4
5
6
# Use ksh shell
export CONFIG_SHELL=/usr/bin/ksh
# Copy/Create links to all gnu tools into one directory and remember to remove letter 'g' from the prefix of the name of executable.
export PATH=/Mytools/binutils_2_18/bin:/gnutools:/sbin:/bin:/usr/bin:/usr/ccs/bin:/usr/sfw/bin
export CC="/usr/sfw/bin/gcc -fPIC"
export CXX="/usr/sfw/bin/g++ -fPIC"

/Mytools/binutils_2_18 is the location where binutils 2.18 is installed. /gnutools is the location where gnu tools like gmake, gawk, gsed and gmake etc are symlinked without the g prefix.

  1. Build:
1
2
3
4
5
cd gcc_source_dir
mkdir objdir && cd objdir
../configure --with-gnu-as --with-as=/binutils_2_18/bin/as --with-gnu-ld --with-ld=/binutils_2_18/bin/ld --prefix=$PREFIX --enable-threads=posix --enable-checking=release --with-system-zlib --enable-shared --disable-symvers --enable-languages=c,c++
gmake #referring to gnu make
gmake install

$PREFIX is the location where you want to install gcc. It should be writable by your user.

Learnings

I learned that compiling a compiler without a compiler is kind of fun. Following are the things I learned:

  • gcc built a basic compiler before actually compiling the code.
  • gcc configure script has so many flags which can cause security issues in the output binary like the one time when I acciedently made all the functions public.
This post is licensed under CC BY 4.0 by the author.