Creating CMakeLists for a project that depends on LLVM - c++

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

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.

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.

How to set c++ compiler on OS X with bazel?

How can you tell bazel to use a different C++ compiler on OS X?
bazel build --action_env CC=/path/to/compiler //:target
works on linux.
But -s shows that bazel always runs with external/local_config_cc/wrapped_clang (clang) on OSX regardless of what CC is.
CC correctly works only when you use the C++-only toolchain. If you have Xcode installed, bazel will detect this and automatically pick a different toolchain, the one that supports both C++ and ObjC. This toolchain can only use Xcode-provided clang.
This is unfortunate and I propose two solutions:
File a feature request for bazel to make it possible to select which toolchain is used. This will allow you to tell bazel that even though you have Xcode installed, you want to use C++ only toolchain with a custom compiler. This is quite simple and doable in a short time.
File a feature request for bazel to make it possible to select which compiler is used with C++/ObjC toolchain. I cannot comment on viability of this, I know next to nothing about osx, and I have no idea if it makes any sense to compile ObjC with a compiler that is not provided with Xcode...
Actually with the latest version of bazel specifying
BAZEL_USE_CPP_ONLY_TOOLCHAIN=1
build --action_env CC=/path/to/compiler [...]
does work, in the sense that the specified compiler is used. However there is still a problem with the compiler flags. If the compiler flags of the old compiler are incompatible with the new one, there is a problem. I still have to find out how to change compiler flags.
Use --crosstool_top.
See also --host_crosstool_top and --apple_crosstool_top.

How do I force cmake to use cl.exe without full path?

I am building an open source project (kst, v2.0.8) that uses CMake. I am using CMake v2.8.12.2 and MSVC 2008 as a compiler and am generating NMake makefiles to build it on the command line. I can get it to build successfully with this setup. These versions are mandated so I cannot currently use a later version of CMake or MSVC.
I need to be able to perform a source code analysis of kst using HP's Fortify and to be able to use it from the command line it works in one of two ways:
Touchless mode where it creates it's own "cl.exe", sets the path to it before the path to the real cl.exe and therefore gets launched during build.
Set the compiler in the makefile to the Fortify command line, e.g. sourceanalyzer -b build_id cl instead of cl.
Either way I need to force the compiler that cmake generates into its makefiles to be something that cmake does not automatically detect.
I've tried setting the compiler when running cmake following the same method in this question but cmake still insists on putting the full path to the MSVC cl.exe in the makefiles.
cmake -DCMAKE_C_COMPILER=cl -DCMAKE_C_COMPILER_FORCED=ON -DCMAKE_CXX_COMPILER=cl -DCMAKE_CXX_COMPILER_FORCED=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%CFITSIO_DIR% -G"NMake Makefiles" ..\cfit3250
I also tried setting the compiler to invoke Fortify but when cmake tests the compiler it fails saying that it cannot find the compiler. (I have also tried this without the FORCED=ON arguments and in that case it says the compiler fails.)
cmake -DCMAKE_C_COMPILER="sourceanalyzer -b %BUILDID% cl" -DCMAKE_C_COMPILER_FORCED=ON -DCMAKE_CXX_COMPILER="sourceanalyzer -b %BUILDID% cl" -DCMAKE_CXX_COMPILER_FORCED=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=%CFITSIO_DIR% -G"NMake Makefiles" ..\cfit3250
I could probably search and replace all the compiler invocations in the makefiles but I'd have to remember to do that after every cmake, and it would be tedious seeing as there are multiple projects / makefiles / calls to cl (rather than defining a CC variable in the makefile). I'd rather have a way to make cmake use the desired compiler right from the offset.
UPDATED: Testing showed the original suggested approach didn't work as expected on at least some platforms. It seems using a wrapper script is likely the way to go.
If you really want to force a particular compiler and by-pass CMake's compiler checks, the CMakeForceCompiler module may be what you are looking for. That link to the CMake docs contains a trivial toolchain file example which shows how to use a specific compiler invoked as a simple command with no path. Unfortunately, CMake still converts this to an absolute path, so on its own, this won't solve your problem. You could, however, use a toolchain file to point at a wrapper script and use CMakeForceCompiler to bypass the compiler checks. This combination should yield the behaviour you've asked for, but note that CMakeForceCompiler is now deprecated.
Note that when using the CMakeForceCompiler module, you take on a bit more responsibility for telling CMake information, notably the compiler ID of the particular compiler you want to force using, but from the CMake docs it seems pretty clear this will just be MSVC in your case.
To use a toolchain file, invoke CMake with a -DCMAKE_TOOLCHAIN_FILE=path/to/file option pointing at your own custom toolchain file. The CMake docs have a specific section covering the use of toolchains, although it does gloss over some of the important nitty gritty details.
As mentioned in #Tsyvarev's comment, the use of a wrapper script is likely to be your best way of dealing with this. That wrapper script just needs to forward the call to the usual compiler command without specifying a path. You then take responsibility for ensuring the command will be on your PATH when you do a build. Something as simple as the following should suffice as a wrapper batch file on Windows (untested):
cl %*
Now, you can control whether the Visual Studio compiler or Fortify gets invoked purely by the PATH the build sees. Personally, I think this is a bit fragile, but it's what you asked for. ;)
As a more robust alternative, is it possible to use two completely separate builds? If so, then I'd recommend that as a better alternative. Build one with the default Visual Studio compiler as normal and for the other build, use a toolchain file to point at the Fortify compiler to get CMake to bypass its compiler checks. That way you aren't relying on the build environment being set up a particular way.

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.