我喜欢使用armadillo线性代数库。将Octave .m文件移植到C 时,它变得非常好,尤其是当您必须使用特征方法时。
但是,当我不得不从本地香草G 中获取程序并将其倒入我的手臂处理器时,我遇到了问题。由于我花了几个小时来弄乱自己的方式,但我想分享,以免其他人避免感到沮丧。
如果其他人可以添加其他任何东西,我会喜欢的。这是我用来解决这个问题的过程,肯定不是唯一或最好的方法。
首先,我将代码源用作交叉编译器。我知道那里的其他人,但是我还没有为另一个编译器重建,无论如何都适用于任何编译器。
信息:
妻子图书馆需要拉帕克和blas,但是代码源没有fortran编译器。这导致我进入了Lapack和Blas的F2C版。
1。获取来源:
首先要抓住来源。
- armadillo
- 拉帕克&blas
2。交叉编译clapack
一旦我们获得了来源,接下来要做的就是将它们交叉编译为我们的最终硬件。就我而言,使用CodeSourcery是ARM7。它是一个真正的在这里阅读阅读的好主意,您确实可以通过花时间和阅读它们来完成所有这些。
-
要做的第一件事是更改make.inc文件以查看我们的交叉补偿器,而不是普通的GCC。通常您会$导出,但我发现通过修改makefiles来保持跟踪更容易。
编辑clapack-3.2.1-cmake/make.inc。来自:
CC = GCC LOADER = GCC
to:
CC = [CROSS-COMPILER-GCC location] LOADER = [CROSS-COMPILER-GCC location]
编辑clapack-3.2.1-cmake/f2clibs/libf2c/makefile来自:
ld -r -x -o $*.xxx $*.o
to:
[CROSS-COMPILER-LD location] -r -x -o $*.xxx $*.o
-
编译F2C库:
$make f2clib
当我制作F2C库时,我会在最后遇到错误:
./a.out > arith.h /bin/sh: ./a.out: cannot execute binary file make[1]: *** [arith.h] Error 126 make[1]: Leaving directory `/home/matt/clapack-3.2.1-CMAKE/F2CLIBS/libf2c' make: *** [f2clib] Error 2
这里没有实际问题。当然,它会遇到难以执行,它是跨编译的!
-
编译大麻:
$make blaslib
完成此操作后,您会注意到您有一个新的" Blas_xxxxx.a"。这是您的交叉编译Blas库。
-
编译拉帕克:
Make.inc将指向您使用
$make lapacklib
,但这将导致其尝试更多地执行交叉编译的项目。而是$cd
进入SRC目录和:$make
应该生成您的新" lapack_xxxxx.a"。现在我们有了F2C,Lapack和Blas,我建议将它们放置在有意义的地方,以便您以后找到它们。在我的情况下,我将它们放置在保留代码源编译器/代码库/ARM-NONE-LINUX-GNUEABI/USR/LIB的地方。切记重命名这些文件:
$cp libf2c.a [CROSS-COMPILE LIBRARY PATH]/libf2c.a $cp blas_XXXXX.a [CROSS-COMPILE LIBRARY PATH]/libblas.a $cp lapack_XXXXX.a [CROSS-COMPILE LIBRARY PATH]/liblapack.a
请记住,他们必须拥有以后才能认可的" lib"。再次继续将它们存储在您的交叉编译的图书馆位置。我使用工具链进行设置,以使与普通的GCC/G 分开变得更容易。
3。跨编译腋窝
首先阅读读书文件,始终是最佳起点的地方。
继续运行:
$cmake .
这将使一切都准备好,并生成Cmake创建我们共享的armadillo库所需的一切。我在这里继续前进的方式不是我认为您应该的方式,但是由于我对Makefiles一般不是巫师,因此我认为展示我所做的事情会有所帮助。 我修改了生成的cmakecache.txt行,并使用以下内容:
//CXX compiler.
CMAKE_CXX_COMPILER:FILEPATH=[CROSS-COMPILER-G++ location]
我知道该cmakecache.txt文件中的某个地方可以在其中指定Blas和Lapack位置的路径,但我很难弄清楚。而不是在这个问题上猛烈抨击我的头部,而是修改了" cmakefiles/armadillo.dir/link.txt",并手动添加了" -l [跨编译的blas/lapack目录]。评论? 接下来,因为我们要在以后编译程序(如Readme所说)修改" Include/Armadillo_bits/config.hpp"时,要手动链接Blas和Lapack库,并确保定义ARMA包装器使用的行进行评论:
// #define ARMA_USE_WRAPPER
唯一要做的就是 $cd
回到armadillo目录的根和
$make
完成完成后,您应该能够在程序中使用Armadillo。
4。在您的程序中使用Armadillo
在您的程序中使用Armadillo添加包括#include <armadillo>
和名称空间using namespace arma;
。现在,您应该能够使用自己喜欢的所有vec
和mat
。 通常,当使用ARMA时,您需要在编译时需要做的就是链接libarmadillo.so库,但是正如我之前说的那样,我们需要直接链接Blas和Lapack。因此,这是我的GCC C 编译器Synatx:
[CROSS-COMPILER-G++] -I [CROSS-COMPILED ARMADILLO DIRECTORY]/include ...
和我的链接器:
[CROSS-COMPILER-G++] -L [CROSS-COMPILED LIBRARY] -o ... -llapack -lf2c -lblas
还请注意,您链接库的顺序确实很重要!拉帕克必须先出现,然后是f2c,然后是blas。
实际上,您需要确保发生的一切是,当您编译并正确设置链接时,包含了交叉编译的Armadillo目录。
同样,更多信息更好,请随时添加更多评论。对您有用的是我所做的,我做错了什么,可以做些什么来改进。
谢谢。
我的特定设置是OSX(IDE Eclipse)交叉编译为Beaglebone Black。但是,这些说明应适用于类似的设置。
可选:
用于编译,我使用了Mac OS X ARM GNU Linux G Lite 2013.11-33工具链。具体而言,ARM GNU/Linux G Lite 2013.11-33高级二进制。
1。下载:
正如Matt发布的一样,GCC Cross编译器不支持Fortran,因此,如果您想编译Lapack和Blas,请在此处使用修改版本。我正在使用的是clapack-3.2.1-cmake.tgz
2。制作交叉编译CMAKE文件:
您可以使用工具链构建器或仅写一个。我写了一个。
示例:
# http://www.cmake.org/Wiki/CMake_Cross_Compiling#The_toolchain_file
# REQUIRED
SET(CMAKE_SYSTEM_NAME Linux)
SET(CMAKE_SYSTEM_VERSION 1)
SET(CMAKE_SYSTEM_PROCESSOR arm)
# Added for the beaglebone
SET(FLOAT_ABI_SUFFIX "")
# specify the cross compiler
SET(CMAKE_C_COMPILER /usr/local/arm-2013.11/bin/arm-none-linux-gnueabi-gcc)
SET(CMAKE_CXX_COMPILER /usr/local/arm-2013.11/bin/arm-none-linux-gnueabi-c++)
# where is the target environment
SET(CMAKE_FIND_ROOT_PATH /usr/local/arm-2013.11)
# search for programs in the build host directories
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
注意:这是我第一次制作cmake文件。它不能保证是正确的。
您需要替换/usr/local/arm-2013.11/bin/arm-none-linux-gnueabi-gcc,使用您选择的编译器的路径,以及/USR/LOCAL/ARMARM-2013.11/bin/Arm-None-linux-gnueabi-c 和/USR/local/arm-2013.11
我选择将此cmake文件保存为beaglebone.cmake
3。编译:
提取clapack-3.2.1-cmake.tgz和cd
编译:cmake -dcmake_toolchain_file =〜/dropbox/workspaces/beaglebone/beaglebone.cmake
〜/dropbox/workspaces/beaglebone/beaglebone.cmake是您的cmake文件的路径。
make
由于某种原因,我得到了:
ds-mac-pro:clapack-3.2.1-CMAKE bunny$ make
Scanning dependencies of target arithchk
[ 0%] Building C object F2CLIBS/libf2c/CMakeFiles/arithchk.dir/arithchk.c.o
Linking C executable arithchk
[ 0%] Built target arithchk
[ 0%] Generating arith.h
/bin/sh: arithchk: command not found
make[2]: *** [F2CLIBS/libf2c/arith.h] Error 127
make[1]: *** [F2CLIBS/libf2c/CMakeFiles/f2c.dir/all] Error 2
make: *** [all] Error 2
奇怪的是,运行再次编译良好:
ds-mac-pro:clapack-3.2.1-CMAKE bunny$ make
[ 0%] Built target arithchk
Scanning dependencies of target f2c
[ 0%] Building C object F2CLIBS/libf2c/CMakeFiles/f2c.dir/f77vers.c.o
[ 0%] Building C object F2CLIBS/libf2c/CMakeFiles/f2c.dir/i77vers.c.o
[ 0%] Building C object F2CLIBS/libf2c/CMakeFiles/f2c.dir/main.c.o
[ 0%] Building C object F2CLIBS/libf2c/CMakeFiles/f2c.dir/s_rnge.c.o
...
[100%] Building C object TESTING/EIG/CMakeFiles/xeigtstz.dir/xerbla.c.o
[100%] Building C object TESTING/EIG/CMakeFiles/xeigtstz.dir/xlaenv.c.o
[100%] Building C object TESTING/EIG/CMakeFiles/xeigtstz.dir/chkxer.c.o
[100%] Building C object TESTING/EIG/CMakeFiles/xeigtstz.dir/__/__/INSTALL/dsecnd.c.o
Linking C executable xeigtstz
[100%] Built target xeigtstz
4。复制(安装):
find . | grep .a$
返回
./BLAS/SRC/libblas.a
./F2CLIBS/libf2c/libf2c.a
./SRC/liblapack.a
./TESTING/MATGEN/libtmglib.a
cp libblas.a libf2c.a和liblapack.a到您喜欢的库文件夹。我制作/usr/local/armadillo-4.300.3/lib
必需:
1。副本包括:
不需要汇编Armadillo。我还没有运行任何基准测试来验证,但是通过在代码中使用#Define,使用Lapack和Blas可以通过未编译的Armadillo副本来工作。稍后代码示例。
提取臂法-4.300.3.300.300.gz
(可选)CP Armadillo-4.300.3/includs/usr/local/armadillo-4.300.3/include
当然,用您的选择路径替换/usr/local/armadillo-4.300.3/include
2。设置GCC使用Armadillo:
我正在使用Eclipse与C/C 交叉编译器支持插件(帮助菜单 ->安装新软件...),但是说明易于转换为CLI或其他IDE。
在"项目属性"窗口中:C/C 构建 ->设置
交叉G 编译器 -> inclage->包括路径(-i)
单击 以添加一个包含。我的路径是:/usr/local/armadillo-4.300.3/include
3。可选 - 设置GCC使用编译的库:
交叉G 链接器 ->库 ->
库(-l)
拉帕克
F2C
blas
库搜索路径(-l)
单击 添加路径。我的道路是:/usr/local/armadillo-4.300.3/lib
3。代码示例:
在CPP文件中尝试:
#include <armadillo>
using namespace arma;
mat A = randu<mat>(4,5);
mat B = randu<mat>(4,5);
std::cout << A*B.t() << std::endl;
成功!:D
某些功能Armadillo不直接支持,并且只能与编译的库一起使用。您可以通过运行一个简单的测试来测试库是否编译并正确工作:
#define ARMA_DONT_USE_WRAPPER
#define ARMA_USE_LAPACK
#define ARMA_USE_BLAS
#include <armadillo>
using namespace arma;
mat A = randu<mat>(5,5);
double x = det(A);
std::cout << x << std::endl;