Wednesday, October 19, 2011

Nerd Food: C++11 with clang

So, C++11 is finally out! However, we still have to wait for the compilers to catch up. Some compilers are faster than others, however, and clang is certainly one of the fastest of the lot. I've recently set-up a simple trunk environment for clang and found it to be pretty stable - at least for learning purposes - so I decided to share my notes.

I started my wonderings with this post: Compiling llvm, clang and libc++ on Linux.However, I must say I found their approach to be a bit too... hacky... so I adjusted it somewhat. You won't fail to notice the similarities though. For the remainder of the article, I assume you have git, svn, cmake, and all other usual development packages installed; if not, apt-get them before proceeding. I also decided to compile clang using clang stable, for giggles mainly, so I got my hands on the latest clang (2.9) via the usual apt-get means. Without further ado, lets get on with it.

The first thing to do is to checkout the source code. I use git as an svn client, but feel free to use svn directly. Unfortunately, I couldn't get git svn to use modules, so I ended up having to do an svn checkout of clang. Oh well.

Checkout steps:
$ mkdir llvm
$ cd llvm
$ git svn clone -r HEAD http://llvm.org/svn/llvm-project/llvm/trunk llvm_src
$ cd llvm_src/tools
$ svn checkout http://llvm.org/svn/llvm-project/cfe/trunk clang
$ cd ../../
$ git svn clone -r HEAD http://llvm.org/svn/llvm-project/libcxx/trunk libcxx_src
We now have llvm, clang and the standard library. However, before we can do a build we must do the include headers hack:
$ cd llvm_src/tools/clang/lib/Frontend
$ emacs InitHeaderSearch.cpp
"Apply" the following patch, replacing marco with your username:
// FIXME: temporary hack: hard-coded paths.
- AddPath("/usr/local/include", System, true, false, false);
+ AddPath("/home/marco/local/include/c++/v1", System, true, false, false);
Exit emacs. The source is now ready to build. As we are civilised folk, we do out of source builds:
$ cd - # e.g. back at the llvm top level directory
$ mkdir llvm_build
$ cd llvm_build
$ CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/home/marco/local ../llvm_src -j4
A couple of notes:
  • If you want to do a default gcc build you can omit the CC and CXX variables. If you have multiple gcc versions, just set them accordingly (e.g. CC=gcc-4.5 CXX=g++-4.5, etc.).
  • Ideally you want the install directory to be a throw away directory that you can wipe out whenever, so don't put anything else on it.
  • Feel free to bump the -j4 to a sensible number depending on the cores you have available. If you are not using the machine, a -j6 or even -j8 on a quad-core tends to speed things up a lot.
You can now install clang:
$ make install
This will copy all the libs and binaries over to the install directory (~/local on our case). Now we can build and install the standard library:
$ cd ../libcxx_build
$ CC=clang CXX=clang++ cmake -DCMAKE_INSTALL_PREFIX=/home/marco/local ../libcxx_src -j4
$ make install
At this point you now have a complete, if somewhat bare, clang trunk environment to play with. So lets create a simple program to test it:
$ cd ..
$ mkdir simple_src
$ mkdir simple_build
$ cd simple_src
$ emacs simple.cpp
Type a simple hello world:
#include "iostream" // can't get the angle-brackets to work..
#include "fstream" // can't get the angle-brackets to work..
using namespace std;

int main(int, char**) {
std::cout << "Hello c++11 world!" << std::endl;
return 0;
}
On the same directory, create a trivial CMakeLists.txt file (I'm making it a bit more involved as I have a template...):
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(simple)

#
# compiler and linker flags
#

# enable as many warnings as possible
set(warning_flags "-Wall -Wextra")

# issue all the warnings demanded by strict iso c and iso c++
set(warning_flags "${warning_flags} -pedantic")

# treat warnings as errors
set(warning_flags "${warning_flags} -Werror")

# definition shadows another
set(warning_flags "${warning_flags} -Wshadow")

# do not issue warnings for system headers
set(warning_flags "${warning_flags} -Wno-system-headers")

# overloaded virtual function has a different signature
set(warning_flags "${warning_flags} -Woverloaded-virtual")

# make string constants const char*
set(warning_flags "${warning_flags} -Wwrite-strings")

# enable RTTI
set(other_flags "-frtti")

# set the flags
set(CMAKE_CC_COMPILER /home/marco/local/bin/clang)
set(CMAKE_CXX_COMPILER /home/marco/local/bin/clang++)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/home/marco/local/lib")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${optimisation_flags}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${warning_flags}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${profiling_flags}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${other_flags}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdinc++")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")

set(app "simple")

set(files "")
file(GLOB_RECURSE files RELATIVE
"${CMAKE_CURRENT_SOURCE_DIR}/"
"${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")

add_executable(${app} ${files})
We can now compile our test program! Exit emacs and type:
$ cd ..
$ cd simple_build
$ cmake ../simple_src
$ make
To run the binary we will need to ensure the C++ library is on the program loader's path:
$ LD_LIBRARY_PATH=/home/marco/local/lib ./simple
Hello c++11 world!
One interesting thing to notice is that we still have two C++ libraries:
$ LD_LIBRARY_PATH=/home/marco/local/lib ldd simple | grep c++
libc++.so.1 => /home/marco/local/lib/libc++.so.1 (0x00007fa5b5188000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa5b463f000)
Something for a further article though.

With this set-up you can now follow clang trunk development; just git svn rebase, and svn update all the checkout directories, rebuild and re-install. Every so often you may need to delete the whole of ~/local and start again, but other than that you should be good to go.

Tuesday, August 02, 2011

Nerd Food: No sound with flash

Life on the debian testing lane is never boring. After loosing X.org for a week - its fine now, thanks! - I found myself without sound on flash. The fix was simple: /etc/asound.conf was gone, for some reason. As root, I created it again with the following content:
pcm.pulse {
type pulse
}
ctl.pulse {
type pulse
}
pcm.!default {
type pulse
}
ctl.!default {
type pulse
}
Solution courtesy of the Ubuntu wiki.

Sunday, June 12, 2011

Nerd Food: High CPU usage with NVidia

I recently bought myself a new shiny i5 Sandy Bridge rig, and I was really looking forward to Debian Testing 64-bit and stable Intel video drivers. No more NVidia and ATI binary drivers, I shouted to the wind! However, being rather averse to reading manuals and being generally stingy, I got myself a cheap deal on a Assus P8P67 motherboard. Yep, you read right, I was blissfully unaware that the P67 chipset didn't allow access to the Intel integrated video card and what I really wanted was the H67 or the Z68. Oh well. I grinned, moaned, cursed and subsequently placed my old and trusty NVidia GeForce 7300 GS on the motherboard.

All was going well, until I started using the machine in anger. For some reason my X server started using 100% of one of the cores, rendering the whole machine unusable for _several seconds_. This was rather disappointing as I have 8 GB of RAM and a Vertex 2 SSD. This thing should fly at all times. And indeed it did fly using nouveau - except nouveau gave me really low resolution (and of course no composition).

After much, much digging I finally figured out the problem. You need to have option UseEvents set:

Option "UseEvents" "True"

Now the machine is 100% responsive 100% of the time, even under high load! However, for some reason I'm still unable to run compiz even though composition works just fine under metacity. Oh well.

Update

Sadly, my good-feeling didn't last long. Although the machine was hyper-responsive when I was using, my screen went totally black when I left the computer running overnight. Black Screen of Death you could call it. I guess this is what they meant by instability associated with UseEvents. Oh well. On the plus side, I've tried a few other options nicked from the Compiz NVidia page and things actually seem ok for the moment - knock on wood. The options are:

Section "Device"
Identifier "Device0"
Driver "nvidia"
VendorName "NVIDIA Corporation"
Option "RenderAccel" "on"
Option "UseEvents" "false"
Option "RenderAccel" "True"
Option "DamageEvents" "True"
Option "TripleBuffer" "True"
Option "BackingStore" "True"
EndSection

Notice UseEvents is set to false.

Tuesday, February 22, 2011

How to access Radio Nacional de Angola from Linux

Admittedly, this may be useful to a rather limited user pool - but nevertheless. If you desperately need to access RNA (Angolan National Radio or Radio Nacional de Angola) from Linux, don't bother going to their website. You'll just get weird plug-in errors, due to the way they detect windows media support. The best way is to access the stream directly in RhythmBox. To do so, click on Library | Radio | New Internet Radio Station and add:

For Radio Luanda. Happy Listening!

Sunday, February 20, 2011

NP: Fitter Happier

Fitter, happier, more productive,
comfortable,
not drinking too much,
regular exercise at the gym
(3 days a week),
getting on better with your associate employee contemporaries,
at ease,
eating well
(no more microwave dinners and saturated fats),
a patient better driver,
a safer car
(baby smiling in back seat),
sleeping well
(no bad dreams),
no paranoia,
careful to all animals
(never washing spiders down the plughole),
keep in contact with old friends
(enjoy a drink now and then),
will frequently check credit at (moral) bank (hole in the wall),
favors for favors,
fond but not in love,
charity standing orders,
on Sundays ring road supermarket
(no killing moths or putting boiling water on the ants),
car wash
(also on Sundays),
no longer afraid of the dark or midday shadows
nothing so ridiculously teenage and desperate,
nothing so childish - at a better pace,
slower and more calculated,
no chance of escape,
now self-employed,
concerned (but powerless),
an empowered and informed member of society
(pragmatism not idealism),
will not cry in public,
less chance of illness,
tires that grip in the wet
(shot of baby strapped in back seat),
a good memory,
still cries at a good film,
still kisses with saliva,
no longer empty and frantic like a cat tied to a stick,
that's driven into frozen winter shit
(the ability to laugh at weakness),
calm,
fitter,
healthier and more productive
a pig in a cage on antibiotics.