I enjoy using the Armadillo Linear Algebra Library. It becomes extremely nice when porting octave .m files over to C++, especially when you have to use the eigen methods.
However I ran into issues when I had to take my program from my native vanilla G++ and dump it onto my ARM processor. Since I spent a few hours muddling my way though it I wanted to share so others might avoid some frustration.
If anyone else could add anything else I would love it. This was the process I used to tackle this and surely isn't the only or best approach.
First off I use Code Sourcery as my cross-compiler. I know there others out there, but I haven't gotten around to rebuilding for another compiler yet, regardless this should be applicable to any compiler.
Information:
The Armadillo library requires LAPACK and BLAS, but Code Sourcery has no Fortran compiler. This led me to a f2c'ed version of LAPACK and BLAS.
1. Get the sources:
First off go grab the sources.
2. Cross-Compile CLAPACK
Once we've got the sources the next thing to do is cross-compile them for our end hardware. In my case an ARM7 using CodeSourcery. Its a REALLY good idea to read the READMEs here, you really can do all of this by just taking the time and reading them.
First thing to do is change the make.inc file to look at our cross-compiler instead of the normal GCC. Normally you would $export, but I found it easier to keep track by modifying the makefiles.
Edit clapack-3.2.1-CMAKE/make.inc from:
to:
Edit clapack-3.2.1-CMAKE/F2CLIBS/libf2c/Makefile from:
to:
Compile the f2c libraries:
When I make the f2c libraries I get an error at the very end:
No actual problem here. Of course it will have trouble executing, it was cross-compiled!
Compile BLAS:
Once this is done you will notice you have a new "blas_XXXXX.a". This is your cross-compiled BLAS library.
Compile LAPACK:
The make.inc will point you to use
$make lapacklib
, but this will lead it to attempt more execution of cross-compiled items. Instead$cd
into the SRC directory and:That should generate your new "lapack_XXXXX.a". Now that we have our F2C, LAPACK and BLAS I recommend placing them somewhere that makes sense so you can find them later. In my case I placed them where I keep my Code Sourcery compiler /CodeSourcery/arm-none-linux-gnueabi/usr/lib. Remember to rename these files:
Remember they have to have the "lib" to be recognized later. Again go ahead and store these in your cross-compiled library location. I have it setup with my tool-chain to make it easier to separate from normal gcc/g++.
3. Cross-Compile ARMADILLO
First off read the README, always the best place to start.
Go ahead and run:
This will get everything ready and generate everything cmake will need for creating our shared armadillo library. The way I proceeded here is not how I think you are supposed to, but as I am no wizard with makefiles in general I thought it would be helpful to show what I did to get it to cross-compile. I modified the generated CMakeCache.txt lines with the following:
I know there is somewhere in that CMakeCache.txt file where you can specify the path to the location of our BLAS and LAPACK, but I struggled to figure it out. Instead of bashing my head against this issue I just modified the "CMakeFiles/armadillo.dir/link.txt" and manually added "-L [Cross-Compiled BLAS/LAPACK directory]. Someone more familiar with how to do this could specify in the comments? Next since we want to manually link the BLAS and LAPACK libraries when we compile our program later (like the README says) modify "include/armadillo_bits/config.hpp" and make sure the line defining the use of the arma wrapper is commented out:
The only thing left to do is
$cd
back to the root of the armadillo directory andOnce the make completes you should be able to use Armadillo in your programs.
4. Using ARMADILLO in your program
To use Armadillo in your program add the include
#include <armadillo>
and the namespaceusing namespace arma;
. Now you should be able to use all of thevec
andmat
you feel like. Normally when using arma all you need to do at compile time is to link libarmadillo.so library, but as I stated earlier we will need to link BLAS and LAPACK directly instead. So here is my GCC C++ Compiler synatx:and my linker:
Also note that the order in which you link libraries does matter! lapack must come first, then f2c, then blas.
Really all you need to make sure happens is that the cross-compiled armadillo directory is included when you compile and your linking is setup correctly as above.
Again more information is better, please feel free to add more comments. What worked for you different that what I did, what I did wrong, what could be done to improve.
Thanks.