3

I am trying to get CMAKE to use a specific compiler when running. Specifically, I want it to use the locally installed GCC compiler. But when i try to set the CMAKE_C_COMPILER variable, it seems to fail.

set(CMAKE_C_COMPILER "gcc")
set(CMAKE_CXX_COMPILER "g++")

cmake_minimum_required(VERSION 3.10)

PROJECT(hello C)

add_executable(hello hello.c)

UPDATE USING TOOLCHAIN

I tried to make it work using the following toolchain file, but it still chooses Visual Studio build tools.

# Toolchain File

# The target of this operating systems is 
SET(CMAKE_SYSTEM_NAME Windows)

# which compilers to use for C and C++
SET(CMAKE_C_COMPILER gcc)
SET(CMAKE_CXX_COMPILER g++)

# here is the target environment located
SET(CMAKE_FIND_ROOT_PATH  C:/MyPrograms/MinGW/bin/ )

# adjust the default behaviour of the FIND_XXX() commands:
# search headers and libraries in the target environment, search
# programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

MORE UPDATES ON ISSUE

When i look at the cache file created when using the toolchain file, i find something interesting. It is trying to point to the correct compiler, but it is using the Visual Studio Generator still...

//Name of generator.
CMAKE_GENERATOR:INTERNAL=Visual Studio 15 2017
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=C:/Program Files (x86)/Microsoft Visual Studio/2017/BuildTools/ 

How do i deal with the generator here?

wolverine99
  • 57
  • 2
  • 7
  • "But when i try to set the CMAKE_C_COMPILER variable, it seems to fail." - Please, show the **error message** you got. Simple "seems to fail" is not a good description of the problem on Stack Overflow. – Tsyvarev May 21 '19 at 08:41
  • appologies. It does run, but it uses the visual studio toolchain. i want it to use gcc compiler. – wolverine99 May 21 '19 at 20:33
  • @Tsyvarev do you have any input here? No matter what i put in my toolchain file, i cannot seem to get it to stop setting **CMAKE_GENERATOR_INSTANCE** to Visual Studio Build Tools. Even if I set it in toolchain file to wipe internal cache using `set(CMAKE_GENERATOR_INSTANCE "" CACHE INTERNAL "" FORCE)` – wolverine99 May 22 '19 at 15:30
  • It smells you are confused between CMake **generator**, which could be Visual Studio, MinGW, Makefile, Ninja, etc. and a **compiler**, which could be gcc, llvm, cl. These are **independent** things. If you want to change a compiler, set `CMAKE_C_COMPILER` in the `CMakeLists.txt` or in the toolchain file. If you want to change a [generator](https://cmake.org/cmake/help/v3.7/manual/cmake-generators.7.html), pass appropriate `-G` option to `cmake`. (I know, that `cl` compiler, shipped with Visual Studio, works with other generators. But I am not sure, whether Visual Studio would work with `gcc`.) – Tsyvarev May 22 '19 at 15:39
  • @Tsyvarev I thought you could specify **generator** in toolchain with following command `set(CMAKE_GENERATOR "MinGW Makefiles" CACHE INTERNAL "" FORCE )`. Why doesn't that work? – wolverine99 May 22 '19 at 16:15
  • When start to parse `CMakeLists.txt`, CMake needs to know the generator. So it is too late to set the generator in the `CMakeLists.txt`. For more information see that question: https://stackoverflow.com/questions/11269833/cmake-selecting-a-generator-within-cmakelists-txt – Tsyvarev May 22 '19 at 16:20

1 Answers1

1

CMake is a tool that is intended for defining dependencies among the targets in your application. You define the dependencies and set the language requirements for your targets, and you ask CMake to generate files to help you build your targets. Having this in mind, please do not mess with the CMAKE_C(XX)_COMPILER variables directly in your CMakeLists.txt, but rather think of using toolchain files to define the specific compiler/linker properties. Using toolchain files, you can not only define different compiler/linker setups for your host but also do cross-compilation, in which the host and target devices are of different architecture.

EDIT. To be able to use the locally installed gcc compiler, you do not need to play with any of the (related) variables inside your CMakeLists.txt file. Instead, you should (re)define your PATH environment variable to include the corresponding (i.e., MinGW or Cygwin) binaries, and select an appropriate generator. Below is a minimal working example based on your code.

Assume that you have the following directory structure:

.
├── appveyor.yml
├── CMakeLists.txt
└── hello.c

with hello.c having the contents

#include <stdio.h>

int main(int argc, char *argv[]) {
  printf("Hello world!\n");
  return 0;
}

CMakeLists.txt having the contents

cmake_minimum_required(VERSION 3.10)
project(hello C)
add_executable(hello hello.c)

and finally, appveyor.yml having the following

image: Visual Studio 2013

environment:
  matrix:
    - generator: "Visual Studio 12 2013 Win64"
    - generator: "MSYS Makefiles"

before_build:
  - IF "%generator%"=="MSYS Makefiles" set PATH=C:\msys64\usr\bin;C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\bin;%PATH%

build_script:
  - mkdir build
  - cd build
  - cmake -G "%generator%" ..
  - cmake --build .

after_build:
  - IF EXIST Debug cd Debug
  - hello.exe

This example successfully builds on AppVeyor with both of the toolchains. The catch here is that when you go for MSYS Makefiles, or MinGW Makefiles for that matter, you should define your PATH variable to include the binaries to the compiler toolchain. In the above example, I simply use the default paths for AppVeyor's VMs. Another thing to note for appveyor.yml is that the Visual Studio generators use different (sub)directories for different CMAKE_BUILD_TYPEs. Hence, I first check the existence of the directory Debug, and if it exists, I change to the directory and run hello.exe.

I hope this answers your question.

Arda Aytekin
  • 1,231
  • 14
  • 24
  • I had to delete previous comment to correct myself. It still doesn't work. I used the toolchain file I put in updated description body. It sill doesn't choose the correct compiler. Not sure what I am doing wrong here. – wolverine99 May 21 '19 at 21:20
  • Have you tried the answers [here](https://stackoverflow.com/q/49808637/4720025) or [here](https://stackoverflow.com/q/46849262/4720025)? Unfortunately, I am on not Windows where I can test an MWE. As a side note, what is the reason for you to use `gcc` while you have a native compiler on your system, if I may ask? – Arda Aytekin May 23 '19 at 08:45
  • @wolverine99 more links: [1](https://github.com/tudelft3d/masbcpp/wiki/Building-on-Windows-with-CMake-and-MinGW), [2](https://stackoverflow.com/q/4101456/4720025), and [3](https://stackoverflow.com/q/36633177/4720025). As you can see, you _should not_ explicitly set the `C(XX)_COMPILER` variables inside `CMakeLists.txt`. Moreover, it seems that you do _not_ need any toolchain files, either, should MinGW and/or Cygwin are properly installed and configured on your system. – Arda Aytekin May 23 '19 at 08:57
  • @wolverine99 I have modified my answer, which I now believe solves your problem. – Arda Aytekin May 23 '19 at 11:08
  • 1
    Thanks. this does work. I think the key here is that i needed to use the `-G` to set the generator. – wolverine99 May 24 '19 at 13:05
  • @wolverine99 if this has solved your problem, please do not forget to mark as an answer. – Arda Aytekin May 24 '19 at 13:34