2

I want to set compiler path (for example:icc) automatically in cmake, so my program can compile at any computer as long as it have installed icc, and we do not need to care about where the icc is installed.

At First, I using the follow command to set compiler. Everything is OK.

set(Intel_C_COMPILER "/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc")
set(Intel_CXX_COMPILER "/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc")

set(CMAKE_C_COMPILER   ${Intel_C_COMPILER}  )
set(CMAKE_CXX_COMPILER ${Intel_CXX_COMPILER})

project(MyProject)

....

Then, I want to set compiler path automatically, I know that the follow command can find compiler path

which icc

So I write the follow command try to set compiler automatically by cmake.

execute_process(COMMAND which icc  OUTPUT_VARIABLE Intel_C_COMPILER)
execute_process(COMMAND which icpc OUTPUT_VARIABLE Intel_CXX_COMPILER)

message(Intel_CXX_COMPILER: ${Intel_C_COMPILER})
message(Intel_CXX_COMPILER: ${Intel_CXX_COMPILER})

set(CMAKE_C_COMPILER   ${Intel_C_COMPILER}  )
set(CMAKE_CXX_COMPILER ${Intel_CXX_COMPILER})

project(MyProject)

....

At these case, something strange happens, cmake shows that:


 Intel_CXX_COMPILER:/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc

-- The C compiler identification is unknown
-- The CXX compiler identification is unknown

 CMake Error at CMakeLists.txt:27 (project):   The CMAKE_C_COMPILER:

    /opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc



  is not a full path to an existing compiler tool.

  Tell CMake where to find the compiler by setting either the
environment   variable "CC" or the CMake cache entry CMAKE_C_COMPILER
to the full path to   the compiler, or to the compiler name if it is
in the PATH.


CMake Error at CMakeLists.txt:27 (project):   The CMAKE_CXX_COMPILER:

    /opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc



  is not a full path to an existing compiler tool.

  Tell CMake where to find the compiler by setting either the
environment   variable "CXX" or the CMake cache entry
CMAKE_CXX_COMPILER to the full path   to the compiler, or to the
compiler name if it is in the PATH.


 -- Configuring incomplete, errors occurred!

CMake said that the path is not a full path to an existing compiler, but as shown in the message, it is just where the compiler located!

I know there are other techniques that we can set compiler, for example export some environment variables to help cmake find the path, but I want to know why my method dose not work?

Is there any better way can handle this problem?

Thanks in advance.

Xu Hui
  • 1,213
  • 1
  • 11
  • 24
  • 1
    In your `Intel_C_COMPILER` and `Intel_CXX_COMPILER` you have **traling newlines**: it is part of output of `which <...>` command and grubbed by `execute_process`. For remove that traling newline, see that question: https://stackoverflow.com/questions/39496043/how-to-strip-trailing-whitespace-in-cmake-variable. BTW, would you format your CMake log correctly, as a **code**, you (and we) would easily find exceeded newlines in your paths. This is why formatting as a *blockquote* should be avoided for logs. – Tsyvarev May 21 '19 at 08:38
  • @Tsyvarev You hint the point directly! Thanks a lot! I have edit the CMake log to a code now. BTW, would you like to copy your comment as an answer? I want to choose your answer as the accept one. – Xu Hui May 21 '19 at 16:09

2 Answers2

2

Generally speaking, it is not possible to set the variables CMAKE_C_COMPILER and CMAKE_CXX_COMPILER from within a project.

Since the compiler detection happens with the project() call, the compiler has to be set early on while configuring the project.

I suggest you try the following:

export CC=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc
export CXX=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc

cd /path/to/build
cmake /path/to/src

or you could also pass the variables CMAKE_C_COMPILER and CMAKE_CXX_COMPILER:

export CC=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc
export CXX=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc

cd /path/to/build
cmake \
  -DCMAKE_C_COMPILER:FILEPATH=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icc \
  -DCMAKE_CXX_COMPILER:FILEPATH=/opt/intel/compilers_and_libraries_2019.0.117/linux/bin/intel64/icpc \
  /path/to/src

Important: When trying these commands, make sure to configure the project in an empty build directory.

J-Christophe
  • 1,975
  • 15
  • 13
  • Acatually, I set the compiler before the command `project(...)`, (I have edit the problem). Thanks for reply and your solution did work. But I am still confused that, why cmake can not find the compiler if the path of compiler is obtained by `which icc`. Any suggestions? – Xu Hui May 21 '19 at 05:37
2

Variables Intel_C_COMPILER and Intel_CXX_COMPILER have trailing newline. Way for removing that newline are described in that question and its answers: How to strip trailing whitespace in CMake variable?

E.g., you may run execute_process with OUTPUT_STRIP_TRAILING_WHITESPACE option, so it will behave similar to the shell's backtick operator (`which icc`).

Detailed description

Most of shell utilities output single- (or even multi-) line information with trailing newline. And utility which is not an exception. With trailing newline an output looks nice when one run these utilities in the terminal.

But when run such utility in the script and grab its output programmatically, one need to care about such newline.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153