What's CMAKE_CXX_FLAGS and which are available - c++

I've been doing C++ for a long long time, but I come from the land of Windows.
I've been handed a project that uses CMake. I've googled around trying to learn it.
I run cmake .
I assume it always looks for CMakeLists.txt and generates makefiles.
This creates a bunch more cmake files and make files.
I was then instructed to run make package.
I assume package is just a target name that could be anything.
I then get errors:
c++: error: unrecognized command line option ‘-mthumb-interwork’
c++: error: unrecognized command line option ‘-mfloat-abi=hard’
c++: error: unrecognized command line option ‘-mfpu=neon’
I think those are due to the fact that I am trying to compile for a different architecture then the one I am on. I assume all the cmake files would set that up correctly for me. I also assume that nothing there is proprietary.
I see the line in the CMakeLists.txt
SET(CMAKE_CXX_FLAGS "-march=armv7-a -mthumb-interwork -mfloat-abi=hard -mfpu=neon -mtune=cortex-a9 -std=c++11 -O3")
If I look at the official cmake documentation, it says, and I quote
"Flags for all build types." ....Not very helpful
I am thinking it isn't using the correct compiler, but I also don't see where in the CMakeLists.txt the compiler is specified at all.
The question is:
Why would these flags be unrecognized?

In the Linux world, it's often assumed that you don't need to specify the compiler by name; instead you arrange for c++ to refer to the compiler. That may involve setting PATH, creating a shell alias or a symbolic link.
Apparently you already did so, as your compiler is being called and is complaining about standard GCC flags - clearly your compiler isn't GCC.
The CMakeLists.txt file however is very much assuming it's intended for GCC. Don't blame CMake for that. CMake is the tool, CMakeLists.txt are project-specific instructions. This is a problem of whoever created the particular CMakeLists.txt file.
There's no easy fix. There is a real possibility that the -mfpu=neon option to gcc was necessary for the program, and it's anyone's guess what you'll need on the other compiler.

Related

Difference between add_compile_options and add_link_options also flags each option supports

I've been using a .bat file to build my applications for years. Recently, switched to CMake for it's elegancy and I ran into a situation where I had to guess the flags that I should put into CMake's add_link_options and add_compile_options
Example flags that I've used in my BAT file,
-s WASM=1 --bind -s MODULARIZE=1
And, In CMake this flags have become (After trial and error),
add_compile_options("SHELL: -s WASM=1")
add_link_options("SHELL: --bind")
add_link_options("SHELL: -s MODULARIZE=1")
Honestly, I can't find any information regards flags that add_link_options and add_compile_options supports.
I know what is a linker is but lost when it comes to add_link_options or linker flags.
I'm used to compile everything in single line and now in CMake everything appear to be involve separate steps.
I am not sure what your problem is, but here is a full working sample from a Wasm project that sets project-wide strict mode and disabling of exception support:
if (EMSCRIPTEN)
add_compile_options(-fno-exceptions "SHELL:-s STRICT=1")
add_link_options("SHELL:-s STRICT=1")
endif()
Note in particular that, as it has a [compile+link] marker in the emscripten settings, -s STRICT=1 has to be used both for compiling and for linking, thus it appears in each.
The if(EMSCRIPTEN) around is there because this project can also be built for Windows and Linux.
The options you can pass to the compiler or linker depends on which compiler or linker you use. For example if you fork GCC and add a -Wstackoverflow-copy-pasta option, you can pass that option to add_compile_options(), but other people using standard GCC cannot.
So the answer to your question seems to be, read your compiler and linker documentation.

Cannot set g++ compiler for CMake

I want to use g++ compiler in my CPP project. So I setup Cmake file like this:
set(CMAKE_CXX_COMPILER "/usr/local/bin/g++")
project(GatewayTest LANGUAGES C CXX)
...
But when error still be shown with Clang. I ran on MacOS Sierra.
The error is:
clang: error: linker command failed with exit code 1 (use -v to see invocation).
Am i wrong with this setting?
Don't try to set the compiler from inside the CMakeLists.txt.
The idea behind this flag is that you give the user the opportunity to specify which compiler to use. This makes sense, as the user will know which machine they are going to build on, so they should know where to find the compiler. It does not make sense to make this information part of the build script, as the build script is, in principle, supposed to be portable to any machine and compiler.
If your project requires a specific compiler to be built correctly, you can inspect the variables like CMAKE_CXX_COMPILER and raise a diagnostic if they do not contain what you expect, but you should never write to those variables.
If you do want to scriptify compiler detection, you can either wrap the call to CMake in a shell script that sets the variables used for compiler detection or use a toolchain file for configuring CMake.
set(CMAKE_C_COMPILER "clang")
set(CMAKE_CXX_COMPILER "clang++")
project(GatewayTest LANGUAGES C CXX)
...

Introduce a new compiler to CMake

We work with a specific compiler, which is called Cadul. It has its own libraries, targets etc. The problem is that CMake does not support it in contrast to such "standard" compilers as GNU, Intel, Clang etc.
Firstly I thought to use cross compiling but it didn't work, since the host and target platforms are the same.
Then I looked into Modules, where I found the directory named "Compiler" which contains a lot of ".cmake" files specified for each compiler and each enabled language. I tried to substitute the word "GNU" by "Cadul" and hoped to see any changes, such as "The CXX compiler identification is Cadul ...". But it didn't happen.
Then I just removed the whole directory "Modules" from cmake and hoped to see that it doesn't work anymore. Surprisingly it did.
So has anyone ever integrated a new compiler to Cmake? With its own features, etc.
It looks like this has been recommended in the comments, but no one has condensed it to an answer yet.
You can choose a compiler by adding these lines to your CMakeLists.txt (source):
SET(CMAKE_C_COMPILER /path/to/c/compiler)
SET(CMAKE_CXX_COMPILER /path/to/cpp/compiler)
If you need to customize further, using a toolchain file works well. There are some examples in the documentation here.
Yes, I've done this before. But you need a lot more then just setting the compiler path (since CMake would try to identify this compiler and then - since it's unknown to CMake - would throw an error).
An example implementation of a new "compiler" can be found in my answer here:
Generic rule from makefile to cmake
It shows a enable_language(FOO) example that could be replaced with enable_language(Cadul).

Can't make project, unrecognized command line option libc++ error

I keep getting this error message while trying to Make this Azteroids project: "c++: error: unrecognized command line option ‘-stdlib=libc++’"
Based on what I've seen online, people are saying it's a Clang flag and the C++11 flag looks different. I mean, I don't disagree, but the instructions for creating the Azteroids executable are pretty simple and CMake seems to recognize C++11 support.
Is this a shortcoming of the cmake system in this project or am I missing a dependency or step? I don't understand. And yes, I've seen the similar questions.
Please see this Pastebin for more both the CMake and Make output.
Nothing in that output indicates that clang is involved here at all. Which is likely the problem.
It would seem that -stdlib=libc++ is a clang flag that your GNU c++ binary does not understand. Those flags are being manually added by the cmake configuration of that project. Which means it will not work without clang. So either remove those flags or install clang and configure cmake to use it.

Creating CMakeLists for a project that depends on LLVM

I've decided to try LLVM and the CMake build system for my language project, but I'm not sure how to generate a proper cross-platform CMakeLists for it. Running "llvm-config --libs" returns about a hundred libraries (I'm still not sure which of them I actually need) and "--cxxflags" gives me g++-specific flags (I wouldn't know how they translate to other compilers).
Is there a way to get output for different compilers from llvm-config? (Perhaps it depends on how llvm is compiled?)
If so, could I run llvm-config from CMakeLists and use its output instead of hard-coding it?
Otherwise, what are some maintainable alternatives?
llvm-config --cxxflags will use the compiler you build LLVM with in the first place. So if you plan on using that and build LLVM itself with a different compiler than g++ (default), then you need to build LLVM itself with a different compiler - or not use llvm-config in the first place.
I went the former route, so I create a build.sh, which contains this:
CC=clang CXX=clang++ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=1 -DLLVM_T
ARGETS_TO_BUILD=X86 ../llvm
make
I then have a makefile that uses llvm-config to define flags and such (I don't use CMake, but the concept should be possible to move to CMake quite easily). See: https://github.com/Leporacanthicus/lacsap/blob/master/Makefile