wolverine99
wolverine99

Reputation: 67

How do you specify a specific compiler in for CMAKE builds in Windows

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?

Upvotes: 4

Views: 6689

Answers (1)

Arda Aytekin
Arda Aytekin

Reputation: 1301

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.

Upvotes: 3

Related Questions