I'm using cmake verison 2.8.11.2 to build a project using some external libraries and packages. However since I tried adding the library spglib I have been unable to compile the code. Despite CMake adding the correct .so file the resulting makefile does not correctly link to it.
I use the following CMake code in src/main/CMakeLists.txt to include the spglib .so file:
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}")
Which seems to work. I check that CMake actually finds the library using
message("The value of SPGLibrary is")
message("${SPGLIBRARY}")
which correctly returns the path to libsymspg.so. However the compiler returns the error
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 ***
I make sure that the libsymspg.so does contain this symbol by using
nm libsymspg.so | grep get_spacegroup_type
which returns
0000ad30 T spgdb_get_spacegroup_type
0000c240 T spg_get_spacegroup_type
So between Cmake and linking something is wrong. As far as I know I am using the "normal" way of doing things, so I am not sure where to begin looking for what is causing this problem. I have appended all whole CMakeLists.txt below since that might be useful and I can add the CMakeCache if needed (it's p. long...).
Full Cmake source
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/main/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}")
Add to the include
extern "C"
{
#include "symspg.h" // or whatever
}
Related
When trying to compile my project using the toolchain provided by the manufacturer of the hardware I'm developing for, compilation succeeds, however linking fails with the following error messages:
/media/xxx/Data/toolchains/sysroots/x86_64-xxx-linux/usr/bin/arm-xxx-linux-gnueabi/../../libexec/arm-xxx-linux-gnueabi/gcc/arm-xxx-linux-gnueabi/4.8.4/ld: cannot find -latomic
/media/xxx/Data/toolchains/sysroots/x86_64-xxx-linux/usr/bin/arm-xxx-linux-gnueabi/../../libexec/arm-xxx-linux-gnueabi/gcc/arm-xxx-linux-gnueabi/4.8.4/ld: cannot find -lstdc++
However, when building a small test program using the same compiler and linker, everything works.
Below is an excerpt of the important parts of my CMake toolchain file:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
###
# Get $CROSS
###
if (NOT $ENV{CROSS_COMPILE} STREQUAL "")
set(cross $ENV{CROSS_COMPILE}) # WARNING: Ends with a - (minus)
else()
set(cross "arm-xxx-linux-gnueabi-")
endif()
###
# Set CMake sysroot
###
set(CMAKE_SYSROOT $ENV{SDKTARGETSYSROOT})
set(CMAKE_SYSROOT_LINK $ENV{SDKTARGETSYSROOT})
set(CMAKE_SYSROOT_COMPILE $ENV{SDKTARGETSYSROOT})
set(CMAKE_C_COMPILER $ENV{TOOLCHAIN_TOOLSDIR}/${cross}gcc)
set(CMAKE_CXX_COMPILER $ENV{TOOLCHAIN_TOOLSDIR}/${cross}g++)
set(CMAKE_LD $ENV{TOOLCHAIN_TOOLSDIR}/${cross}ld)
set(CMAKE_STRIP $ENV{TOOLCHAIN_TOOLSDIR}/${cross}strip)
set(CMAKE_AR $ENV{TOOLCHAIN_TOOLSDIR}/${cross}ar)
include_directories($ENV{SDKTARGETSYSROOT}/usr/include)
I'm not at liberty to disclose source code, but the source code isn't the issue here as it compiles correctly.
Here's another MWE of the CMakeLists.txt file:
cmake_minimum_required(VERSION 3.10)
project(xxx LANGUAGES CXX VERSION 2.0.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(TARGET_NAME xxx.bin)
include_directories(
include/
${INCLUDE_DIRS}
)
file(GLOB_RECURSE FILES ${CMAKE_CURRENT_SOURCE_DIR} FOLLOW_SYMLINKS src/*.cpp)
if (xxx_DEBUG)
add_compile_options(
-Wpedantic
-DDDC_STUB
-fabi-version=6
-Wno-format-security
-Wno-reorder
-ggdb3
-O0
-fpermissive # Test
-fPIC
#-static-libstdc++ # with or without, doesn't change the behaviour
#-static-libgcc # with or without, doesn't change the behaviour
)
else()
add_compile_options(
-Wpedantic
-fabi-version=6
-Wno-format-security
-Wno-reorder
-O3
-fpermissive # Test
-fPIC
#-static-libstdc++ # with or without, doesn't change the behaviour
#-static-libgcc # with or without, doesn't change the behaviour
)
endif()
add_executable(${TARGET_NAME} ${FILES} ${MEMWATCH_FILES})
I've tried setting the sysroot-argument for ld, I've tried manually specifying the link (search) path -L$ENV{SDKTARGETSYSROOT}/usr/lib/.debug, and I've also tried hard-wiring the path to the library in question: $ENV{SDKTARGETSYSROOT}/usr/lib/.debug/libatomic.so.1.0.0
Is there another way I can tell ld what libraries to use?
This works perfectly with standard toolchains!
EDIT:
I've now also tried brute-forcing it by creating a symlink from the .debug/libatomic to usr/lib/libatomic. That also hasn't had the desired effect.
I installed the bwapi via wine on Mac OSX. And I try to compile the ExampleAIModule in it with CMake and MinGW on Mac OSX. The ExampleAIModule is actually a VS2017 project, I write a CMakeLists.txt, ran cmake CMakeLists.txt && make VERBOSE=1 got some errors. I want to know how to fix my CMakeLists.txt?
The folder structure:
BWAPI/ExampleAIModule/CMakeLists.txt
BWAPI/ExampleAIModule/Source/*.cpp *.h
BWAPI/include/*.h
BWAPI/lib/BWAPI.lib
BWAPI/lib/BWAPIClient.lib
make got errors:
Linking CXX shared library libExampleAIModule.dylib
/usr/local/Cellar/cmake/3.2.2/bin/cmake -E cmake_link_script CMakeFiles/ExampleAIModule.dir/link.txt --verbose=1
i686-w64-mingw32-g++ -std=c++11 -O3 -DNDEBUG -dynamiclib -Wl,-headerpad_max_install_names -o libExampleAIModule.dylib -install_name #rpath/libExampleAIModule.dylib CMakeFiles/ExampleAIModule.dir/Source/Dll.cpp.o CMakeFiles/ExampleAIModule.dir/Source/ExampleAIModule.cpp.o -L/.wine/drive_c/Starcraft/BWAPI/ExampleAIModule/../lib
i686-w64-mingw32-g++: error: rpath/libExampleAIModule.dylib: No such file or directory
i686-w64-mingw32-g++: error: unrecognized command line option ‘-install_name’
make[2]: *** [libExampleAIModule.dylib] Error 1
make[1]: *** [CMakeFiles/ExampleAIModule.dir/all] Error 2
CMakeLists.txt
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
################### Variables. ####################
# Change if you want modify path or other values. #
###################################################
set(PROJECT_NAME ExampleAIModule)
# Output Variables
# Folders files
set(CPP_DIR_1 Source)
set(HEADER_DIR_1 Source)
############## Define Project. ###############
# ---- This the main options of project ---- #
##############################################
project(${PROJECT_NAME} CXX)
# Define Release by default.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
message(STATUS "Build type not specified: defaulting to release.")
endif(NOT CMAKE_BUILD_TYPE)
# Definition of Macros
add_definitions(
-DNOMINMAX
-D_DEBUG
-D_WINDOWS
-D_USRDLL
-DEXAMPLEAIMODULE_EXPORTS
-DUNICODE
-D_UNICODE
)
################# Flags ################
# Defines Flags for Windows and Linux. #
########################################
if(MSVC)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /EHsc")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /EHsc")
endif(MSVC)
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif(NOT MSVC)
########### Add by me #############
SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
include_directories(../include)
link_directories(../lib)
################ Files ################
# -- Add files to project. -- #
#######################################
file(GLOB SRC_FILES
${CPP_DIR_1}/*.cpp
${HEADER_DIR_1}/*.h
)
# Add library to build.
add_library(${PROJECT_NAME} SHARED
${SRC_FILES}
)
CMake always use toolchains to compile for a specific platform/target, as mentioned here. However, for cross-compilation, you need to specify the toolchain file it needs to use. This is done using the CMAKE_TOOLCHAIN_FILE variable, as explained here.
The parameters related to the compilation (such as the system name, processor, compiler, etc.) on the target platform shouldn't be in the CMakeLists.txt file where you defined your project (using the project function).
Instead, you're supposed to set the compilers and other parameters related to cross-compilation in a toolchain file. And you may have a toolchain file for each platform you like to cross-compile for.
This is how your toolchain file may look like, assuming that the compilers are in the path:
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
SET(CMAKE_C_COMPILER i686-w64-mingw32-gcc)
SET(CMAKE_CXX_COMPILER i686-w64-mingw32-g++)
If your toolchain file has the path /toolchains/windows.cmake, you need to pass -DCMAKE_TOOLCHAIN_FILE=/toolchains/windows.cmake to cmake.
This design keeps your project's CMakeLists.txt file toolchain-agnostic.
I have a cmake project where I want to add a class containing the matlab engine. For compiling it I need to include two libraries eng and mx, which I do by adding
target_link_libraries( ${TARGET} /usr/local/MATLAB/R2013b/bin/glnxa64/libeng.so)
target_link_libraries( ${TARGET} /usr/local/MATLAB/R2013b/bin/glnxa64/libmx.so)
to my CMakeLists.txt file.
However there are also lots of other old versions of libraries in /usr/local/MATLAB/R2013b/bin/glnxa64/, which seem
to be automatically added to the path as well when calling the above command. I think this causes the compiler to not find my
normal libraries anymore and produces an error.
How can I include only the two above libraries, and not all the others in the glnxa64 folder?
The warning shown after running cmake . :
CMake Warning at CMakeLists.txt:23 (add_executable):
Cannot generate a safe runtime search path for target CCDWidget because
files in some directories may conflict with libraries in implicit
directories:
runtime library [libboost_program_options.so.1.49.0] in /usr/lib may be hidden by files in:
/usr/local/MATLAB/R2013b/bin/glnxa64
runtime library [libboost_system.so.1.49.0] in /usr/lib may be hidden by files in:
/usr/local/MATLAB/R2013b/bin/glnxa64
runtime library [libboost_filesystem.so.1.49.0] in /usr/lib may be hidden by files in:
/usr/local/MATLAB/R2013b/bin/glnxa64
runtime library [libboost_regex.so.1.49.0] in /usr/lib may be hidden by files in:
/usr/local/MATLAB/R2013b/bin/glnxa64
Some of these libraries may not be found correctly.
And the error message during linking:
Linking CXX executable CCDWidget
/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0: undefined reference to `FT_Face_GetCharVariantIndex'
/usr/lib/x86_64-linux-gnu/libharfbuzz.so.0: undefined reference to `FT_Get_Advance'
collect2: error: ld returned 1 exit status
make[2]: *** [CCDWidget] Error 1
make[1]: *** [CMakeFiles/CCDWidget.dir/all] Error 2
make: *** [all] Error 2
Below is my full CMakeLists.txt file. Lines commented out with two ## are alternatives that I tried before and didn't solve my problem.
I also added LINK_PRIVATE to the target_link_libraries command as shown in the code below, which didn't make a difference.
The option PRIVATE alone seems to be not accepted by my cmake version, as it changed the error meassage to
/usr/bin/ld: cannot find -lPRIVATE
collect2: error: ld returned 1 exit status
When the #eng line is commented out, the compilation and linking works without errors
(when calling the matlab engine is also commented out in Readout.cpp), so the error must be produced by that line.
#Specify the version being used as well as the language
cmake_minimum_required(VERSION 2.6)
##cmake_policy(SET CMP0003 NEW)
#Name your project here
project(CCDWidget)
set(TARGET CCDWidget)
set(MAIN_SOURCES CCDWidget.cpp main.cc CCDControl.cpp VideoWindow.cpp ImageWindow.cpp ThisMeasurement.cpp KineticSeries.cpp FastKinetics.cpp Readout.cpp)
##SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
#set_source_files_properties(Readout.cpp PROPERTIES COMPILE_FLAGS "-I/usr/local/MATLAB/R2013b/extern/include -I/usr/local/MATLAB/R2013b/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE -I/usr/local/MATLAB/R2013b/extern/include/cpp -I/usr/local/MATLAB/R2013b/extern/include -DGLNXA64 -DGCC -DMX_COMPAT_32 -DNDEBUG -Wno-effc++")
find_package(Boost COMPONENTS program_options system filesystem regex REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GTKMM gtkmm-3.0)
include_directories( ${GTKMM_INCLUDE_DIRS} )
include_directories( ${Boost_INCLUDE_DIR} )
include_directories( ${PROJECT_SOURCE_DIR} )
##link_directories(/usr/local/MATLAB/R2013b/bin/glnxa64)
##target_link_libraries( ${TARGET} eng)
##target_link_libraries( ${TARGET} mx)
set(CMAKE_CXX_FLAGS "--std=c++11")
add_executable( ${TARGET} ${MAIN_SOURCES} )
target_link_libraries( ${TARGET} ${GTKMM_LIBRARIES} )
target_link_libraries( ${TARGET} ${Boost_LIBRARIES} )
target_link_libraries( ${TARGET} LINK_PRIVATE /usr/local/MATLAB/R2013b/bin/glnxa64/libeng.so) # eng
#target_link_libraries( ${TARGET} LINK_PRIVATE /usr/local/MATLAB/R2013b/bin/glnxa64/libmx.so ) # mx
target_link_libraries( ${TARGET} andor )
You could try using an imported target:
add_library(eng SHARED IMPORTED)
set_property(TARGET eng PROPERTY IMPORTED_LOCATION /usr/local/MATLAB/R2013b/bin/glnxa64/libeng.so)
...
add_executable( ${TARGET} ${MAIN_SOURCES} )
...
target_link_libraries(${TARGET} eng)
For debugging you could try to build with "make VERBOSE=1".
This will show you the used gcc command line.
CMake probably transforms your target_link_libraries command to something like:
g++ ... -L/usr/local/MATLAB/R2013b/bin/glnxa64 -leng ...
gcc then finds some boost libraries in this folder.
I was able to successfully configure and generate the build folder (KinectSLAM6D/build.). However, when I try to build it using make, I got an error saying gsl is not found. I am pretty sure this is just a configuration issue as I have gsl installed (they're in usr/local), but I am unable to configure it. I have tried adding the following lines to CMakeList:
include_directories(${GSL_INCLUDE_DIRS} ${GSLCBLAS_INCLUDE_DIRS})
set(LIBS ${LIBS} ${GSL_LIBRARIES} ${GSLCBLAS_LIBRARIES})
I have copied the pertinent output below. I have found a couple of answers to compiling with gsl (adding -lgsl). However, I have no clue where to put that in CMakeLists or the generated MakeList and MakeList2 files.
Here's the generated output.
....
[ 44%] Building CXX object CMakeFiles/Kinect6DSLAM.dir/src/GraphOptimizer_G2O.cpp.o
[ 45%] Building CXX object CMakeFiles/Kinect6DSLAM.dir/src/CKinect2DRawlog.cpp.o
Linking CXX executable Kinect6DSLAM
/usr/bin/ld: warning: libopencv_core.so.2.3, needed by /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libmrpt-base.so, may conflict with libopencv_core.so.2.4
/usr/bin/ld: warning: libopencv_imgproc.so.2.3, needed by /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libmrpt-base.so, may conflict with libopencv_imgproc.so.2.4
/usr/bin/ld: warning: libopencv_highgui.so.2.3, needed by /usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../lib/libmrpt-base.so, may conflict with libopencv_highgui.so.2.4
../gicp/libgicp.a(gicp.o): In function `dgc::gicp::GICPPointSet::ComputeMatrices()':
gicp.cpp:(.text+0x462): undefined reference to `gsl_vector_alloc'
gicp.cpp:(.text+0x470): undefined reference to `gsl_vector_alloc'
... a bunch more undefined references to gsl
collect2: ld returned 1 exit status
make[2]: *** [Kinect6DSLAM] Error 1
make[1]: *** [CMakeFiles/Kinect6DSLAM.dir/all] Error 2
make: *** [all] Error 2
This if the full CMakeList.txt. I am trying to run Miguel Algaba's SLAM project.
PROJECT(KinectSLAM6D)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW) # Required by CMake 2.7+
endif(COMMAND cmake_policy)
# Set the output directory for the build executables
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/build)
#Add here your project dependencies
FIND_PACKAGE(MRPT REQUIRED hwdrivers maps graphslam) #Add here your project dependencies
FIND_PACKAGE(PCL REQUIRED)
FIND_PACKAGE(OpenCV REQUIRED )
INCLUDE_DIRECTORIES(${PCL_INCLUDE_DIRS})
LINK_DIRECTORIES(${PCL_LIBRARY_DIRS})
ADD_DEFINITIONS(${PCL_DEFINITIONS})
# Required by StanfordGICP
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
FIND_PACKAGE(GSL REQUIRED)
include_directories(${GSL_INCLUDE_DIRS} ${GSLCBLAS_INCLUDE_DIRS})
set(LIBS ${LIBS} ${GSL_LIBRARIES} ${GSLCBLAS_LIBRARIES})
FIND_PACKAGE(Boost COMPONENTS system program_options REQUIRED)
include_directories(${PROJECT_SOURCE_DIR}/gicp)
include_directories(${PROJECT_SOURCE_DIR}/gicp/ann_1.1.1/include/ANN)
# G2O library
# Set up the top-level include directories
SET( G2O_INCLUDE ${PROJECT_SOURCE_DIR}/EXTERNAL/g2o CACHE PATH "Directory of G2O")
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR} ${G2O_INCLUDE})
# Add g2o lib dir
LINK_DIRECTORIES( ${LINK_DIRECTORIES} "${G2O_INCLUDE}/lib" )
#Generate config.h
configure_file(g2o/trunk/config.h.in ${PROJECT_BINARY_DIR}/g2o/config.h)
include_directories(${PROJECT_BINARY_DIR})
INSTALL(FILES ${PROJECT_BINARY_DIR}/g2o/config.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include/g2o)
# Include the subdirectories
ADD_SUBDIRECTORY(g2o/trunk)
INCLUDE_DIRECTORIES(${CSPARSE_INCLUDE_DIR}) #You can use CPARSE or CHOLMOD
INCLUDE_DIRECTORIES(${CHOLMOD_INCLUDE_DIR})
set(G2O_DIR ${PROJECT_SOURCE_DIR}/g2o/trunk)
include_directories(${G2O_DIR})
link_directories(${G2O_DIR}/lib)
# Declare the target (an executable)
ADD_EXECUTABLE(Kinect6DSLAM kinect6DSLAM.cpp
./include/KinectGrabber.h
./include/KinectGrabber_OpenNI.h
./src/KinectGrabber_OpenNI.cpp
./include/KinectGrabber_Rawlog.h
./src/KinectGrabber_Rawlog.cpp
./include/KinectGrabber_Rawlog2.h
./src/KinectGrabber_Rawlog2.cpp
./include/KinectGrabber_MRPT.h
./src/KinectGrabber_MRPT.cpp
./include/VisualFeatureDescriptorExtractor.h
./include/VisualFeatureDescriptorExtractor_SURF_GPU.h
./include/VisualFeatureDescriptorExtractor_Generic.h
./include/VisualFeatureDescriptorExtractor_ORB.h
./include/VisualFeatureMatcher.h
./include/VisualFeatureMatcher_Generic.h
./include/PointCloudViewer.h
./include/PointCloudViewer_MRPT.h
./src/VisualFeatureDescriptorExtractor_SURF_GPU.cpp
./src/VisualFeatureDescriptorExtractor_Generic.cpp
./src/VisualFeatureDescriptorExtractor_ORB.cpp
./src/VisualFeatureMatcher_Generic.cpp
./src/PointCloudViewer_MRPT.cpp
./include/Visual3DRigidTransformationEstimator.h
./include/Visual3DRigidTransformationEstimator_SVD.h
./src/Visual3DRigidTransformationEstimator_SVD.cpp
./include/Visual3DRigidTransformationEstimator_RANSAC.h
./src/Visual3DRigidTransformationEstimator_RANSAC.cpp
./include/ICPPoseRefiner.h
./include/ICPPoseRefiner_PCL.h
./src/ICPPoseRefiner_PCL.cpp
./include/ICPPoseRefiner_StanfordGICP.h
./src/ICPPoseRefiner_StanfordGICP.cpp
./include/Miscellaneous.h
./src/Miscellaneous.cpp
./include/FrameRGBD.h
./src/FrameRGBD.cpp
./include/PointCloudDownsampler.h
./src/PointCloudDownsampler.cpp
./include/KeyframeLoopDetector.h
./src/KeyframeLoopDetector.cpp
./include/GraphOptimizer.h
./include/GraphOptimizer_MRPT.h
./src/GraphOptimizer_MRPT.cpp
./include/GraphOptimizer_G2O.h
./src/GraphOptimizer_G2O.cpp
./include/CKinect2DRawlog.h
./src/CKinect2DRawlog.cpp
)
TARGET_LINK_LIBRARIES(Kinect6DSLAM ${MRPT_LIBS}
${PCL_LIBRARIES}
${OpenCV_LIBS}
${Boost_LIBRARIES}
#GICP
${GSL_LIBRARIES}
${PROJECT_SOURCE_DIR}/gicp/ann_1.1.1/lib/libANN.a
${PROJECT_SOURCE_DIR}/gicp/libgicp.a
#G2O
core math_groups types_slam3d
solver_csparse #You can use CPARSE or CHOLMOD
solver_cholmod ${CHOLMOD_LIBRARIES}
)
# Declare the target (an executable)
ADD_EXECUTABLE(PairwiseAlignmentSteps PairwiseAlignmentSteps.cpp
./include/KinectGrabber.h
./include/KinectGrabber_OpenNI.h
./src/KinectGrabber_OpenNI.cpp
./include/KinectGrabber_Rawlog.h
./src/KinectGrabber_Rawlog.cpp
./include/KinectGrabber_MRPT.h
./src/KinectGrabber_MRPT.cpp
./include/VisualFeatureDescriptorExtractor.h
./include/VisualFeatureDescriptorExtractor_SURF_GPU.h
./include/VisualFeatureDescriptorExtractor_Generic.h
./include/VisualFeatureDescriptorExtractor_ORB.h
./include/VisualFeatureMatcher.h
./include/VisualFeatureMatcher_Generic.h
./include/PointCloudViewer.h
./include/PointCloudViewer_MRPT.h
./src/VisualFeatureDescriptorExtractor_SURF_GPU.cpp
./src/VisualFeatureDescriptorExtractor_Generic.cpp
./src/VisualFeatureDescriptorExtractor_ORB.cpp
./src/VisualFeatureMatcher_Generic.cpp
./src/PointCloudViewer_MRPT.cpp
./include/Visual3DRigidTransformationEstimator.h
./include/Visual3DRigidTransformationEstimator_SVD.h
./src/Visual3DRigidTransformationEstimator_SVD.cpp
./include/Visual3DRigidTransformationEstimator_RANSAC.h
./src/Visual3DRigidTransformationEstimator_RANSAC.cpp
./include/ICPPoseRefiner.h
./include/ICPPoseRefiner_PCL.h
./src/ICPPoseRefiner_PCL.cpp
./include/ICPPoseRefiner_StanfordGICP.h
./src/ICPPoseRefiner_StanfordGICP.cpp
./include/Miscellaneous.h
./src/Miscellaneous.cpp
./include/FrameRGBD.h
./src/FrameRGBD.cpp
./include/PointCloudDownsampler.h
./src/PointCloudDownsampler.cpp
)
TARGET_LINK_LIBRARIES(PairwiseAlignmentSteps ${MRPT_LIBS}
${PCL_LIBRARIES}
${OpenCV_LIBS}
${Boost_LIBRARIES}
#GICP
${GSL_LIBRARIES}
${PROJECT_SOURCE_DIR}/gicp/ann_1.1.1/lib/libANN.a
${PROJECT_SOURCE_DIR}/gicp/libgicp.a
)
# Set optimized building:
IF(CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_BUILD_TYPE MATCHES "Debug")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -mtune=native")
ENDIF(CMAKE_COMPILER_IS_GNUCXX AND NOT CMAKE_BUILD_TYPE MATCHES "Debug")
target_link_libraries(Kinect6DSLAM ${LIBS})
Something tells me, that adding target_link_libraries(Kinect6DSLAM ${LIBS}) will help you.
Also, instead of constructs like
set(VAR ${VAR} somethingelse)
you can use this:
list(APPEND VAR somethingelse)
Here is my compiler part of my config:
IF(UNIX)
## Compiler flags
# specify the cross compiler
SET(CMAKE_C_COMPILER /home/username/projects/buildroot/output/host/usr/bin/arm-linux-gcc)
SET(CMAKE_CXX_COMPILER /home/username/projects/buildroot/output/host/usr/bin/arm-linux-g++)
if(CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "-O3")
set(CMAKE_EXE_LINKER_FLAGS "-lsqlite3 -lrt -lpthread")
endif()
target_link_libraries(complex
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY})
ENDIF(UNIX)
There are 3 problems : -lsqlite3 -lrt -lpthread
How must I to make them for my architecture and specify here? How to set (using set?) the path of compiled libraries after I will get them recompiled for my architecture somehow?
If you want to do cross-compilation with CMake you really should use a toolchain file for that. See the CMake Wiki for an introduction. In order to use third-party libraries (i.e. not included by the cross-compilation toolchain) you need to cross-compile them too.
Edit: Since you are using the buildroot toolchain, you can use the already included CMake toolchain file. Just pass -DCMAKE_TOOLCHAIN_FILE=/home/username/projects/buildroot/output/toolchainfile.cmake when invoking CMake. No need to set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER in your CMakeLists.txt file. Also, setting CMAKE_CXX_FLAGS and CMAKE_EXE_LINKER_FLAGS is considered to be very bad practice.
Presumably you have built sqlite3 while building the buildroot toolchain, so you can use it just like any other library. I.e:
find_path(SQLITE3_INCLUDE_DIR sqlite3.h)
find_library(SQLITE3_LIBRARY sqlite3)
if(NOT SQLITE3_INCLUDE_DIR)
message(SEND_ERROR "Failed to find sqlite3.h")
endif()
if(NOT SQLITE3_LIBRARY)
message(SEND_ERROR "Failed to find the sqlite3 library")
endif()
find_package(Threads REQUIRED)
# ...
target_link_libraries(complex
${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${SQLITE3_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
rt)
Lastly, do not set CMAKE_CXX_FLAGS to -O3. The user should pass -DCMAKE_BUILD_TYPE=Release when configuring the project instead.
You'll have to cross-compile the dependencies as well. The path depends on where you install them.
Btw., using -lpthread is not the safe way of getting POSIX threads. You should give the option -pthread to both the compiler and the linker.