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.
Related
I'm trying to use CMake with a CUDA project of mine, but I'm having trouble getting it to build the executable when compiled on a system that has a CUDA-enabled device.
The CMakeLists.txt in question is below. It supports systems with and without CUDA-enabled devices, and builds just fine on my Macbook which doesn't have CUDA.
cmake_minimum_required (VERSION 2.8)
message(STATUS "CMake version: ${CMAKE_VERSION}")
project(stockModel)
# Grab the CUDA package
find_package(CUDA)
set(GPU_ACCELERATED ${CUDA_FOUND})
# Set directory and compilation flags for both g++ and nvcc
set(CMAKE_BINARY_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS}
-gencode arch=compute_50,code=sm_50; -std=c++11; -lcurand;"
)
set(CUDA_PROPAGATE_HOST_FLAGS off)
# Add directories
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/build/)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/core/)
if (${GPU_ACCELERATED})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/support/)
endif()
# Setup environments, depending on GPU accel. status
set(SRCS build/main.cpp core/callModels.cpp)
set(INCS core/callModels.h)
if (${GPU_ACCELERATED})
set(SRCS ${SRCS} support/prng.cu support/debugCFP.cu)
set(INCS ${INCS} support/prng.h support/debugCFP.h)
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/core/callModels.cpp
PROPERTIES CUDA_SOURCE_PROPERTY_FORMAT OBJ
)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}
-L/usr/local/cuda/lib64 -lcuda -lcudart"
)
endif()
# Create executable
message(STATUS "Sources: ${SRCS}")
message(STATUS "Includes: ${INCS}")
cuda_add_executable(stockModel ${SRCS} ${INCS})
The error I get when I attempt to build on my Jetson TX1 is as follows:
...
[ 80%] Building CXX object CMakeFiles/stockModel.dir/main.cpp.o
[100%] Linking CXX executable stockModel
c++: fatal error: no input files
compilation terminated.
...
Any ideas as to what is going wrong here? Obviously it has something to do with the CUDA 'extras', but I'm at a loss as to what is causing this.
Let me know if you need more details.
Here is the relevant part of the verbose output:
...
[100%] Linking CXX executable stockModel
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/stockModel.dir/link.txt --verbose=1
/usr/bin/c++ -std=c++11 -pthread
c++: fatal error: no input files
compilation terminated.
I've uploaded the full make VERBOSE=1 output to this gist on GitHub.
CMake is sometimes finicky about spaces and list combinations. I know that doesn't sound like much of an explanation, but I'm not much of an expert.
What you need to do is replace this:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}
-L/usr/local/cuda/lib64 -lcuda -lcudart"
with this:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/usr/local/cuda/lib64 -lcuda -lcudart")
(single line). That should do it. At least - it does on my system (I created dummy source files with your files' names to try this out).
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.
In my CMake project I set up compiler flags like this:
if (MSVC)
# Build cpp files on all cores
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W4")
# can't use the "secure" versions as they're Windows specific
add_definitions("/D\"_CRT_SECURE_NO_WARNINGS\"")
add_definitions("/D\"_SCL_SECURE_NO_WARNINGS\"")
add_definitions("/wd4290")
else()
# Enable C++11, you may need to use -std=c++0x if using an older gcc compiler
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-unused-parameter -fPIC -Wall -Weffc++ -pedantic")
endif()
endif()
To set the flags for MSVC, Clang and GCC. However in my source files var I have my source code and 3rd party things like gtest and gmock.
How can I set these flags such that they only apply to some subset of my source code?
E.g
# This should use the flags set above
SET(source
mycode/mysrc.cpp)
# This should not use the flags from above
SET(not_my_source
3rdparty/3rdparty.cpp)
# But both end up being part of the same executable
add_executable(Test ${source} ${not_my_source})
You may want to refer to here. You should be able to pass a list of files that you want to change the compiler flags for.
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
}
I have following toolchain for iPhone crosscompilation on mac os x:
# Platform Info
SET (CMAKE_SYSTEM_VERSION 1)
SET (CMAKE_SYSTEM_PROCESSOR arm)
# SDK Info
SET (SDKVER "3.0")
SET (DEVROOT "/Developer/Platforms/iPhoneOS.platform/Developer")
SET (SDKROOT "${DEVROOT}/SDKs/iPhoneOS${SDKVER}.sdk")
SET (CMAKE_OSX_SYSROOT "${SDKROOT}")
SET (CMAKE_OSX_ARCHITECTURES "armv6")
SET_PROPERTY(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
# C Compiler
SET (CMAKE_C_COMPILER "${DEVROOT}/usr/bin/arm-apple-darwin9-gcc-4.2.1")
#SET (LINK_FLAGS "-arch armv6 -arch armv7")
#SET (CMAKE_C_LINK_EXECUTABLE "${DEVROOT}/usr/bin/g++-4.2")
SET (CMAKE_C_FLAGS "-x objective-c")
SET (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -DDEBUG=1 -ggdb")
SET (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -DNDEBUG=1")
SET (CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS} -DNDEBUG=1 -ggdb")
# CXX Compiler
SET (CMAKE_CXX_COMPILER "${DEVROOT}/usr/bin/arm-apple-darwin9-g++-4.2.1")
SET (CMAKE_CXX_FLAGS "-x objective-c++")
SET (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -DDEBUG=1 -ggdb")
SET (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG=1")
SET (CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG=1 -ggdb")
# Definitions
#ADD_DEFINITIONS("-arch armv6")
#ADD_DEFINITIONS("-arch armv7")
ADD_DEFINITIONS("-pipe")
ADD_DEFINITIONS("-no-cpp-precomp")
ADD_DEFINITIONS("--sysroot=${SDKROOT}")
ADD_DEFINITIONS("-miphoneos-version-min=${SDKVER}")
# System Includes
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/usr/include")
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/usr/include/c++/4.2.1")
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/usr/include/c++/4.2.1/armv6-apple-darwin9")
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/opt/iphone-${SDKVER}/include")
INCLUDE_DIRECTORIES(SYSTEM "${SDKROOT}/usr/local/iphone-${SDKVER}/include")
# System Libraries
LINK_DIRECTORIES("${SDKROOT}/usr/lib")
LINK_DIRECTORIES("${SDKROOT}/usr/lib/gcc/arm-apple-darwin9/4.2.1/")
#LINK_DIRECTORIES("${SDKROOT}/opt/iphone-${SDKVER}/lib")
#LINK_DIRECTORIES("${SDKROOT}/usr/local/iphone-${SDKVER}/lib")
# Root Paths
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "/opt/iphone-${SDKVER}/" "/usr/local/iphone-${SDKVER}/")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# CMake Parameters
SET (iPhone 1)
SET (iPhoneOS 1)
SET (iPhoneOS_VERSION ${SDKVER})
SET (CMAKE_CROSSCOMPILING 1)
#SET_TARGET_PROPERTIES(p3dm PROPERTIES LINK_FLAGS "-arch armv6 -arch armv7")
# HELPERS
#---------
MACRO(ADD_FRAMEWORK appname fwname)
find_library(FRAMEWORK_${fwname}
NAMES ${fwname}
PATHS ${SDKROOT}/System/Library
PATH_SUFFIXES Frameworks
NO_DEFAULT_PATH)
if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
MESSAGE(ERROR ": Framework ${fwname} not found")
else()
TARGET_LINK_LIBRARIES(${appname} ${FRAMEWORK_${fwname}})
MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")
endif()
endmacro(ADD_FRAMEWORK)
And i use following CMakeLists.txt:
# PROJECT PARAMETERS
#--------------------
SET(APP_NAME p3dm)
PROJECT(${APP_NAME})
# SOURCE CODE
#-------------
SET(CMAKE_CXX_FLAGS "-x objective-c++")
INCLUDE_DIRECTORIES(SYSTEM ../inc/ ../xsrc/)
FILE(GLOB headers ../src/*.h ../xsrc/*.h)
FILE(GLOB sources ../src/*.cpp ../xsrc/*.c ../xsrc/*.cpp)
#set_source_files_properties(${sources} PROPERTIES LANGUAGE C )
# EXECUTABLE
#------------
SET(MACOSX_BUNDLE_GUI_IDENTIFIER "org.reversity.${APPNAME}")
SET(APP_TYPE MACOSX_BUNDLE)
ADD_EXECUTABLE(${APP_NAME} ${APP_TYPE} ${headers} ${sources})
SET_TARGET_PROPERTIES(${APP_NAME} PROPERTIES XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer: Mario Hros")
# FRAMEWORKS
#------------
ADD_FRAMEWORK(${APP_NAME} UIKit)
I use following compilation bash script:
#!/bin/bash
unset CPATH
unset C_INCLUDE_PATH
unset CPLUS_INCLUDE_PATH
unset OBJC_INCLUDE_PATH
unset LIBS
unset DYLD_FALLBACK_LIBRARY_PATH
unset DYLD_FALLBACK_FRAMEWORK_PATH
export SDKVER="3.0"
export DEVROOT="/Developer/Platforms/iPhoneOS.platform/Developer"
export SDKROOT="$DEVROOT/SDKs/iPhoneOS$SDKVER.sdk"
export PKG_CONFIG_PATH="$SDROOT/usr/lib/pkgconfig":"/opt/iphone-$SDKVER/lib/pkgconfig":"/usr/local/iphone-$SDKVER/lib/pkgconfig"
export PKG_CONFIG_LIBDIR="$PKG_CONFIG_PATH"
export MAINFOLDER=`pwd`
cmake . \
-DCMAKE_TOOLCHAIN_FILE="$MAINFOLDER/cmake/iphone-$SDKVER.toolchain" \
-DCMAKE_INSTALL_PREFIX="/opt/iphone-$SDKVER" \
"$#"
The problem is, that it uses CMAKE_CXX_FLAGS also in linker. Compilation is fine. Linking looks fine, it adds correct -framework flags, but also adds CMAKE_CXX_FLAGS (which are -x objective-c++) so instead of linking object files compiled previously it behaves like compiling objective c++ (-x objective-c++) and it is impossible to link these objects.
I am getting errors like
ComponentManager.cpp.o:20: error: stray '\341' in program
Don't you know what I am doing wrong?
You can set the LINKER_LANGUAGE to C to force CMake to use the CMAKE_C_FLAGS for the linker. Check it out here.
I've solved this problem by removing CMAKE_CXX_FLAGS and CMAKE_C_FLAGS from the toolchain file and adding ADD_DEFINITIONS("-x objective-c++") to CMakeLists.txt.
That way -x objective-c++ flags get passed only to the compiler (not linker) and only for my source code (not cmake test compilation which happens before building my target).
The link command line is set in Modules/CMake{C,CXX,Fortran}Information.cmake and defaults to using the compiler and its compilation flags (see source code). This can be changed by replacing the rule that builds the link command line, which lives in variables CMAKE_CXX_LINK_EXECUTABLE (and friends). That variable does not give the linker executable; it says how to link an executable!
One solution is to set a modified form of that rule that avoids the use of CXX flags, e.g.
cmake -DCMAKE_CXX_LINK_EXECUTABLE="<CMAKE_CXX_COMPILER> <FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
However, you can avoid the problem by not setting CMAKE_CXX_FLAGS in the first place, but rather adding COMPILE_FLAGS property to the target.