Cannot set g++ compiler for CMake - c++

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)
...

Related

Is it ok for CMake to use c++, rather than mpicxx, to compile my code?

I'm trying to build an executable from C++ source code which uses MPI, on a GNU/Linux Devuan Chimaera system. Now, I'm an MPI/OpenMP newbie, I'm just trying to adapt this code, which isn't mine, to be built with CMake - when before it had a Makefile. My build succeeds, but I'm seeing segfaults, so I want to make sure my problem isn't with the build phase, which bugs me.
My CMakeLists.txt has:
find_package(OpenMP REQUIRED)
find_package(MPI REQUIRED)
and my system has OpenMPI 4.1.1 installed, which is found. I do this for my target:
target_link_libraries(my_executable PRIVATE MPI::MPI_CXX OpenMP::OpenMP_CXX)
but nothing else which indicates its expecting to be compiled by mpicxx.
... and indeed, when I configure (with CMake 3.22.1) and then build, the usual c++ executable gets invoked to compile (and then link) the my_target executable.
Questions:
Can source code which originally was getting compiled with mpicxx be compiled with "just" a C++ compiler, with the appropriate includes?
Assuming there's any merit to using mpicxx for compilation - how do I get CMake to use it for my target?
Edit: It's been suggested to me to try using mpirun to run my program. With it, I get no segmentation faults, consistently; it's only when I run directly that I see them.
Can source code which originally was getting compiled with mpicxx be compiled with "just" a C++ compiler, with the appropriate includes?
Yes, and you're doing it correctly.
The MPI systems I've used (Cori, Perlmutter, Stampede) have all provided implementations that work correctly with CMake's MPI support. However, it's possible that a sufficiently poorly administered system will break this.
Assuming there's any merit to using mpicxx for compilation - how do I get CMake to use it for my target?
This is a toolchain setting... set CMAKE_CXX_COMPILER to /path/to/mpicxx either at the command line, in a preset, or in a toolchain file.

How to set CMAKE_TRY_COMPILE_TARGET_TYPE from outside CMake

tl;dr
Given a CMakeList.txt which I cannot edit, can I set CMAKE_TRY_COMPILE_TARGET_TYPE to be STATIC_LIBRARY while configuring that file?
Ideally I could do this via an environmental variable, but if that is not possible, passing in my value as a command line argument would be ok too.
Details
I am trying to build a Conan profile that will allow me to cross build using the GNU Arm Embedded Toolchain.
Conan provides a mechanism for specifying the compiler binary and compiler + linker flags I would like CMake to use, but I need to specify set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) in order for GNU Arm Embedded to pass CMake's compiler check.
In order to get my cross build toolchain to work, then, I am left with 2 options:
Every single CMake file that I want to support cross build must check if we are building for an embedded device, and if so, runset(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY). This is annoying because it forces all projects to have to think about being embedded.
OR, Somehow pass CMAKE_TRY_COMPILE_TARGET_TYPE to CMake without editing the CMakeList.txt.
I would like to do 2.
You may be able to get the functionality you're looking for with the -D flag.
I would try something like this: cmake -D CMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY

What's CMAKE_CXX_FLAGS and which are available

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.

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).

Recommended ways to use CMake with icc via configuration options?

I would like to use the Intel compiler icc (or icpc) with a CMake-based project (on Linux for what it's worth). I can of course export the CXX variable when calling cmake, e.g. like
CXX=icpc cmake ../
and this works fine. I would however like to make this choice available via a custom option. For this I parse custom option, e.g.
cmake -DMY_COMPILER_OPTION=Intel ..
as
IF (MY_COMPILER_OPTION STREQUAL "Intel")
MESSAGE(STATUS "** Compiling with Intel settings **")
SET(CMAKE_CXX_COMPILER "icpc")
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -w")
SET(CMAKE_CXX_FLAGS_DEBUG "-g")
ENDIF ()
and set CMAKE_CXX_COMPILER together with some compiler flags. This also works, however there is an important "but".
I would also like to use the option -ipo (interprocedural optimization) for my code when compiling with icc plus I need to compile a static library within the build process. For this to work, I need to use Intel's xiar (and also xilink I guess).
cmake actually offers a special property for this
set_property(TARGET mytarget PROPERTY INTERPROCEDURAL_OPTIMIZATION 1)
however this only seems to works properly when the compiler has been set via the environment variable (then xiar is used). When setting the compiler via CMAKE_CXX_COMPILERthis property is ignored.
Is there another way to do this?. Some recommended way? Or at least a work-around?
The recommended way is to run cmake with the appropriate CMAKE_<LANG>_COMPILER defined.
Linux users
cmake -DCMAKE_C_COMPILER=icc -DCMAKE_CXX_COMPILER=icpc -DCMAKE_Fortran_COMPILER=ifort ..
Windows users
From an Intel Compiler console:
cmake -G "NMake Makefiles" -DCMAKE_C_COMPILER=icl -DCMAKE_CXX_COMPILER=icl -DCMAKE_Fortran_COMPILER=ifort ..
Ok, since there have been no answers here, I've also turned to the CMake mailing list list for help on this issue. The consent of the experts there seems to be that the way I was trying to do this is a rather bad idea. The reason is that the parsing of my custom flags happens to late in the initialization process. One should therefore rely on setting the compiler via environment variables and let CMake do its magic during the initial configuration run. I will modify my approach..
Basically, avoid trying to change the compiler. See the FAQ: How do I use a different compiler?. CMake Toolchain files provide a way to support some complex cases, like an exotic HPC compiler.