我正在使用Armadillo简化我的C++开发。要在Linux和Windows(两者均为64位)上正常运行,则可以正常工作。我正在使用Qt Creator + qmake来构建项目,以跨平台保留单个工具集。

我直接将Armadillo包括在我的项目中。由于它是模板库,因此不需要编译。包括标题就足够了。

现在,我想使用AMD's Core Math Library (ACML)加快处理速度,因为它可以在Linux和Windows上免费使用。因此,我将Armadillo的config.hpp设置为通过ACML通过以下方式使用LAPACK + BLAS:

#define ARMA_USE_LAPACK
#define ARMA_USE_BLAS
#define ARMA_BLAS_CAPITALS

在Linux上,编译+链接正确运行。我的qmake项目文件包含以下内容:
unix: {
    INCLUDEPATH += /usr/include/acml/gfortran/
    LIBS += -L/usr/lib/acml/gfortran/ -lacml_mp
}

在生成的可执行文件上使用ldd会显示对/usr/lib/acml/gfortran/libacml_mp.so的共享库依赖性。

但是在Windows上,我找不到正确的链接标志来链接到ACML。我使用acml5.3.1-ifort64.exe,它是使用Intel Fortran编译器针对64位Windows编译的。根据PDF手册(包含在acml的存档中acml.pdf,第2.3.2节),可以通过以下方式在Windows上动态链接:
cl driver.c -Ic:\acml5.3.1\ifort64_mp\include c:\acml5.3.1\ifort64_mp\lib\libacml_mp_dll.lib

将路径更改为正确的路径(cl不是链接器,而是编译器...)

因此,基本上,它应该只是将* libacml_mp_dll.lib *文件添加到链接命令。

不幸的是,我无法正确链接。我将此添加到Windows上的qmake项目文件中:
LIBS += $$quote(C:\AMD\acml5.3.1\ifort64_mp\lib\libacml_mp_dll.lib)

路径正确,文件存在,等等。

我不断出现链接错误,第一个是(和所有其他类似):
file.obj:-1: error: LNK2019: unresolved external symbol sgetrf_ referenced in function "void __cdecl arma::lapack::getrf<double>(int *,int *,double *,int *,int *,int *)" (??$getrf@N@lapack@arma@@YAXPEAH0PEAN000@Z)

符号sgetrf_是ACML应该提供的LAPACK函数。

如何正确链接?我是否正确设置qmake来查找ACML库?

非常感谢您的任何提示!

编辑:我检查了qmake生成的makefile如何调用链接器,并尝试从那里开始工作。这是当我完全不启用ACML时调用链接器的方式(将obj文件放入一个tmp文件中,该文件在make调用后消失,因此我只将“debug / *。obj”放入所有对象):
link.exe  /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='*******************' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\project.exe.embed.manifest /OUT:debug\project.exe debug/*.obj /LIBPATH:C:\Boost\1.54.0\lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\bin" hdf5.lib hdf5_hl.lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\lib"

然后,我将库手动添加到链接器命令。我尝试了这些:
link.exe  /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='*******************' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\project.exe.embed.manifest /OUT:debug\project.exe debug/*.obj /LIBPATH:C:\Boost\1.54.0\lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\bin" hdf5.lib hdf5_hl.lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\lib" /LIBPATH:C:\AMD\acml5.3.1\ifort64_mp\lib libacml_mp_dll.lib
link.exe  /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='*******************' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\project.exe.embed.manifest /OUT:debug\project.exe debug/*.obj /LIBPATH:C:\Boost\1.54.0\lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\bin" hdf5.lib hdf5_hl.lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\lib" C:\AMD\acml5.3.1\ifort64_mp\lib\libacml_mp_dll.lib
link.exe  /NOLOGO /DYNAMICBASE /NXCOMPAT /DEBUG /SUBSYSTEM:CONSOLE "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='*******************' language='*' processorArchitecture='*'" /MANIFEST /MANIFESTFILE:debug\project.exe.embed.manifest /OUT:debug\project.exe C:\AMD\acml5.3.1\ifort64_mp\lib\libacml_mp_dll.lib debug/*.obj /LIBPATH:C:\Boost\1.54.0\lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\bin" hdf5.lib hdf5_hl.lib /LIBPATH:"C:\Program Files\HDF_Group\HDF5\1.8.11\lib"

但是这些命令中的每个命令都会失败,并显示相同的链接器错误。

最佳答案

问题是ACML附带的BLAS没有下划线作为后缀。因此,必须在config.hpp中注释 Armadillo 的ARMA_BLAS_UNDERSCORE标志:

// #define ARMA_BLAS_UNDERSCORE

我正在使用的qmake配置如下:
win32: {
    ACMLDIR = $$quote(C:\AMD\acml5.3.1\ifort64_mp)
    INCLUDEPATH += $$quote($$ACMLDIR\include)
    LIBS += -L$$quote($$ACMLDIR\lib) -llibacml_mp_dll
}

10-08 13:43