Feeds:
Posts
Comments

Archive for the ‘cmake’ Category

i’ve just finished a wiki page on how to develop arbitrary software on nixos [1] (thanks to viric!). as this is fundamentally different to all other linux and non linux operating systems i think this is worth a posting about this subject in my blog.

the interesting aspect is that nix/nixos provides such a development environment per project so one is not forced to pollute the system environment with the ongoing changes which always lead to horrible side effects as regression (you know when old habits stop working as a tiny update of libX breaks tool Z).

the way it is used is covered by [1] already.

a slightly more complex example

config.nix

     1  {
     2    packageOverrides = pkgs : with pkgs; rec {
     3      # example environment from viric
     4      sdlEnv = pkgs.myEnvFun {
     5        name = "sdl";
     6        buildInputs = [ stdenv doxygen SDL SDL_image SDL_ttf SDL_gfx cmake SDL_net pkgconfig ];
     7      };
     8
     9      # a custom library NOT included in nixpkgs (maybe later it is but assume for this example it is not)
    10      libnoise = callPackage ./libnoise.nix {};
    11
    12      # this is the needed environment for development of my spring random map generator
    13      # type 'load-srmg-env' to load it after installing it using 'nix-env -i env-srmg'
    14      srmgEnv = pkgs.myEnvFun {
    15        name = "srmg";
    16        buildInputs = [ stdenv doxygen cmake libnoise qt4 ];
    17      };
    18    };
    19  }

in the ~/.nixpkgs/config.nix expression i added a custom library which is then available with nix-env, this way it can be installed using (nix-env -i libnoise).

the interesting point is that line 2 contains the rec keyword indicating that all 3 attributes in the attribute set (line 2 to 18) may recursively reference each other. this is required as the the srmgEnv on line 14 where the buildInputs lists libnoise.

the libnoise expression is outsourced (line 10) into the file libnoise.nix (listed below).

libnoise.nix

     1  {stdenv, doxygen, fetchgit, cmake}:
     2
     3  stdenv.mkDerivation rec {
     4    name = "libnoise-1.0.0";
     5
     6    # i also change bits in the library and therefore i like to have it local
     7    # in case i change anything this needs to be done to reflect the change
     8    # 1. make the change 
     9    # 2. use 'git add file_which_has_changed'
    10    # 3. use 'git commit'
    11    # 4. use 'git log' to find the most recent rev
    12    # 5. paste the copied rev in the rev field below
    13    # 6. reinstall the libnoise 
    14    src = fetchgit {
    15      url = /home/joachim/Desktop/projects/libnoise;
    16      rev = "8b5b89b7241a112dfe0b387f7589ea9a2df00b02";
    17      sha256 = "";
    18    };
    19
    20    buildInputs = [ cmake doxygen ];
    21
    22    meta = {
    23      description = "libnoise";
    24      homepage = "http://www.github.com/qknight/libnoise";
    25      license = "LGPL2";
    26      maintainers = with stdenv.lib.maintainers; [qknight];
    27    };
    28  }
    29

the libnoise.nix file is interesting as it references a local git repository. it also lists what to do in order to alter the package.

once the srmg-env is installed (nix-env -i env-srmg) it can be used using: load-srmg-env. as mentioned in [1] this environment will then behave as if one had used ubuntu linux and then installed all the required libraryies.

future

as i noted in [1] nix will soon get a toggle (nix-build –run-env ‘<nixpkgs>’ -A xterm, see [2]) which will clone the environment of virtually any sourceScription on the system. this means one can hack on any software easily by injecting code into the build chain on an arbitrary position – still, this changes won’t be persistent, meaning:

  • after reinstallation of the sourceScription the former version will be installed
  • the environment will not last a reboot of the system (not 100% sure about this)

still it is one step towards the concept of the midstream platform (mentioned in my diploma thesis) and is a great way to test a quick hack.

update: 23.5.2012

another interesting potential property is that tools like kdevelop could be patched to automatically see all the include paths of a complete project and therefore are able to provide automatic code completion without having too much manual effort.

 

kdevelop can do that already! when importing the project’s ‘CMakeLists.txt’, kdevelop reads the ‘found’ entries and therefore collects all the library paths!

links

[1] https://nixos.org/wiki/Howto_develop_software_on_nixos

[2] https://github.com/NixOS/nix/commit/7f38087f35e6f74a73bfdb28da8acd8930565d51

Read Full Post »

motivation

searching for a ‘cross platform‘, ‘cross distribution‘ package manager, one question that arises in regards to nix is:

can nix be used for ‘source deployment’ and ‘binary deployment‘ on windows?

in the last post i discussed how to install nix 0.16 [1] on windows but back then i could not find any working gui tool. i was not able to compile such a tool either with the tools found in nixpkgs [2]. the problem is that the used toolchain is optimized for posix environments (linux and others) with dependencies to X11.

how to use nix to build software for windows then? the solution to this problem is easy: we have to extend the current toolchain (used in nixpkgs) by a new one.

first, let’s see what others do: other distributions already support ‘cross compilers’ to compile program in linux (but for windows). the drawback of such a solution is that it binds the developer to a certain distribution. so what concepts do exist, in order to build software, for windows:

  • windows+cygwin (running nix inside cygwin) using the posix toolchain (nixpkgs)
    this is already working and supported
  • windows+cygwin (running nix inside cygwin) using a different toolchain: MinGW
    this is what this blog posting is about
  • using nix on any posix conform distrubtion with a cross compiler setup using the MinGW toolchain
    there are some references to MinGW found in the nixpkgs already, according to developers on irc.freenode.org#nixos [10] this is used for cross compiler setups. still i could not find any mingw expression to experiment with such a cross compiler setup in nix.

so why would i want to have windows+cygwin+nix with a native windows mingw toolchain?

  • nix can be used as a package manager for windows
  • nix does support ‘source deployment’ and ‘binary deployment’
    so it is a important target for developers on all platforms/distributions
  • nix is not bound to any distribution in particular
    which also makes it an excellent tool for ‘cross distribution’ packaging (when using nix in a prefix installation in contrast to using NIX OS)
  • nix can be used to create abstract targets of all kind
    examples: creating NSIS installers, automated software builds/tests
  • nix can be used to build  ‘cross compiler chains’
    this would actually be interesting for me as well (but not covered here)

creating a new mingw based nix toolchain

this is not that easy, but we somehow have to replace/extend the linux based toolchain with a MinGW toolchain optimized for windows.

first: what should be supported?

on windows, that is:

  • direct hardware access (using windows api and device drivers) / directX
  • using Qt natively (without X11)
  • things like ‘start menu’ shortcuts

we will use qt 4.7 as an example how to do that.

how to build software for windows natively?

first let’s build software for windows, how it would be done using windows:

  • download the Automated MinGW installer (should contain gcc 4.x) at [3]
  • download the qt 4.7.1 library (i used the zip distribution for this experiment) [4]

to build the libraries (&later the software)

making mingw work (native installation)

  1. as already mentioned, download the ‘Automated MinGW installer’
  2. install MinGW

NOTE: do not add anything to the global PATH, as we are going to setup multiple toolchains, this would be a source of horrible side-effects.

so instead of a global PATH, we could alter the PATH used in cmd.exe on the fly (every time we start a new cmd.exe) with:

PATH = %PATH%;c:\mingw\bin;

NOTE: windows does not have something like RPATH [5] (rpath is not cmake specific but that linked page should give you an basic idea what rpath is about), that means a windows program is lost if the library (something like mingw.dll) is not found in the same directory as the binary is in. as a quick fix to the problem one could expand the PATH variable to include also the place, where the respective library is in.

as we’ll with the new nix-toolchain, this simple fact is very problematic.

[7] provides an interesting (maybe outdated) table about how such things are handled in other distributions.

making qt work (using mingw, still native installation)

so as the compiler setup is done, we need to add the qt library. download a file called qt-everywhere-opensource-src-4.7.1.zip at [5].

  1. using the cmd.exe from above (with the PATH adaption)
  2. unzip qt-everywhere-opensource-src-4.7.1.zip
  3. cd qt-everywhere-opensource-src-4.7.1
  4. configure.exe
  5. make install (will install into the same directory, but we don’t care right now)

afterwards we can execute qt programs from the cmd.exe shell. to make the examples executable from everywhere either:

  • (DON’T DO THAT!): add the MinGW path and the Qt-library path to the global PATH variable
  • (DON’T DO THAT!): copy the needed dll files into EACH qt example directory to make the examples work from everywhere (either from  cmd.exe shell or when starting from explorer.exe)
  • add another PATH, namely: c:\qt-everywhere-opensource-src-4.7.1\bin in the cmd.exe shell

as a final step we test if the qt examples work (this is kind of a module test), run any qt example from cmd.exe with the extended PATH settings applied. as we now know how to get this toolchain working in a native environment, we can try to automate this process using nix expressions.

adapting this buildchain into nix expressions

to get a working toolchain inside nix i packaged the installation of MinGW from c:\MinGW and created something like mingw.tar.bz2 for redistribution. see the nix expressions in [6] and consult the README in order to get the nix expression to work in your cygwin environment (this time not cmd.exe anymore, instead use the cygwin shell).

  • winmingw.nix downloads my re-release of mingw and installs it
  • it also makes the tools like mingw32-make available for use inside your cygwin shell

NOTE: make sure your cygwin (not cmd.exe) has ~/.nix-profile/bin in your PATH environment variable (example: export PATH=~/.nix-profile/bin:$PATH).

how to install cygwin/nix and my nix expressions on windows:

  1. install a full cygwin environment (several gb of files, use the setup.exe installer)
    or see my last post about this
  2. make nix 0.16 work
    again: see my last post about this
  3. use git clone with my local repo in [6]
    cd ~; mkdir .nixpkgs; cd .nixpkgs; git clone …
  4. install winmingw: nix-env.exe -i winmingw
  5. check that the mingw tools are there, type: mingw32-make.exe or mingw32-make

NOTE: after installing winmingw notice that there are a lot of new tools symlinked from ‘~/.nix-profile/bin’. interestingly this also includes symlinks to libraries (read dll files) files. so why symlink dll files?

installing qt using the new mingw toolchain

there is another anomaly using cygwin in comparison to all other posix systems. in windows all executables do have the .exe suffix while on linux they don’t. as the cygwin shell must be compatible to both worlds, the designer of cygwin made this decision:

  • programs can be executed by typing: ‘curl.exe’ but also by typing ‘curl’, both times it is the same program which gets executed
  • there is an exception to the rule above, if a script called ‘curl’ also exists (which is executable), it is executed instead of curl.exe
  • if the script ‘curl’ and the binary ‘curl.exe’ are in the same directory, then the ‘curl’ script has precedence, when typing ‘curl’ in a shell

at least [8] states it that way. i also experimented with these commands:

  1. touch AA; touch AA.exe (both files get created)
  2. touch AA.exe; touch AA (only AA.exe is created and later the timestamp is updated)

i guess (1) is true on all posix systems (at least for those i’ve been working with so far). but (2) is cygwin specific and implies some issues on would not think of.

to track down an issue which is caused by the fromer rule it cost me at least 1-2 hours. the problem was that my winqt.nix expression was fine but always exited with ‘error 1’ after the unzip operation (without any error message, except the exit 1 code). i always thought that i did something wrong with the nix language. but then i decided to run the command (which would normally be executed by nix) in a shell and found out that the cygwin shell bahaves differently than the cmd.exe shell for the exact same command.

to my surprise i got prompted by unzip (in the cygwin shell) with the question if i want to [o]verwrite or [r]ename ‘configure.exe’ (cause by a file configure). i wondered quite some time what problem could cause this?! so i extracted it again, but this time in cmd.exe with no prompt.

important conclusions

Edit: further discussion should be redirected to the nix wiki [11].

problem 1: symlinks and dll files

  • all programs in nix are installed into a unique prefix but are available as a symlink from ~/.nix-profile/bin
  • symlinking the same program twice does therefore not work but happens rarely anyway
  • however: symlinking two different dll files sharing the same name is  not possible, this is the biggest issue right now

a solution would be static linking. therefore:

  • two programs having the same binary name (‘firefox’ for example)
  • two programs sharing the same library name (‘mingw32.dll’ for example)

the former point is easy to accomplish but the later is not. ‘viric’ (a developer from irc.freenode.org#nixos) pointed out that in order to fix this issue we could use ‘side-by-side sharing’ [9].

NOTE: it would be very interesting to see, if such a thing would actually work.

problem 2: directory and file handling

the other important problem is how file handling is implemented in cygwin. the current behaviour seems to be convenient for users but is a no-go for packaging as it might cause a lot of unforeseen consequences (and we all have played halfile and know where this could be going).

links

[1] http://nixos.org/nix/

[2] http://nixos.org/nixpkgs/

[3] http://mingw.org

[4] http://qt.nokia.com/products/

[5] http://www.cmake.org/Wiki/CMake_RPATH_handling

[6] https://github.com/qknight/mingw-nix-on-windows

[7] http://www.fortran-2000.com/ArnaudRecipes/sharedlib.html

[8] http://hem.bredband.net/richardc/Cygwin.html

[9] http://msdn.microsoft.com/en-us/library/ms995843.aspx

[10] http://webchat.freenode.net/?channels=nixos

[11] http://wiki.nixos.org/wiki/Nix_on_Windows

Read Full Post »

motivation

as i’ve been experimenting with nix [1] (cross platform, cross distribution package manager) i hit a lot of issues in the automake based buildsystem. this post is about what motivated me to replace automake with cmake. it also coveres issues i had to solve. the nix-0.16-cmake project can be found at [2].

found autotools issues

i’ve found quite many issues in the autotools build script of nix. i don’t know if they are specific to nix or to autotools. however: i don’t like autotools because:

  • they are very complex to maintain
  • complicated in usage, what parameters do what?
    you are literally ‘flooded‘ by typing: ./configure –help
  • there are a million differnt versions of automake
    probably all are installed on my gentoo system! why?
  • all your directories get filled with these strange files:
    config.status, configure.ac, Makefile.am, Makefile.in, …
  • does autotools support “out of source” builds? never seen it yet.

in contrast cmake:

  • cmake has a very easy to lern syntax
  • i like the colored build system

some may say i might a bit biased towards cmake, so let’s consider nix-specific issues only:

  • prefix installation does not work (as normal user) if not passing –localstatedir=path/state
    this is not listed in any docu, nor ./configure –help
    update: (
    it is actually listed in the documentation, see section:  Quick Start, point 1)
  • the build system does not warn, when not using –with-store-dir=/nix/store, that all software has to be recompiled
    it is listed in the documentation tough but this screwed some of my first builds
  • when using –with-store-dir=/nix/ it will chmod /nix/ to mode 1777 instead of adding /nix/store
  • running ./configure is slow
  • if you forget to run ./bootstrap.sh you still can build & install nix but it does not work properly
  • –with-store-dir= and –localstatedir= will always overwrite –prefix by default
    this implies they need to be always used in a ‘pure prefix’ installation

i might very likely hit some other issues but i don’t remember them. if this list is not enough for you, just read why the kde developers use cmake instead of autools/scons today.

NOTE: this is not a criticism about upstream (the nix developers). i do like their work very much. in case they do not want to use cmake, i’m fine with that. they can use my changelog to fix issues associated with the automake issues i pointed out.

how to replace autotools by cmake

one of the first things was to install nix 0.16 with autotools:

  • cd nix
  • rm -Rf nix-0.16
  • tar xf nix-0.16.tar
  • cd nix-0.16/
  • ./bootstrap.sh
  • ./configure –prefix=$mPREFIX –localstatedir=$mPREFIX/state –with-store-dir=/nix/store
  • make
  • make install

i copied the shell output to a text file to have an idea what to do when. next i started from scratch with a top-level ‘CMakeLists.txt’.

  • as cmake is hierarchical, start small with an ever increasing directory coverage
  • make only small changes
  • start with a build environment, later create the installer and finally do QA
  • install into the same prefix, say /tmp/nix-prefix, move the fils apart and check both directories for differences

#!/bin/bash

DIRA=/tmp/nix-unified
DIRB=/tmp/nix-autotools

find $DIRA | sed “s%${DIRA}%%g” | sort > /tmp/fileA
find $DIRB | sed “s%${DIRB}%%g” | sort > /tmp/fileB

echo “files in both dirs are filtered by -3”
echo “——————————————–”
echo “$DIRA”
echo ”  $DIRB”
echo “——————————————–”
comm <(cat /tmp/fileA) <(cat /tmp/fileB) -3

i’ve also created scripts to automate various installation scenarios for automated testing.

interesting findings

  • automake/cmake supports RPATH build of binaries, see [3]
    that helps to make binaries find their associated libraries (libfoo.so) without having to alter the LD_LIBRARY_PATH. this way you can execute the program either while it is in your ‘out of source’ build directory (interesting for developers) or after you typed ‘make install’.
  • use DEFINES instead of CONFIGURE_FILE where possible
    especially to pass the version number variable from the CMakeLists.txt to your c/c++ code
  • DESTDIR builds, see [4]. this is a very nice feature for ‘downstream’ (distributions) to integrate software into their system

cmake pitfalls

  • always check your variable names, i had a bug which cost me a few hours where a cmake variable was wrong: CMAKE_TR_PATH was CMAKE_TR_PATh
    this resulted in a silent fail.
    in c/c++ one would get a error of using an undefined variable, why not here?
  • when trying to add ‘broken’ symlinks (which won’t work as you passed the wrong directories) cmake tends to pass silently
  • when adding PERMISSIONS to a file, cmake might break when the file is not readable (anymore). i don’t know the cause for this, maybe a cmake issue.
    so instead of
    PERMISSIONS OWNER_EXECUTE GROUP_EXECUTE  WORLD_EXECUTE
    better do:
    PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE

the result of using the wrong PERMISSONS was:

CMake Error at scripts/cmake_install.cmake:40 (FILE):
file INSTALL cannot set permissions on
“/tmp/nix-cmake/bin/nix-collect-garbage”
Call Stack (most recent call first):
cmake_install.cmake:175 (INCLUDE)

  • CMAKE_INSTALL_RPATH must match your library-directory (where your libraries are)!
    i forgot to add the subdirectory once  and the effect was that the binaries were not executable, moking about not finding libmain.
  • check that all scripts/program which should be executable are actually ‘installed’ as executable
    ls -la –color=auto helps a lot here
  • check file modes in general, use this:
    find . -name *.pl -exec ls -la –color=auto {} +

current status

i’ve invested quite some time now and still the project isn’t finished. it’s usually very small issues as discussed in the pitfalls section already. since this is my first major cmake integration i expected this. see [5] for further details.

links

[1] http://nixos.org/nix/

[2] https://github.com/qknight/nix-0.16-cmake/

[3] http://www.cmake.org/Wiki/CMake_RPATH_handling

[4] http://www.dwheeler.com/essays/automating-destdir.html

[5] https://github.com/qknight/nix-0.16-cmake/blob/master/README.cmake

Read Full Post »

i’ve finished a set of basic ogre examples – since the ones coming with ogre 1.7+ are not very good. you can download them from github.com/qknight, see [1]. i’ve added a README which explains all in detail, again see [1]. i wish i had the time to create more of these examples. so here are a few screenshots.

mars example (about texturing)

ninja-camera (about using the mouse navigation)

mars-rings (about creating circles in ogre)

mars-rings-shader-cg (about using shaders)

so basically my examples are about:

  • how to create fully self-contained simple examples independent of each other
  • how to get ogre running (with the example framework from the ogre wiki tutorials)
  • using ois or sdl joystick/gamepad support in ogre
  • how to create spheres and how to texture them properly
  • how to approximate rings which are approximated circles using line segments
  • how to use cg (nvidia) and glsl (opengl) shaders
  • how to use cmake
  • how to write small but yet powerful example
  • i’ve also put attention at a very light weight CustomMedia system, it will be easy for you to understand how to use materials and textures together with shaders

all of these use cmake and you can use them for whatever purpose you like. just note that i’ve included code from the ogre wiki and i don’t know which copyright or license they use which is ‘yet’ another criticism (but i will stop right here). i would like to thank the irc folks in #ogre3d@irc.freenode.net for their support.

it would be nice if you would drop me a email with feedback on how you liked/used my examples.

links

[1] http://github.com/qknight/ogre-examples

Read Full Post »

libnoise-viewer

i’ve just fixed most bugs in libnoise-viewer [1] and the software is really usable now. it features a QGraphicsScene and a QGraphicsView and to make it faster i’ve used some it::blackmagic called threads. Actually i used QThread and this was my first real use of multi-threading and it works pretty well. When i scroll the planar area small tiles are generated, two at a time are dispatched so that a dual core system is ‘saturated’ cpu load wise.

This viewer uses the ‘noise::module::RidgedMulti‘ module to generate the surface in a black/white fashion. All i did was to apply a color-band according to the relative height. As you might have seen already, there is a black/white vs color toggle. Using this you can visualize the heightmap.

if (job.colorstate) {
renderer.ClearGradient ();

renderer.AddGradientPoint ( 1.000000, utils::Color (0, 90, 0, 255));
renderer.AddGradientPoint ( 0.740000, utils::Color (0, 129, 0, 255));
renderer.AddGradientPoint ( 0.700000, utils::Color (0, 190, 0, 255));
renderer.AddGradientPoint ( 0.650000, utils::Color (0, 250, 0, 255));
renderer.AddGradientPoint ( 0.600000, utils::Color (120, 250, 250, 255));
renderer.AddGradientPoint ( 0.390000, utils::Color (20, 120, 200, 255));
renderer.AddGradientPoint ( 0.340000, utils::Color (20, 50, 250, 255));
renderer.AddGradientPoint ( 0.200000, utils::Color (0, 0, 120, 255));

renderer.EnableLight();
renderer.SetLightContrast (3.0); // Triple the contrast
renderer.SetLightBrightness (2.0); // Double the brightness
}

The rendering speed is very good. But see yourself (the upload of the ogv video to wordpress media didn’t work, so i host it somewhere else).

http://lastlog.de/misc/wordpress/libnoise-viewer.ogv

If you want to visualize other ‘libnoise graphs‘ you can edit the sourcode (see renderThread.cpp) , all you need is to add 3 or 5 lines of code:

module::RidgedMulti myModule;
myModule.SetOctaveCount (job.octave);
myModule.SetFrequency (job.frequency);

Again: if you ever have to use threads, use QThreads since signals/slots are threadsafe (coming with qt ~4.2 if i recall correctly) communication between the threads is very easily done using the signals/slot mechanism, which means using the event loop.

I need to say, this is the 3rd project i’ve migrated to cmake and to do that i needed about 30-50 minutes since i also cleaned up the sourcode and did some other things as renaming of files and re factoring of class names.

I’ve also updated to =dev-util/kdevelop-3.9.97 this release fixed all the crashes the previous release had and i absolute love this ide. Currently i can’t think of ever using something else! The cmake integration is very good and makes a lot of fun using it. Renaming of classes or member functions as well as object’s names works like a charm!

Unlike other KDE components kdevelop 3.9.97 works reliably stable for me!

links

[1] http://github.com/qknight/libnoise-viewer

[2] http://github.com/qknight/libnoise

Read Full Post »

cmake / kdevelop 4

source http://math.lbl.gov/~deschamp/jpg/CMakeBanner.jpgi’ve converted the second project to use ‘cmake‘. this time an qt4 application which usually uses qmake.

i love cmake. it is easy to use (once you get used to the cmake of doing things). i love ‘out of source’ builds. kdevelop4 can handle cmake so i decided to move into the future and use cmake for my kdevelop4 projects as well. so far a very good decision.

i did have problems at first. using cmake with normal cpp/h files is easy and well documented but using it with moc|uic|rcc is different. i searched for help in irc.freenode.net#cmake and ‘Marc Bowes’ gave me a link [2] to his github.com project which uses cmake for a qt4 project – an excellent resource. looking at that code made my work easy.

in case you want to convert your qt4 applications from qmake to cmake see [1] and [2]. in general i recommend reading [3], [4] and [5].

i probably said enought about cmake but one more thing a kde developer told to me:

when using cmake with uic (when using qt4) one has to maintain a list of QObject deriving classes which are then processed by a macro called: ‘QT4_WRAP_UI’. He said when using cmake with kde4 projects cmake does this automagically. This sounds great – maybe someone ports that code over to the qt4 macro – would be nice!

So finally some words about kdevelop4. I loved kdevelop3 but refactoring was a pain with kdevelop3 – that changed with kdevelop4. The language parser and ‘auto completion‘ feature now works so well you don’t think of kdevelop4 as a normal editor with syntax highlighting but more as a fully automated code generator.

Kdevelop4 can now have several projects in one widget (in kdevelop3 i needed two instances – resulting in issues since starting the second instance usually would resume the project which was used at last so one would end up having two IDEs with the same project opened). Kdevelop4 has also support for several worksets – this is one of the best features. Currently i consider it the greatest c++ IDE i’ve ever used and i didn’t even mention ‘compile sets‘ yet…

[1]  http://github.com/qknight/springrts.com-random-map-generator

[2]  http://github.com/marcbowes/mxitc

[3] http://www.linux-magazin.de/Heft-Abo/Ausgaben/2007/02/Mal-ausspannen

[4] http://www-flc.desy.de/ldcoptimization/documents/talks/CMake_Tutorial.pdf

Read Full Post »

i’ve just rewrote a library called libnoise to use cmake (instead of static Makefiles/libtool). i have to admit that cmake is probably the best buildsystem i’ve ever used. cmake does so many things better than others – but you probably know that already so i will focus on different things.

i had lot’s of problems using doxygen with an ‘out of source’ build. but i finally fixed that. i consider my hack an excellent example of how to use doxygen with cmake. the first thing i tried was hacking on [2], a posting from “Philippe Poilbarbe” (i don’t know this developer) which i couldn’t get running at first. exhausted i tried something else (for those who are interested, it was [3] a mail about a library called ‘libLASi’ using doxygen together with cmake (see [4] for libLASi). now happy to get doxygen working the ‘libLASi way’ at least  i decided to branch back to my first attempt which was [2].  finally i got that working, too. so [2] is the basis for this posting – keep that in mind.

i don’t like the way doxygen is integrated in cmake by the ‘libLASi’ developers. why?

because they write to the source directory (called ‘in source build‘) and this is not how cmake developers (that is those who wrote cmake)  consider stuff to be done right.

if you ever have to use doxygen with cmake you should look at my code [2]. it will compile on linux (probably unix in general) and all you need is a g++ compiler and doxygen installed.

in general to adapt the cmake/doxygen from any other build system keep this in mind:

  • the “Doxygen” file most often static will be rewritten (then called “Doxygen.in“) and some placeholders are inserted as:
    PROJECT_NUMBER         = @LIBNOISE_VERSION@
  • in general one could say “Doxygen.in” needs some adaption to receive cmake variables contents as i already wrote in the libnoise sourcecode (see quote below)
  • the cmake script called: CMakeLists.txt dealing with the docu (doxygen) will then replace this placeholders on the fly – that is when executing ‘cmake .
  • nearly all variables (i can’t think of any which would not work but i didn’t check them either) can be modified this way
  • one variable is replaced by a REGEXP (see quote below as well)

# you could also set the version with this, see Doxygen.in
# there you will find a line like this:
#      PROJECT_NUMBER         = @LIBNOISE_VERSION@
# @LIBNOISE_VERSION@ is then replaced by our global LIBNOISE_VERSION
#
# for instance you could uncomment the next 3 lines and change the version for testing
# SET(LIBNOISE_VERSION
#     “1.2.3-foo500”
# )

# doxygen can reference external images with IMAGE_PATH, this is how we set it dynamically
SET( CMAKE_DOXYGEN_IMAGE_PATH
“${CMAKE_CURRENT_SOURCE_DIR}/img”
)

# doxygen searches for source code (defined in FILE_PATTERNS, for example: *.cpp *.h)
# with DOXYGEN_SOURCE_DIR we fill a list of directories and later we write it into
# the Doxyfile with a REGEX REPLACE (see below)
SET( DOXYGEN_SOURCE_DIR
${CMAKE_SOURCE_DIR}
)

SET(DOXYGEN_OUTPUT_DIR html)
STRING(REGEX REPLACE “;” ” ” CMAKE_DOXYGEN_INPUT_LIST “${DOXYGEN_SOURCE_DIR}”)
CONFIGURE_FILE(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
SET(HTML_TARGET “html” )
ADD_CUSTOM_TARGET(${HTML_TARGET} ALL
/usr/bin/doxygen ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
INSTALL( DIRECTORY “${CMAKE_CURRENT_BINARY_DIR}/html/” DESTINATION “/usr/share/doc/libnoise-${LIBNOISE_VERSION}” )

  • it is very important to understand what ${CMAKE_CURRENT_SOURCE_DIR} and ${CMAKE_CURRENT_BINARY_DIR} are used for

i hope you won’t loose as much time as i did figuring this out.

finally: thanks very much for help from straszheim#cmake@irc.freenode.net (general cmake questions, nothing doxygen related) and thanks to the example at [5] but it wasn’t very helpful since i didn’t understand it – nice try, maybe next time! 😉

[1] http://github.com/qknight/libnoise

[2] http://www.cmake.org/pipermail/cmake/2006-August/010794.html

[3] http://marc.info/?l=cmake&m=119868994732284&w=2

[4] http://lasi.svn.sourceforge.net/viewvc/lasi/trunk/

[5] http://tobias.rautenkranz.ch/cmake/doxygen/

UPDATE(30Nov09): replaced static path with ${CMAKE_SOURCE_DIR} in the quoted script above

Read Full Post »