Reputation: 67
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)
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)
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
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_TYPE
s. 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