c++ - 如何将 lapack 与 CMake 和 Visual 2013 链接起来?

标签 c++ linker cmake intel lapack

摘要: 我使用 lapack 创建了一个简单的 c++ 示例。由于链接错误,我无法使用 CMake 和 Visual Studio 2013 对其进行编译。

配置:Windows 7 64 位、Visual Studio 12 2013 Win64、编译器 intel64、CMake 3.1.0、Lapack 3.5.0。

Lapack 安装: 我使用 CMake 构建了 lapack 3.5.0,使用的是来自 intel 的编译器。我激活了除 BUILD_SHARED_LIBS 之外的所有 BUILD_* 选项。我在 Release模式下使用 Visual Studio 构建。我在安装目录下得到了两个lib文件:blas.lib和lapack.lib。

C++ 示例:我使用函数 ilaver(给出了 lapack 的版本)创建了以下简单的 C++ 示例。

#include <iostream>
extern "C" { void ilaver_(int* major, int* minor, int* patch); }
int main(int argc, char** argv)
{
  int major = 0; int minor = 0; int patch = 0;
  ilaver_(&major, &minor, &patch);
  std::cout << major << "." << minor << "." << patch << std::endl;
  return 0;
}

CMakeLists.txt:我还创建了关联的 CMakeLists 文件:

cmake_minimum_required(VERSION "2.8.9")
project(linklapack)
enable_language(C)
enable_language(CXX)
enable_language(Fortran)
set(LAPACK_LIBDIRS "C:/softs/lapack/3.5.0/64/lib")
set(LAPACK_LIBRARIES lapack)
link_directories(${LAPACK_LIBDIRS})
add_executable(GetLapackVersion ${CMAKE_SOURCE_DIR}/GetLapackVersion.cpp)
target_link_libraries(GetLapackVersion ${LAPACK_LIBRARIES})
install(TARGETS GetLapackVersion DESTINATION ${CMAKE_INSTALL_PREFIX})

在 Linux 下: 它可以工作。 (当然是通过改变lib的路径)

在 Windows 下: 我使用相同的编译器和相同的 Visual Studio 配置启动了 CMake。我为 Visual Studio 加载了生成的解决方案,并构建了“GetLapackVersion”目标。然后我收到以下链接错误:

2>GetLapackVersion.obj : error LNK2019: unresolved external symbol ilaver_ referenced in function main
2>C:\Users\caduchon\Documents\Christophe\linklapack\BUILD\Release\GetLapackVersion.exe : fatal error LNK1120: 1 unresolved externals

编辑:目标在 Visual Studio 中的链接命令如下:

/OUT:"C:\Users\caduchon\Documents\Christophe\linklapack\BUILD\Release\GetLapackVersion.exe" /MANIFEST /NXCOMPAT /PDB:"C:/Users/caduchon/Documents/Christophe/linklapack/BUILD/Release/GetLapackVersion.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "comdlg32.lib" "advapi32.lib" "lapack.lib" /IMPLIB:"C:/Users/caduchon/Documents/Christophe/linklapack/BUILD/Release/GetLapackVersion.lib" /MACHINE:X64 /INCREMENTAL:NO /PGD:"C:\Users\caduchon\Documents\Christophe\linklapack\BUILD\Release\GetLapackVersion.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"GetLapackVersion.dir\Release\GetLapackVersion.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:/softs/lapack/3.5.0/64/lib" /LIBPATH:"C:/softs/lapack/3.5.0/64/lib/Release" /TLBID:1 

我不知道如何解决这个问题...在此先感谢您的帮助。

最佳答案

回答我自己的问题。

正如 rubenvb 所预料的那样,库中没有出现预期的符号。该问题被记录为“Fortran Name Mangling”。为了用 CMake 检测库的配置,我修改了我的测试示例如下:

#include <iostream>
#if defined LapackNameManglingUpper
#define ilaver ILAVER
#elif defined LapackNameManglingLower
#define ilaver ilaver
#elif defined LapackNameManglingUBack
#define ilaver ilaver_
#elif defined LapackNameMangling2UBack
#define ilaver ilaver__
#elif defined LapackNameManglingUFront
#define ilaver _ilaver
#endif
extern "C" { void ilaver(int* major, int* minor, int* patch); }
int main(int argc, char** argv)
{
  int major = 0; int minor = 0; int patch = 0;
  ilaver(&major, &minor, &patch);
  std::cout << major << "." << minor << "." << patch << std::endl;
  return 0;
}

然后,我可以通过尝试使用附加参数 -DLapackNameManglingConfig 编译代码来检测 CMake 的良好配置:

set(NAME_MANGLING_OPTIONS
  "NameManglingUpper"
  "NameManglingLower"
  "NameManglingUBack"
  "NameMangling2UBack"
  "NameManglingUFront")
set(LAPACK_NAME_MANGLING "")
foreach(NAME_MANGLING_OPTION IN LISTS NAME_MANGLING_OPTIONS)
  set(LAPACK_NAME_MANGLING "${NAME_MANGLING_OPTION}")
  set(TRY_MANGLING_LIBRARY_DIRS ${Lapack_LIBRARY_DIRS} ${Compiler_LIBRARY_DIRS})
  set(TRY_MANGLING_LIBRARIES ${Lapack_LIBRARIES} ${Fortran_LIBRARIES})
  try_compile(TRY_MANGLING_OPTION ${CMAKE_BINARY_DIR}/tmpLapack ${CMAKE_MODULES_DIR}/GetLapackVersion.cpp
              CMAKE_FLAGS "-DLINK_DIRECTORIES=${TRY_MANGLING_LIBRARY_DIRS}" "-DLINK_LIBRARIES=${TRY_MANGLING_LIBRARIES}"
              COMPILE_DEFINITIONS "-DLapack${NAME_MANGLING_OPTION}")
  if(TRY_MANGLING_OPTION)
    set(LAPACK_NAME_MANGLING "Lapack${NAME_MANGLING_OPTION}")
    break()
  endif()
endforeach()
if(LAPACK_NAME_MANGLING STREQUAL "")
  message(SEND_ERROR "Impossible to detect Fortran name mangling...")
else()
  message(STATUS "Lapack: detected Fortran name mangling: ${LAPACK_NAME_MANGLING}")
  add_definitions("-D${LAPACK_NAME_MANGLING}")
endif()

关于c++ - 如何将 lapack 与 CMake 和 Visual 2013 链接起来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28542426/

相关文章:

c++ - .obj 中已定义的函数

c++ - C/C++ - 条件头文件包含不起作用

c++ - CMake这个 “/string”文件失败了吗?

boost - 在cMake中使用boost.asio

c++ - CMake 和 Window .Lib 文件

c++ - 使用 libudev 时没有内存

C++ 获取不同线程的回溯

c++ - RegQueryValueEx 不返回值的数据

c++ - 将遗留 MFC DAO 应用程序转换为使用 Access 2013

assembly - 是什么阻止您单独运行目标文件?