Menu

  • Home
  • Archives
  • Tags
  • RSS
August 26, 2013

In which I recall how to build stuff

In which I recall how to build stuff

It all started when I wanted to "relearn" C++. I use it everyday, but it's been so long since I first came across it 15 years ago that I've accumulated tons of bad habits and thought patterns etc, so I wanted to get a "beginner's mind" feel of it again.

The initial detour

Ok, I thought, let's read the 4th edition of Bjarne's introduction to C++, and meanwhile also get to know Boost with some familiarity.

So I downloaded the Boost libraries (which took a while), and then tried to build this basic example (from the Boost FAQ)


#include <iostream>

#include <algorithm>

#include <iterator>



using boost::lambda::_1;



int main() {

  typedef std::istream_iterator<int> in;

  std::for_each(

      in(std::cin), in(), std::cout << (_1 * 3) << " ");

}

using Clang


clang -std=c++11 -stdlib=libc++ -I/opt/boost/boost_1_54_0 example.cc -o example

Fork in the road

No luck


/tmp/example-oWquCX.o: In function `__cxx_global_var_init3':

example.cc:(.text+0x71): undefined reference to `std::ios_base::Init::Init()'

example.cc:(.text+0x79): undefined reference to `std::ios_base::Init::~Init()'

/tmp/example-oWquCX.o: In function `main':

example.cc:(.text+0xb3): undefined reference to `std::cin'

example.cc:(.text+0xf0): undefined reference to `std::cout'

/tmp/example-oWquCX.o: In function `std::istream_iterator<int, char, std::char_traits<char>, long>::_M_read()':

(and more that I'll skip over right now).

Later I realized that this was probably my fault in not linking it correctly, but I immediately, inexplicably, decided "Aha! let's build clang from source!"

This might also have been because I had gotten bored of sudo apt-get install foo and longed for the (decade ago) days of emerge foo.

Deep in the woods

Luckily, this turned out to be well-documented, more or less.

So I got up to the point where I got and built clang:


$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm

$ cd llvm/tools

$ svn co http://llvm.org/svn/llvm-project/cfe/trunk clang

$ mkdir build && cd build

$ ../llvm/configure --prefix=/usr/clang_3_3 \

  --enable-optimized --enable-targets=host

$ make -j 8

And I procedded to then build libcxx


$ svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx

$ mkdir build_libcxx && cd build_libcxx

$ CC=clang CXX=clang++ cmake -G "Unix Makefiles" \

  -DLIBCXX_CXX_ABI=libsupc++ \

  -DLIBCXX_LIBSUPCXX_INCLUDE_PATHS="/usr/include/c++/4.6/;\

  /usr/include/c++/4.6/x86_64-linux-gnu/" \

  -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr $HOME/Clang/libcxx

$ make

Mt. Doom

At this point I got a compiler error. Very sad. Too bad, I thought, we need to go deeper. Time for building gcc/g++ and a new version of the C++ standard library. My Ubuntu version only had gcc upto 4.6, and I found a mailing list post which suggested this might be fixed in 4.7.

I could have at this point decided to add a PPA repository and got the new libraries and binaries that way, but luckily this was also well-documented (thank you, "Solarian Programmer", whoever you are!).

So I went ahead and downloaded gcc, and what turned out to be its prerequisites, gmp, mpfr and mpc.

These I built in the usual way (configure, make, make install), and then had to refer to them while setting up gcc:


$ export LD_LIBRARY_PATH=/usr/gcc_4_7/lib:$LD_LIBRARY_PATH

$ export LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/

$ export C_INCLUDE_PATH=/usr/include/x86_64-linux-gnu

$ export CPLUS_INCLUDE_PATH=/usr/include/x86_64-linux-gnu

$ ../gcc-4.7.2/configure --build=x86_64-linux-gnu --prefix=/usr/gcc_4_7 \

  --with-gmp=/usr/gcc_4_7 --with-mpfr=/usr/gcc_4_7 \

  --with-mpc=/usr/gcc_4_7 --enable-checking=release \

  --enable-languages=c,c++,fortran --disable-multilib \

  --program-suffix=-4.7

Now I could proceed where I left off earlier, with the libcxx build, after setting a couple of path variables:


$ export PATH=/usr/gcc_4_7/bin:$PATH

$ export LD_LIBRARY_PATH=/usr/gcc_4_7/lib:/usr/gcc_4_7/lib64:$LD_LIBRARY_PATH

A ray of hope

But first, I wanted to see if the new g++ could do what I had initially tried to do with clang:


$ g++4.7 -std=c++11 -I/opt/boost/boost_1_54_0 example.cc -o example

$ echo 1 2 3 | ./example

3 6 9

Whew, now I was getting somewhere.

I went back and re-ran cmake, and then libcxx built successfully.

And then of course, I retried my original example:


$ /usr/clang_3_3/bin/clang++ -std=c++11 -I/opt/boost/boost_1_54_0 example.cc -o example

and that worked too ... Woohoo!!

Finally, since I always measure running time:


$ time /usr/clang_3_3/bin/clang++ -std=c++11 -I/opt/boost/boost_1_54_0 example.cc -o example



real    0m0.848s

user    0m0.780s

sys     0m0.056s



$ time g++4.7 -std=c++11 -I/opt/boost/boost_1_54_0 example.cc -o example



real    0m0.714s

user    0m0.648s

sys     0m0.044s

Now to do something more than this example program ...


Tags: old-post

« Learning how to build (part 2) Switching to KDE »

Copyright © 2020 Agam Brahma

Powered by Cryogen