cross compile dll on mac OSX with cmake and mingw - c++

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.

Related

C++: Problem with M1 architecture in cmake: how do I change the architecture?

I am trying to run cmake command in the new environment.
Upon running cmake . . I get clang: error: the clang compiler does not support '-march=core2' error. I tried to run it with cmake '-DCMAKE_CXX_FLAGS='-march=x86-64'' flag, and it changed the march for a while but only in CLion IDE and only when I was doing that continuously. I can't seem to make it work in the terminal while reading different makefile.
Full error when I run either cmake or ```cmake '-DCMAKE_CXX_FLAGS='-march=x86-64'':
Determining if the C compiler works failed with the following output:
Change Dir: /Users/marcin/CLionProjects/pythontest5/CMakeFiles/CMakeTmp
Run Build Command(s):/Library/Developer/CommandLineTools/usr/bin/make -f Makefile cmTC_925c1/fast && /Library/Developer/CommandLineTools/usr/bin/make -f CMakeFiles/cmTC_925c1.dir/build.make CMakeFiles/cmTC_925c1.dir/build
Building C object CMakeFiles/cmTC_925c1.dir/testCCompiler.c.o
/Library/Developer/CommandLineTools/usr/bin/gcc -march=core2 -mtune=haswell -mssse3 -ftree-vectorize -fPIC -fPIE -fstack-protector-strong -O2 -pipe -isystem /opt/homebrew/anaconda3/include -arch arm64 -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -MD -MT CMakeFiles/cmTC_925c1.dir/testCCompiler.c.o -MF CMakeFiles/cmTC_925c1.dir/testCCompiler.c.o.d -o CMakeFiles/cmTC_925c1.dir/testCCompiler.c.o -c /Users/marcin/CLionProjects/pythontest5/CMakeFiles/CMakeTmp/testCCompiler.c
clang: error: the clang compiler does not support '-march=core2'
make[1]: *** [CMakeFiles/cmTC_925c1.dir/testCCompiler.c.o] Error 1
make: *** [cmTC_925c1/fast] Error 2
My CMakeLists.txt
cmake_minimum_required(VERSION 3.1)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
project(automobile VERSION 0.1.0)
# Include dir
include_directories(/usr/local/include)
# Src
AUX_SOURCE_DIRECTORY(src SRC_FILES)
# Headers
set(PROJECT_SOURCE_DIR "src")
set(PROJECT_INCLUDE_DIR "include/automobile_bits")
# Source files
set(SOURCE_FILES
${PROJECT_INCLUDE_DIR}/motorcycle.hpp
${PROJECT_SOURCE_DIR}/motorcycle.cpp
)
# Set up such that XCode organizes the files correctly
source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${SOURCE_FILES})
# Add library
add_library(automobile SHARED ${SOURCE_FILES})
# Include directories
target_include_directories(automobile PRIVATE include/automobile_bits)
# Install
install(TARGETS automobile DESTINATION lib)
# Install the headers
install(FILES include/automobile DESTINATION include)
# Create base directory
install(DIRECTORY include/automobile_bits DESTINATION include)
It's unclear where cmake gets -march=core2 from. Try to remove CMakeCache.txt then re-run cmake ..
If it does not help, try to remove CMakeCache.txt and run cmake . -DCMAKE_OSX_ARCHITECTURES=arm64.

Compiling Chaiscript with i686-w64-mingw32-g++ fails

I am trying to compile a simple chaiscript example for windows from Linux using the i686-w64-mingw32-g++ compiler. I have already gotten it to work with g++, but when compiling my app using the command
i686-w64-mingw32-g++ ./main.cpp -pthread -L/lib/x86_64-linux-gnu/libdl.a -std=c++17
And here are the contents of main.cpp
#include "chaiscript/chaiscript.hpp"
#include "chaiscript/chaiscript_stdlib.hpp"
int main()
{
chaiscript::ChaiScript chai;
chai.eval(R"(puts("Hello"))");
}
This is the error it gives me
How do I fix this error so I can compile my code?
Edit:
I was able to get farther along by using x86_64-w64-mingw32-g++ instead of i686-w64-mingw32-g++, but now I am getting this error:
/usr/bin/x86_64-w64-mingw32-as: /tmp/ccE1ZcKe.o: too many sections (73147)
/tmp/ccwlaMBb.s: Assembler messages:
/tmp/ccwlaMBb.s: Fatal error: can't write 41 bytes to section .text of /tmp/ccE1ZcKe.o: 'file too big'
/usr/bin/x86_64-w64-mingw32-as: /tmp/ccE1ZcKe.o: too many sections (73147)
/tmp/ccwlaMBb.s: Fatal error: can't close /tmp/ccE1ZcKe.o: file too big
Here is the solution using cmake:
First make a toolchain file:
# the name of the target operating system
set(CMAKE_SYSTEM_NAME Windows)
# which compilers to use
set(CMAKE_C_COMPILER x86_64-w64-mingw32-g++)
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32)
# adjust the default behavior of the find commands:
# search headers and libraries in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
# search programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
The next step is to make the actual CMakeLists.txt:
# set minimum cmake version
cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# project name and language
project(HelloWorld LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(GNUInstallDirs)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
# define executable and its source file
add_executable(HelloWorld main.cpp)
if("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows")
add_definitions(-O3)
SET(CMAKE_CXX_FLAGS "-pthread -Wa,-mbig-obj -static -std=c++17")
target_link_libraries(HelloWorld PUBLIC "-L/lib/x86_64-linux-gnu/libdl.a")
endif()
after, run the following commands to build:
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchainfile.cmake
cmake --build .
And you should now have a working exe file for chaiscript
Looks like you need #include <mutex> first. Perhaps you will need others, too.

ld cannot find -latomic or -lstdc++

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.

Cmake finds library but does not find symbols

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
}

CMake cross-compile problem with CXX_FLAGS in linker

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.