C++ 使用cmake编译CSDP
我试图使用CSDP,它是SDP的一个数学库。 我下载了库并提取了库(libsdp.a)。它使用lapack和blas lib,所以我添加了-lblas和-llapack选项 我想用cmake编译,hier是我的CmakeList文件(我注释了很多行,我只想测试example.c的编译,它是CSDP给出的一个示例): 问题是,我认为libsdp.a需要一个库(blas、lapack和math),但是,即使我将它添加到我的Cmake中,他也没有成功地找到它:C++ 使用cmake编译CSDP,c++,c,cmake,lapack,blas,C++,C,Cmake,Lapack,Blas,我试图使用CSDP,它是SDP的一个数学库。 我下载了库并提取了库(libsdp.a)。它使用lapack和blas lib,所以我添加了-lblas和-llapack选项 我想用cmake编译,hier是我的CmakeList文件(我注释了很多行,我只想测试example.c的编译,它是CSDP给出的一个示例): 问题是,我认为libsdp.a需要一个库(blas、lapack和math),但是,即使我将它添加到我的Cmake中,他也没有成功地找到它: [100%] Building
[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
这不是一个真正的答案。这是我的CMake文件,如果可以帮助您的话,我将包括用于使用blas/lapack构建的文件。它需要以下变量:
DefaultLapackPath
,CompilerName
(小写),以及${CMAKE_MODULES_DIR}
给定目录中的cpp文件GetLapackVersion.cpp
(见下文)
文件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)
#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;
}
#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
文件GetLapackVersion.cpp:
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)
#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;
}
#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})
(我的shell是法语的,但“référence indéfinie vers”类似于“未定义的引用”)
add_definitions
为编译器添加定义,但-l
是链接器的一个选项。您需要使用。与相同的错误?