使用cmake编译CSDP

时间:2016-02-14 09:02:58

标签: c++ c cmake lapack blas

我尝试使用CSDP,它是SDP的数学库。 我下载了一个提取lib(libsdp.a)的库。它使用lapack和blas lib,所以我添加-lblas和-llapack选项。

我想用cmake编译,hier是我的CmakeList文件(我评论了很多行,我只想测试一下example.c的编译,是一个CSDP给出的例子):

# Cette commande non obligatoire est fortement conseillée.
cmake_minimum_required (VERSION 2.6)

# Déclaration du projet.
# Les fichiers CMakeLists pourront référer à la racine du projet par la variable
# ${ECMA_SOURCE_DIR} et ${ECMA_BINARY_DIR}
project(projet_ECMA)
set(EXE run)

# L'exécutable sera rangé différemment en fonction de la plateformee.
# Par défaut le binaire est construit dans le répertoire courant (?)
# set(EXECUTABLE_OUTPUT_PATH ../bin)
# set( EXECUTABLE_OUTPUT_PATH bin/${CMAKE_BUILD_TYPE} )

#     SET (CMAKE_C_COMPILER             "/usr/bin/clang")
#     SET (CMAKE_C_FLAGS                "-Wall -std=c99")
#     SET (CMAKE_C_FLAGS_DEBUG          "-g++")
#     SET (CMAKE_C_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
#     SET (CMAKE_C_FLAGS_RELEASE        "-O4 -DNDEBUG")
#     SET (CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g")
#
#     SET (CMAKE_CXX_COMPILER             "/usr/bin/clang++")
#     SET (CMAKE_CXX_FLAGS                "-Wall")
#     SET (CMAKE_CXX_FLAGS_DEBUG          "-g")
#     SET (CMAKE_CXX_FLAGS_MINSIZEREL     "-Os -DNDEBUG")
#     SET (CMAKE_CXX_FLAGS_RELEASE        "-O4 -DNDEBUG")
#     SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
#
#     SET (CMAKE_AR      "/usr/bin/llvm-ar")
#     SET (CMAKE_LINKER  "/usr/bin/llvm-ld")
#     SET (CMAKE_NM      "/usr/bin/llvm-nm")
#     SET (CMAKE_OBJDUMP "/usr/bin/llvm-objdump")
#     SET (CMAKE_RANLIB  "/usr/bin/llvm-ranlib")

#set(CSDP_DIR "/home/hassan/Bureau/ECMA/projet_ECMA/trunk/lib/libsdp.a")
#find_package(CSDP REQUIRED)
SET (BLAS "/usr/lib/libcblas.a")
SET (LAPACK "/usr/lib/liblapack.a")
SET (CSDP "/home/hassan/Bureau/ECMA/projet_ECMA/trunk/lib/libsdp.a")
# Les options de compilation
# add_definitions(-Wall -Wextra -ansi -O2 -Wwrite-strings
#                 -Wuninitialized -Wno-missing-braces
#                 -Wno-missing-field-initializers)
add_definitions(
    # -Wno-unused-private-field  # Pour inhiber un warning de cplex 12.4
#    -m64
#    -g
#    -fPIC
#    -fexceptions
#    -pg
#    -DNDEBUG
#    -DIL_STD  # Pour cplex en C++
#    -std=c++11
#    -o
    -O3
#    -pthread
    #-L/home/hassan/Bureau/ECMA/projet_ECMA/trunk/lib    
    -ansi 
    -Wall
    -DNOSHORTS
    -DUSEGETTIME   
#    -lsdp

-lsdp -llapack
-latlas 
    -lcblas 
    -lgfortran
    -lm
-lg2c
-lctmg -lf2c

)

# Config spécifique à un système
# - UNIX vrai sous une plateforme Unix (don macosx)
# - APPLE vrai pour un os apple (donc macosx !)
# - WIN32 : vrai sous Windows (32 et 64bit !)
if(APPLE)
    message("=> Détection système Apple")
    set(CMAKE_EXE_LINKER_FLAGS  "-Wl,-no_compact_unwind")
endif()


# file(
#     GLOB
#     srcs
#     src/*.cpp
#     src/*.cc
#     src/*.c
#     src/*.hh
#     src/*.h
# )

# On définit la liste des tous les fichiers sources (dont les includes)
# cmale se débrouillera pour trouver le main() et les dépendances.
# On peut préciser des sous-répertoires, des groupes de fichiers, ...
# Mais ATTENTION aux fichiers inutilisés : ils seront compiler et peuvent
# provoquer des erreurs. Il peut donc être référable de préciser exactement les
# fichiers sources
file(
    GLOB
    srcs
    # src/site.*
    # src/station.*
    # src/remorque.*
    # src/arc.*
    # src/util.*
    # src/logger.*
    # src/options.*
    # src/bench.*
    # src/*Solver.*
    # src/solver.*
    # src/cir.*
    # src/solu.*
    # src/main.*
 #   src/*hpp
 #   /home/hassan/Bureau/ECMA/projet_ECMA/trunk/include/*.*
 #   src/*cpp
    src/*.cc
    src/*.hh
    src/example.c
    src/*.h
    # src/*.*
)

# Le ou les exécutables à générer
add_executable(${EXE} ${srcs})

# Les répertoire ou chercher vos includes (ou ceux de cplex, ...)
include_directories(
  # ${PROJECT_SOURCE_DIR}
  # ${PROJECT_BINARY_DIR}
  #$ENV{CONCERT_INCLUDE_DIR}
  $ENV{CSDP_INCLUDE}
  #$ENV{CPOPTIMIZER_INCLUDE_DIR}
  #$ENV{CPLEX_INCLUDE_DIR}
  # $ENV{LEMON_INCLUDE}
  #$ENV{CPOPTIM_INCLUDE_DIR}
  # $ENV{GLPK_INCLUDE}
)

# Ajouter ici les répertoires de vos bib. dynamiques utilisées
#

link_directories(
  # ${PROJECT_BINARY_DIR}/lemon
  # $ENV{LEMON_LIB}
  # $ENV{GLPK_LIB} 
   $ENV{CSDP_LIB} 
#  $ENV{CONCERT_LIB_DIR}
#  $ENV{CPLEX_LIB_DIR}
)

#find_library(CPLEX cplex HINTS $ENV{CPLEX_LIB_DIR})
#find_library(ILO_CPLEX ilocplex HINTS $ENV{CPLEX_LIB_DIR})
#find_library(CPOTIMIZER cpoptimizer HINTS $ENV{CPOPTIMIZER_LIB_DIR})
#find_library(CONCERT concert HINTS $ENV{CONCERT_LIB_DIR})
find_library(CSDP sdp HINTS $ENV{CSDP_LIB})

# Ajouter ici les bibliothèques dynamiques que vous utilisez
#
target_link_libraries(${EXE} blas)  # pour programmation multithead
target_link_libraries(${EXE} lapack)  # pour programmation multithead
#target_link_libraries(${EXE} sdp)  # pour programmation multithead
target_link_libraries(${EXE} pthread)  # pour programmation multithead
target_link_libraries(${EXE} m)        # lib mathématique
target_link_libraries(${EXE} ${ILO_CPLEX}) # spécial cplex
target_link_libraries(${EXE} ${CPLEX})    # spécial cplex
target_link_libraries(${EXE} ${CPOPTIMIZER})    # spécial cplex
target_link_libraries(${EXE} ${CONCERT})  # spécial cplex
message("=> CSDP     is   ${CONCERT}")
#target_link_libraries(${EXE} ${BLAS})  # spécial csdp
#target_link_libraries(${EXE} ${LAPACK})  # spécial csdp
target_link_libraries(${EXE} ${CSDP})  # spécial csdp

#target_link_libraries(${EXE} ${BLAS})  # spécial csdp
# target_link_libraries(${EXE} emon)   # lib de graphe
# target_link_libraries(${EXE} glpk)   # solveur PLNE gratuit




# La liste des exécutables mono-fichiers à compiler
## set(demo_srcs
##     main.cc
##     test1.cc
##     test2.cc
## )
# file(GLOB demo_srcs src/*.cc)


## foreach(demo_src ${demo_srcs})
##     get_filename_component( demo_name ${demo_src} NAME_WE )
##     message("=> demo_src=${demo_src}")
##     message("=> demo_name=${demo_name}")
##     add_executable(${demo_name} ${demo_src})
##     target_link_libraries(${demo_name} emon)
## endforeach()

# Quelques messages précisant la configuration utilisée
#
 message("=> CSDP_INCLUDE     is   $ENV{CSDP_INCLUDE}")
 message("=> CSDP_LIB     is   $ENV{CSDP_LIB}")
 message("=> ILOG_CPLEX_INCLUDE     is   $ENV{CPLEX_INCLUDE_DIR}")
 message("=> ILOG_CPLEX_LIB         is   $ENV{CPLEX_LIB_DIR}")
 message("=> ILOG_CONCERT_INCLUDE   is   $ENV{CONCERT_INCLUDE_DIR}")
 message("=> ILOG_CONCERT_LIB       is   $ENV{CONCERT_LIB_DIR}")
# message("=> LEMON_INCLUDE          is   $ENV{LEMON_INCLUDE}")
# message("=> LEMON_LIB              is   $ENV{LEMON_LIB}")
# message("=> GLPK_INCLUDE           is   $ENV{GLPK_INCLUDE}")
# message("=> GLPK_LIB               is   $ENV{GLPK_LIB}")
message("=> srcs                   is   ${srcs}")
# Ceci affiche 8 sur un machine 64 bits ou 4 sur un machine 32 bit
message("=> CMAKE_SIZEOF_VOID_P    is   ${CMAKE_SIZEOF_VOID_P}")
message("\n")



#
# Complément pour ajouter quelques cibles personnalisées dans le Makefile généré
#
EXECUTE_PROCESS(
    COMMAND date +%Y%m%d-%Hh%M
    OUTPUT_VARIABLE date_stamp
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
GET_FILENAME_COMPONENT( project_dir_name ${CMAKE_SOURCE_DIR} NAME )


# On peut compléter les cible du Makefile généré
# (la comande finale de cette ciblesera ajoutée à CMakeFiles/Makefile2)
# (puis Essayer de créer un cmake tbz !!)
ADD_CUSTOM_TARGET(distclean
    COMMAND @echo Nettoyage complet des sources
    COMMAND @echo \"Répertoire courant = `pwd`\"
    COMMAND @echo "CMAKE_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}"
    # COMMAND make clean
    COMMAND find ${CMAKE_CURRENT_BINARY_DIR} -name "CMakeCache.txt" | xargs rm -rf
    COMMAND rm -rf ${CMAKE_CURRENT_BINARY_DIR}/*
)
ADD_CUSTOM_TARGET(dc
    COMMAND make distclean
)
ADD_CUSTOM_TARGET(cc
    COMMAND make distclean
)
ADD_CUSTOM_TARGET(c
    COMMAND make clean
)
# Attention : cette commande construit une cible pour le Makefile.
# Il faut protéger les double-quote si l'on veux qu'elles ne soient pas consommées
# par cmake mais passée au Makefile.
# Un seul COMMENT par cible semble-t-il
ADD_CUSTOM_TARGET(tbz
    COMMENT "Création d'une archive datée du projet"
    COMMAND @echo \" => duplication du projet en : ${project_dir_name}-${date_stamp}\"
    COMMAND cp -Rp ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}-${date_stamp}
    COMMAND rm -r ${CMAKE_SOURCE_DIR}-${date_stamp}/build/
    COMMAND mkdir -p ${CMAKE_SOURCE_DIR}-${date_stamp}/build/
    # tar -C newDir :  pour se placer dans le répertoire parent de l'archive
    COMMAND tar cjf  ${CMAKE_SOURCE_DIR}-${date_stamp}.tbz
                     -C ${CMAKE_SOURCE_DIR}/..
                     ${project_dir_name}-${date_stamp}
    COMMAND rm -r ${CMAKE_SOURCE_DIR}-${date_stamp}
    COMMAND @echo \" => Archive faite :  ${project_dir_name}-${date_stamp}.tbz\"
)
ADD_CUSTOM_TARGET(txz
    COMMENT "Création d'une archive datée du projet (TEST XZ)"
    COMMAND @echo \" => duplication du projet en : ${project_dir_name}-${date_stamp}\"
    COMMAND cp -Rp ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}-${date_stamp}
    COMMAND rm -r ${CMAKE_SOURCE_DIR}-${date_stamp}/build/
    COMMAND mkdir -p ${CMAKE_SOURCE_DIR}-${date_stamp}/build/
    # tar -C newDir :  pour se placer dans le répertoire parent de l'archive
    COMMAND tar cf  ${CMAKE_SOURCE_DIR}-${date_stamp}.tar
                     -C ${CMAKE_SOURCE_DIR}/..
                     ${project_dir_name}-${date_stamp}
    COMMAND xz  ${CMAKE_SOURCE_DIR}-${date_stamp}.tar
    COMMAND mv    ${CMAKE_SOURCE_DIR}-${date_stamp}.tar.xz ${CMAKE_SOURCE_DIR}-${date_stamp}.txz
    COMMAND rm -r ${CMAKE_SOURCE_DIR}-${date_stamp}
    COMMAND @echo \" => Archive faite :  ${project_dir_name}-${date_stamp}.tbz\"
)
# ADD_CUSTOM_TARGET(zip
#     COMMENT "Création d'une archive datée du proje (TEST ZIP°t"
#     COMMAND @echo \" => duplication du projet en : ${project_dir_name}-${date_stamp}\"
#     COMMAND cp -Rp ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}-${date_stamp}
#     COMMAND rm -r ${CMAKE_SOURCE_DIR}-${date_stamp}/build/
#     COMMAND mkdir -p ${CMAKE_SOURCE_DIR}-${date_stamp}/build/
#     COMMAND echo \"1: CMAKE_SOURCE_DIR-date_stamp==1==${CMAKE_SOURCE_DIR}-${date_stamp}\"
#     COMMAND echo \"2: project_dir_name-date_stamp==2==${project_dir_name}-${date_stamp}\"
#     # tar -C newDir :  pour se placer dans le répertoire parent de l'archive
#     # COMMAND '_pwd=`pwd`'
#     # COMMAND pushd  ${CMAKE_SOURCE_DIR}/..
#     COMMAND echo 'pushd; zip -r -v -y -o -9  ${CMAKE_SOURCE_DIR}-${date_stamp}.zip \
#                      ${project_dir_name}-${date_stamp} ; popd'
#     COMMAND sh -c "pushd; zip -r -v -y -o -9  ${CMAKE_SOURCE_DIR}-${date_stamp}.zip \
#                      ${project_dir_name}-${date_stamp} ; popd"
#     # COMMAND zip -r -v -y -o -9  ${CMAKE_SOURCE_DIR}-${date_stamp}.zip
#     #                  ${project_dir_name}-${date_stamp}
#     COMMAND 'cd $_pwd'
#     # COMMAND popd
#     COMMAND rm -r ${CMAKE_SOURCE_DIR}-${date_stamp}
#     COMMAND @echo \" => Archive faite :  ${project_dir_name}-${date_stamp}.tbz\"
# )

INCLUDE(InstallRequiredSystemLibraries)
IF(WIN32 AND NOT UNIX)
    SET(CPACK_NSIS_MODIFY_PATH ON)
ENDIF(WIN32 AND NOT UNIX)

INCLUDE(CPack)

#./

问题是,我认为libsdp.a需要库(blas,lapack和math)但是,即使我在Cmake中添加它,他也没有成功找到它:

    [100%] Building C object CMakeFiles/run.dir/src/example.c.o
/usr/bin/cc  -DNOSHORTS -DUSEGETTIME -I/home/hassan/Bureau/ECMA/projet_ECMA/trunk/include    -O3 -ansi -Wall -lsdp -llapack -latlas -lcblas -lgfortran -lm -lg2c -lctmg -lf2c -o CMakeFiles/run.dir/src/example.c.o   -c /home/hassan/Bureau/ECMA/projet_ECMA/src/example.c
/home/hassan/Bureau/ECMA/projet_ECMA/src/example.c: In function ‘main’:
/home/hassan/Bureau/ECMA/projet_ECMA/src/example.c:62:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘double’ [-Wformat=]
  printf("%d \n", sqrt(2));
  ^
Linking C executable run
/usr/bin/cmake -E cmake_link_script CMakeFiles/run.dir/link.txt --verbose=1
/usr/bin/cc      CMakeFiles/run.dir/src/example.c.o  -o run -rdynamic -lblas -llapack -lpthread -lm trunk/lib/libsdp.a 
trunk/lib/libsdp.a(initsoln.o): dans la fonction « initsoln »:
initsoln.c:(.text+0x2a9): référence indéfinie vers « sqrt »
initsoln.c:(.text+0x2ed): référence indéfinie vers « sqrt »
initsoln.c:(.text+0x334): référence indéfinie vers « sqrt »
trunk/lib/libsdp.a(norms.o): dans la fonction « norm2 »:
norms.c:(.text+0x1d): référence indéfinie vers « dnrm2_ »
trunk/lib/libsdp.a(norms.o): dans la fonction « norm1 »:
norms.c:(.text+0x4d): référence indéfinie vers « dasum_ »
trunk/lib/libsdp.a(norms.o): dans la fonction « norminf »:
norms.c:(.text+0x81): référence indéfinie vers « idamax_ »
trunk/lib/libsdp.a(sdp.o): dans la fonction « sdp »:
sdp.c:(.text+0x1ed7): référence indéfinie vers « dpotrf_ »
sdp.c:(.text+0x2104): référence indéfinie vers « pow »
sdp.c:(.text+0x7cf3): référence indéfinie vers « sqrt »
sdp.c:(.text+0x8651): référence indéfinie vers « sqrt »
sdp.c:(.text+0x88eb): référence indéfinie vers « sqrt »
sdp.c:(.text+0x88f5): référence indéfinie vers « sqrt »
sdp.c:(.text+0x8968): référence indéfinie vers « pow »
sdp.c:(.text+0x89bd): référence indéfinie vers « sqrt »
sdp.c:(.text+0x89e9): référence indéfinie vers « sqrt »
trunk/lib/libsdp.a(Fnorm.o): dans la fonction « Fnorm »:
Fnorm.c:(.text+0xcb): référence indéfinie vers « sqrt »
trunk/lib/libsdp.a(calc_dobj.o): dans la fonction « calc_dobj »:
calc_dobj.c:(.text+0x2d): référence indéfinie vers « ddot_ »
trunk/lib/libsdp.a(mat_mult.o): dans la fonction « mat_mult »:
mat_mult.c:(.text+0xef): référence indéfinie vers « dgemm_ »
trunk/lib/libsdp.a(mat_mult.o): dans la fonction « mat_mult_raw »:
mat_mult.c:(.text+0x479): référence indéfinie vers « dgemm_ »
trunk/lib/libsdp.a(solvesys.o): dans la fonction « solvesys »:
solvesys.c:(.text+0x40): référence indéfinie vers « dpotrs_ »
trunk/lib/libsdp.a(linesearch.o): dans la fonction « linesearch »:
linesearch.c:(.text+0x39f): référence indéfinie vers « dgemv_ »
linesearch.c:(.text+0x416): référence indéfinie vers « dgemv_ »
linesearch.c:(.text+0x488): référence indéfinie vers « dgemv_ »
linesearch.c:(.text+0x4ff): référence indéfinie vers « dgemv_ »
linesearch.c:(.text+0xe2b): référence indéfinie vers « sqrt »
trunk/lib/libsdp.a(matvec.o): dans la fonction « matvec »:
matvec.c:(.text+0xb8): référence indéfinie vers « dgemv_ »
trunk/lib/libsdp.a(chol.o): dans la fonction « chol_blk »:
chol.c:(.text+0x36): référence indéfinie vers « dpotrf_ »
trunk/lib/libsdp.a(chol.o): dans la fonction « chol_diag »:
chol.c:(.text+0x134): référence indéfinie vers « sqrt »
trunk/lib/libsdp.a(chol.o): dans la fonction « chol »:
chol.c:(.text+0x1bd): référence indéfinie vers « dpotrf_ »
chol.c:(.text+0x2e1): référence indéfinie vers « sqrt »
trunk/lib/libsdp.a(chol.o): dans la fonction « chol_inv »:
chol.c:(.text+0x42f): référence indéfinie vers « dtrtri_ »
trunk/lib/libsdp.a(qreig.o): dans la fonction « qreig »:
qreig.c:(.text+0x539): référence indéfinie vers « sqrt »
qreig.c:(.text+0x64f): référence indéfinie vers « sqrt »
qreig.c:(.text+0x718): référence indéfinie vers « sqrt »
collect2: error: ld returned 1 exit status
make[2]: *** [run] Erreur 1

1 个答案:

答案 0 :(得分:0)

不是真正的答案。这是我的包含用于构建blas / lapack的CMake文件,如果它可以帮助你。它需要以下变量:DefaultLapackPathCompilerName(小写)和GetLapackVersion.cpp给出的目录中的cpp文件${CMAKE_MODULES_DIR}。(见下文)。

文件 LoadLapack.cmake

set(LapackPath "${DefaultLapackPath}" CACHE PATH "Path to Lapack installation")
if(NOT "${LapackPath}" STREQUAL "${LapackPath_copy}")
    unset(LibBlas CACHE)
    unset(LibLapack CACHE)
    set(LapackPath_copy "${LapackPath}" CACHE INTERNAL "")
endif()
message(STATUS "Path to Lapack: ${LapackPath}")

set(Lapack_LIBRARY_DIRS ${LapackPath}/lib)
find_library(LibBlas blas PATHS ${Lapack_LIBRARY_DIRS} DOC "Complete path to blas library" NO_DEFAULT_PATH)
find_library(LibLapack lapack PATHS ${Lapack_LIBRARY_DIRS} DOC "Complete path to lapack library" NO_DEFAULT_PATH)
if(EXISTS "${LibBlas}" AND EXISTS "${LibLapack}")
    message(STATUS "Lapack libraries found !")
else()
    message(SEND_ERROR "Lapack libraries not found...")
endif()

if(CompilerName STREQUAL "gcc")
    set(Fortran_LIBRARIES gfortran)
endif()
set(Lapack_LIBRARIES lapack blas)

set(NAME_MANGLING_OPTIONS
    "NameManglingUpper"
    "NameManglingLower"
    "NameManglingUBack"
    "NameMangling2UBack"
    "NameManglingUFront"
    "NameMangling2UFront")
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()

set(GET_LAPACK_VERSION_LIBRARY_DIRS ${Lapack_LIBRARY_DIRS} ${Compiler_LIBRARY_DIRS})
set(GET_LAPACK_VERSION_LIBRARIES ${Lapack_LIBRARIES} ${Fortran_LIBRARIES})
try_run(GET_LAPACK_VERSION_RUN GET_LAPACK_VERSION_COMPILE ${CMAKE_BINARY_DIR}/tmpLapack ${CMAKE_MODULES_DIR}/GetLapackVersion.cpp
        CMAKE_FLAGS "-DLINK_DIRECTORIES=${GET_LAPACK_VERSION_LIBRARY_DIRS}" "-DLINK_LIBRARIES=${GET_LAPACK_VERSION_LIBRARIES}"
        COMPILE_DEFINITIONS "-D${LAPACK_NAME_MANGLING}"
        COMPILE_OUTPUT_VARIABLE GET_LAPACK_VERSION_COMPILE_OUT RUN_OUTPUT_VARIABLE GET_LAPACK_VERSION_RUN_OUT)
if(NOT GET_LAPACK_VERSION_COMPILE)
    message(SEND_ERROR "Impossible to compile the file \"${CMAKE_MODULES_DIR}/GetLapackVersion.cpp\". Output: ${GET_LAPACK_VERSION_COMPILE_OUT}")
elseif(NOT GET_LAPACK_VERSION_RUN_OUT MATCHES "^[0-9]+.[0-9]+.[0-9]+")
    message(SEND_ERROR "Error while running GetLapackVersion:${GET_LAPACK_VERSION_RUN_OUT}XXX")
else()
    string(STRIP "${GET_LAPACK_VERSION_RUN_OUT}" LapackVersion)
    if(LapackVersion VERSION_LESS "${RequiredLapackVersion}")
        message(SEND_ERROR "The version of Lapack (${LapackVersion}) is too old")
    else()
        message(STATUS "Lapack version: ${LapackVersion}")
    endif()
endif()

mark_as_advanced(LibBlas FORCE)
mark_as_advanced(LibLapack FORCE)

文件 GetLapackVersion.cpp

#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
#elif defined LapackNameMangling2UFront
    #define ilaver __ilaver
#endif
extern "C" { void ilaver(int* major, int* minor, int* patch); }
int main()
{
    int major = 0; int minor = 0; int patch = 0;
    ilaver(&major, &minor, &patch);
    std::cout << major << "." << minor << "." << patch << std::endl;
    return 0;
}

然后我定义我的blas / lapack头文件:

档案 blas.h

#ifndef _INCLUDED__BLAS_H_
#define _INCLUDED__BLAS_H_
#if defined LapackNameManglingUpper
#   define dgemm DGEMM
#   define dsymm DSYMM
#   define dtrmm DTRMM
#elif defined LapackNameManglingLower
#   define dgemm dgemm
#   define dsymm dsymm
#   define dtrmm dtrmm
#elif defined LapackNameManglingUBack
#   define dgemm dgemm_
#   define dsymm dsymm_
#   define dtrmm dtrmm_
#elif defined LapackNameMangling2UBack
#   define dgemm dgemm__
#   define dsymm dsymm__
#   define dtrmm dtrmm__
#elif defined LapackNameManglingUFront
#   define dgemm _dgemm
#   define dsymm _dsymm
#   define dtrmm _dtrmm
#elif defined LapackNameMangling2UFront
#   define dgemm __dgemm
#   define dsymm __dsymm
#   define dtrmm __dtrmm
#endif
namespace blas
{
    extern "C"
    {
        void dgemm(char* transa, char* transb, int* m, int* n, int* k, double* alpha, double* A, int* lda, double* B, int* ldb, double* beta, double* C, int* ldc);
        void dsymm(char* side, char* uplo, int* m, int* n, double* alpha, double* A, int* lda, double* B, int* ldb, double* beta, double* C, int* ldc);
        void dtrmm(char* side, char* uplo, char* transa, char* diag, int* m, int* n, double* alpha, double* A, int* lda, double* B, int* ldb);
    }
}
#endif

然后,我可以用这种CMake文件构建我的可执行文件:

link_directories( ${Lapack_LIBRARY_DIRS} )
set( MyApp_UsedLib
    ${Lapack_LIBRARIES}
    ${Fortran_LIBRARIES}
)
add_executable( myapp my_app.cpp )
target_link_libraries(myapp ${MyApp_UsedLib})