27

It seems like CMake is fairly entrenched in its view that there should be one, and only one, CMAKE_CXX_COMPILER for all C++ source files. I can't find a way to override this on a per-target basis. This makes a mix of host-and-cross compiling in a single CMakeLists.txt very difficult with the built-in CMake facilities.

So, my question is: what's the best way to use multiple compilers for the same language (i.e. C++)?

cdleary
  • 66,842
  • 52
  • 160
  • 191

3 Answers3

14

It's impossible to do this with CMake.

CMake only keeps one set of compiler properties which is shared by all targets in a CMakeLists.txt file. If you want to use two compilers, you need to run CMake twice. This is even true for e.g. building 32bit and 64bit binaries from the same compiler toolchain.

The quick-and-dirty way around this is using custom commands. But then you end up with what are basically glorified shell-scripts, which is probably not what you want.

The clean solution is: Don't put them in the same CMakeLists.txt! You can't link between different architectures anyway, so there is no need for them to be in the same file. You may reduce redundancies by refactoring common parts of the CMake scripts into separate files and include() them.

The main disadvantage here is that you lose the ability to build with a single command, but you can solve that by writing a wrapper in your favorite scripting language that takes care of calling the different CMake-makefiles.

ComicSansMS
  • 46,689
  • 13
  • 143
  • 152
  • 2
    Seems like add_directory(other_build_kind_folder) is a possibility as well, as opposed to making a custom wrapper, since that's what I've been doing and it seems to work. :-) – cdleary Mar 04 '12 at 17:51
  • 2
    @cdleary Could you clarify how that works? How does `add_subdirectory` (or did you really mean `add_directory`?) allow you to switch toolchains? – Kyle Strand Apr 27 '15 at 21:56
  • 1
    Mostly correct, but there are techniques to massage CMake to use both a host and a toolchain set of compilers controlled from the one build. See [this question](http://stackoverflow.com/q/36084785/1938798) and [answer](http://stackoverflow.com/a/36084786/1938798) for a similar scenario which I've been using successfully in a couple of real world projects for some time now. @Bill's answer recommending ExternalProject is also good advice. – Craig Scott Jul 16 '16 at 02:46
  • 1
    @ComicSancMs I strongly disagree on the reasoning behind the 3rd paragraph ,Indeed you can't link with different architectures but that's not the only reason to have diffrent c++ compilers, for example I used to use [templight](https://github.com/mikael-s-persson/templight) as a wrapper for clang and ccache is also a compiler wrapper , both these projects count as different compilers but there are just different tools that by principal you can use at will at any separate cpp files you want – Spyros Mourelatos Feb 09 '21 at 12:44
  • In VS it's fine to have one solution with even static library projects compiled with different compilers. Because they all binary compatible. Compilers are VC, Intel, Clang. They all use the same VC stl. Designed to be binary compatible. – Антон Сергунов Oct 12 '21 at 03:23
5

You might want to look at ExternalProject: http://www.kitware.com/media/html/BuildingExternalProjectsWithCMake2.8.html

E-rich
  • 8,775
  • 11
  • 45
  • 74
Bill Hoffman
  • 1,712
  • 11
  • 11
0

To extend @Bill Hoffman's answer: Build your project as a super-build, by using some kind of template like the one here https://github.com/Sarcasm/cmake-superbuild which will configure both the dependencies and your project as an ExternalProject (standalone cmake configure/build/install environment).

Gabriel
  • 8,141
  • 5
  • 49
  • 95