Reputation: 29
I am trying to migrate my C++ code to CLion on Mac OSX, but I am new to CMake. I have a C++ code, which has been tested in Eclipse and works successfully. In particular, I have created the Eclipse project by setting the project properties according to the following Makefile.
SYSTEM = x86-64_osx
LIBFORMAT = static_pic
CPLEXDIR = /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271
CONCERTDIR = /Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/concert
# ---------------------------------------------------------------------
# Compiler selection
# ---------------------------------------------------------------------
CCC = clang++ -O0
# ---------------------------------------------------------------------
# Compiler options
# ---------------------------------------------------------------------
CCOPT = -m64 -O -fPIC -fexceptions -DNDEBUG -DIL_STD -stdlib=libc++
# ---------------------------------------------------------------------
# Link options and libraries
# ---------------------------------------------------------------------
CPLEXBINDIR = $(CPLEXDIR)/bin/$(BINDIST)
CPLEXLIBDIR = $(CPLEXDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CONCERTLIBDIR = $(CONCERTDIR)/lib/$(SYSTEM)/$(LIBFORMAT)
CCLNDIRS = -L$(CPLEXLIBDIR) -L$(CONCERTLIBDIR)
CCLNFLAGS = -lconcert -lilocplex -lcplex -m64 -lm -lpthread -framework CoreFoundation -framework IOKit -stdlib=libc++
all:
make all_cpp
execute: all
make execute_cpp
CONCERTINCDIR = $(CONCERTDIR)/include
CPLEXINCDIR = $(CPLEXDIR)/include
CCFLAGS = $(CCOPT) -I$(CPLEXINCDIR) -I$(CONCERTINCDIR)
Here is what I have created so far for the CMakeLists.txt file.
cmake_minimum_required(VERSION 3.9)
project(SFCNF CXX)
set(CMAKE_CXX_STANDARD 11)
include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex/include)
include_directories(/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/concert/include)
set(CMAKE_CXX_FLAGS "-O0 -c -m64 -fPIC -DNDEBUG -DIL_STD -stdlib=libc++")
link_directories("/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/concert/lib/x86-64_osx/static_pic")
link_directories("/Users/soheilmn/Applications/IBM/ILOG/CPLEX_Studio1271/cplex/lib/x86-64_osx/static_pic")
add_executable(SFCNF "/Users/soheilmn/CLionProjects/SFCNF/main.cpp")
target_Link_Libraries(SFCNF "-lconcert -lilocplex -lcplex -m64 -lm -lpthread -framework CoreFoundation -framework IOKit -stdlib=libc++")
In CLion, when I click on the "Build" button, I see "Built target SFCNF" message (with a number of warnings). But, when I run the program, I see the following message:
"File not found: /Users/soheilmn/CLionProjects/SFCNF/cmake-build-debug/SFCNF"
Can anyone please tell me what I am missing here? Thanks!
Update: I edited my CMake file as follows.
cmake_minimum_required(VERSION 3.9)
project(SFCNF CXX)
set(CMAKE_CXX_STANDARD 11)
add_executable(SFCNF main.cpp)
With a simple Hello World program, my C++ code now works in CLion. However, when I set the compiler options like below
cmake_minimum_required(VERSION 3.9)
project(SFCNF CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "-O0 -c -m64 -fPIC -DNDEBUG -DIL_STD -stdlib=libc++")
add_executable(SFCNF main.cpp)
CLion produces a number of warnings as follows.
/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/soheilmn/CLionProjects/SFCNF/cmake-build-debug --target SFCNF -- -j 2
[ 50%] Linking CXX executable SFCNF
clang: warning: -Wl,-search_paths_first: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: -Wl,-headerpad_max_install_names: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: CMakeFiles/SFCNF.dir/main.cpp.o: 'linker' input unused [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-O0' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-fPIC' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-D NDEBUG' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-D IL_STD' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-stdlib=libc++' [-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-g' [-Wunused-command-line-argument]
[100%] Built target SFCNF
Moreover, now if I modify my program to print another message, CLion keeps running the previous Hello World program as if I have not modified anything in the main.cpp file.
Upvotes: 1
Views: 3728
Reputation: 54737
Do not manually set compile flags in CMake like that.
Instead, use the respective CMake features to achieve what those flags where supposed to do:
-O0
the level of optimization is typically determined by the CMAKE_BUILD_TYPE
. Note that this is a variable that will be set by the user when invoking CMake, so you should only ever read from that variable in the CMakeLists.txt
.-c
CMake properly separates compile and link steps, just never pass this option.-m64
The machine type is determined by the compiler being used (for Makefiles) or the generator (on Visual Studio). If you need to manually choose a different machine type, you will need a toolchain file. Unless you are cross-compiling, you almost certainly just want to skip this option.-fPIC
This is done by setting the POSITION_INDEPENDENT_CODE
target property. You can also set this globally for all targets by setting the CMAKE_POSITION_INDEPENDENT_CODE
variable.-DNDEBUG
This is again set automatically based on the CMAKE_BUILD_TYPE
.-DIL_STD
Use target_compile_definitions
to set preprocessor defines.-stdlib=libc++"
First be sure that you actually need this. This is again a toolchain dependent option, and one that highly depends on the build environment. So you will want to at least escape it behind a generator expression to make sure it is only invoked for the toolchains where it applies. You might even consider moving it to a toolchain file as well.All of that being said: There is no easy 1:1 conversion from Makefiles to CMake.
Both systems have vastly different scopes and use completely different idioms. In particular, CMake needs to be portable to a lot of underlying build systems, so a lot of the shortcuts that make can use are not supported by CMake. For instance, the link_directories
approach that you used is usually a really bad idea in CMake. Be sure you first get familiar with how CMake does these things before proceeding.
Upvotes: 2