我正在使用cmake verison 2.8.11.2使用一些外部库和包构建项目。但是,因为我尝试添加库spglib,我无法编译代码。尽管CMake添加了正确的.so文件,但生成的makefile无法正确链接到它。
我在 src / main / CMakeLists.txt 中使用以下CMake代码来包含spglib .so文件:
ADD_EXECUTABLE(PotFit ${SourceFiles})
SET_TARGET_PROPERTIES(PotFit PROPERTIES COMPILE_DEFINITIONS "${POTFIT_COMPILE_DEFINITIONS}")
TARGET_LINK_LIBRARIES(PotFit PotFitLibrary boost_timer boost_system)
set(CMAKE_PREFIX_PATH [path to]/src/.libs)
find_library(SPGLIBRARY NAMES spg spglib libsymspg symspg PATHS /home/staffana /CS/trunk/spglib-1.6.0/src/.libs [path to]/spglib-1.6.0/src)
target_link_libraries(PotFit "${SPGLIBRARY}")
这似乎有效。我检查CMake实际上是否使用
找到了库 message("The value of SPGLibrary is")
message("${SPGLIBRARY}")
正确返回libsymspg.so的路径。但是编译器会返回错误
CMakeFiles/PotFit.dir/Main.cpp.o: In function `main':
Main.cpp:(.text.startup+0x11a): undefined reference to `spg_get_spacegroup_type(int)'
collect2: error: ld returned 1 exit status
make[2]: *** [main/PotFit] Error 1
make[1]: *** [main/CMakeFiles/PotFit.dir/all] Error 2
make: *** [all] Error 2
*** Failure: Exit code 2 ***
我确保libsymspg.so使用
包含此符号nm libsymspg.so | grep get_spacegroup_type
返回
0000ad30 T spgdb_get_spacegroup_type
0000c240 T spg_get_spacegroup_type
所以在Cmake和链接之间有些不对劲。据我所知,我正在使用“正常”的做事方式,所以我不知道从哪里开始寻找造成这个问题的原因。我已经在下面添加了所有CMakeLists.txt,因为这可能很有用,如果需要我可以添加CMakeCache(它是p.long ...)。
src / CMake.txt:
PROJECT(FitPot CXX C Fortran)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
OPTION(USE_OPENMP "Use OpenMP parallelization" "ON")
OPTION(ENABLE_DEBUG_CHECKS "Enable sanity checks in the code." "ON")
# Find and set up Qt4 library.
SET(QT_USE_QTOPENGL FALSE)
SET(QT_USE_QTGUI FALSE)
SET(QT_USE_QTXML TRUE)
SET(QT_USE_QTXMLPATTERNS FALSE)
SET(QT_MIN_VERSION "4.6.0")
# Use the Q_SIGNALS and Q_SLOTS macros to avoid name conflicts with Python.
ADD_DEFINITIONS(-DQT_NO_KEYWORDS)
FIND_PACKAGE(Qt4)
IF(NOT QT4_FOUND)
IF(QT4_INSTALLED_VERSION_TOO_OLD)
MESSAGE(FATAL_ERROR "The installed Qt version ${QTVERSION} is too old, at least version ${QT_MIN_VERSION} is required.")
ELSE(QT4_INSTALLED_VERSION_TOO_OLD)
MESSAGE(FATAL_ERROR "The Qt library or the qmake program was not found! Please install Qt manually and specify the path to the 'qmake' program by setting the QT_QMAKE_EXECUTABLE setting in CMake. You need at least version ${QT_MIN_VERSION}.")
ENDIF(QT4_INSTALLED_VERSION_TOO_OLD)
ENDIF(NOT QT4_FOUND)
INCLUDE(${QT_USE_FILE})
# Find Boost library.
#SET(BOOST_ROOT "/usr/local/boost_1_50_0/") # Might want to use this line, a modified version. !!MODIFYME
FIND_PACKAGE(Boost REQUIRED)
IF(NOT Boost_FOUND)
MESSAGE(FATAL_ERROR "Boost library not found. Reason: ${Boost_ERROR_REASON}")
ENDIF()
# Modify this line to point to the directory where the boost libraries are. !!MODIFYME
SET(Boost_LIBRARY_DIRS "/usr/local/boost_1_50_0/stage/lib")
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
find_package(OpenMP)
if (OPENMP_FOUND)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
endif()
MESSAGE("boost lib dirs: ${Boost_LIBRARY_DIRS}")
MESSAGE("boost include dirs: ${Boost_INCLUDE_DIRS}")
# Choose compiler flags for Fortran compiler.
GET_FILENAME_COMPONENT(Fortran_COMPILER_NAME ${CMAKE_Fortran_COMPILER} NAME)
IF(Fortran_COMPILER_NAME MATCHES "gfortran")
# gfortran:
SET(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -funroll-all-loops -fno-f2c -O3")
SET(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fno-f2c -O0 -g")
ELSEIF(Fortran_COMPILER_NAME STREQUAL "ifort")
# ifort:
# The '-fltconsistency' flag forces the compiler to "maintain floating point precision";
# replaces -mp option in older ifort versions.
# This is necessary to avoid hangups in the 'dpmeps' function in lbfgs.f on some systems.
SET(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -fltconsistency -f77rtl -O3")
SET(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fltconsistency -f77rtl -O0 -g")
ELSEIF(Fortran_COMPILER_NAME STREQUAL "g77")
# g77:
SET(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -funroll-all-loops -fno-f2c -O3 -m32")
SET(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -fno-f2c -O0 -g -m32")
ELSE()
MESSAGE("Unknown Fortran compiler (${Fortran_COMPILER_NAME}), using default flags")
SET(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -O2")
SET(CMAKE_Fortran_FLAGS_DEBUG "${CMAKE_Fortran_FLAGS_DEBUG} -O0 -g")
ENDIF()
SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS_RELEASE}")
MESSAGE("Fortran flags: ${CMAKE_Fortran_FLAGS}")
# Code files will reference header files relative to the root source directory.
INCLUDE_DIRECTORIES(".")
IF(ENABLE_DEBUG_CHECKS)
SET(POTFIT_COMPILE_DEFINITIONS "DEBUG_FITPOT")
ENDIF()
# Creates a sub CMakeList.txt in those two subdirectories where source files are defined.
ADD_SUBDIRECTORY(potfitlib)
ADD_SUBDIRECTORY(main)
MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
MESSAGE("cxx flags: ${CMAKE_CXX_FLAGS}")
MESSAGE("cxx linker flags: ${CMAKE_EXE_LINKER_FLAGS}")
MESSAGE("Library path is : ${CMAKE_LIBRARY_PATH}")
的src / potfitlib /的CMakeLists.txt
# List of source files that need to be compiled:
SET(SourceFiles
util/linalg/LinAlg.cpp
util/Debug.cpp
util/Dijkstra.cpp
job/FitJob.cpp
job/Fitting.cpp
job/Validation.cpp
potentials/Potential.cpp
potentials/TabulatedEAMPotential.cpp
potentials/SplineMEAMPotential.cpp
potentials/LennardJonesPotential.cpp
potentials/CDIPotential.cpp
potentials/HarmonicModelFullPhi.cpp
potentials/HarmonicModel.cpp
potentials/PairPotential.cpp
potentials/FourthOrderModel.cpp
potentials/functions/CubicSpline.cpp
potentials/functions/GridCubicSpline.cpp
potentials/functions/Functions.cpp
potentials/fourthOrderHelpers/Bond.cpp
potentials/fourthOrderHelpers/TupleFinder.cpp
potentials/fourthOrderHelpers/SymmetryOperator.cpp
potentials/fourthOrderHelpers/GeneralizedDirection.cpp
potentials/fourthOrderHelpers/ForceTuple.cpp
potentials/fourthOrderHelpers/OldEnergyAndForces.cpp
potentials/fourthOrderHelpers/ForceComputation.cpp
properties/FitProperty.cpp
properties/AtomVectorProperty.cpp
dof/DegreeOfFreedom.cpp
dof/AtomCoordinatesDOF.cpp
structures/FitObject.cpp
structures/StructureGroup.cpp
structures/AtomicStructure.cpp
structures/UserStructure.cpp
structures/NeighborList.cpp
structures/LatticeStructures.cpp
minimizer/SplitBregmanFunctionEvaluator.cpp
minimizer/Minimizer.cpp
minimizer/SplitBregmanMinimizer.cpp
minimizer/MinimizerParameters.cpp
minimizer/lbfgsb.f
util/xml/XMLParserUtilities.cpp
util/xml/XMLWriterUtilities.cpp
)
# Include a resource file in the library.
QT4_ADD_RESOURCES(ResourceFiles resources/resources.qrc)
ADD_LIBRARY(PotFitLibrary STATIC ${SourceFiles} ${ResourceFiles})
SET_TARGET_PROPERTIES(PotFitLibrary PROPERTIES COMPILE_DEFINITIONS "${POTFIT_COMPILE_DEFINITIONS}")
# Link with the Qt libraries.
TARGET_LINK_LIBRARIES(PotFitLibrary ${QT_LIBRARIES})
# Enable OpenMP parallelization when using a GNU C++ compiler.
IF(CMAKE_COMPILER_IS_GNUCXX AND USE_OPENMP)
SET_TARGET_PROPERTIES(PotFitLibrary PROPERTIES COMPILE_FLAGS "-fopenmp")
SET_TARGET_PROPERTIES(PotFitLibrary PROPERTIES LINK_FLAGS "-fopenmp")
ENDIF(CMAKE_COMPILER_IS_GNUCXX AND USE_OPENMP)
的src /主/的CMakeLists.txt
# List of source files that need to be compiled:
SET(SourceFiles
Main.cpp
)
INCLUDE_DIRECTORIES([path to]/spglib-1.6.0/src)
INCLUDE_DIRECTORIES([path to]/spglib-1.6.0/src/.libs)
LINK_DIRECTORIES([path to]/spglib-1.6.0/src/.libs )
ADD_EXECUTABLE(PotFit ${SourceFiles})
SET_TARGET_PROPERTIES(PotFit PROPERTIES COMPILE_DEFINITIONS "${POTFIT_COMPILE_DEFINITIONS}")
TARGET_LINK_LIBRARIES(PotFit PotFitLibrary boost_timer boost_system)
set(CMAKE_PREFIX_PATH [path_to]/spglib-1.6.0/src/.libs)
find_library(SPGLIBRARY NAMES spg spglib libsymspg symspg PATHS [path_to]/spglib-1.6.0/src/.libs [path_to]/spglib-1.6.0/src)
target_link_libraries(PotFit "${SPGLIBRARY}")
message("The value of SPGLibrary is")
message("${SPGLIBRARY}")
MESSAGE("Spglib link flags: ${SPGLIB_LINK_FLAGS}")
MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
MESSAGE("cxx flags: ${CMAKE_CXX_FLAGS}")
MESSAGE("cxx linker flags: ${CMAKE_EXE_LINKER_FLAGS}")
MESSAGE("Library path is : ${CMAKE_LIBRARY_PATH}")
答案 0 :(得分:3)
添加到包含
extern "C"
{
#include "symspg.h" // or whatever
}