Preserving options with spaces in add_compile_options

kvrigor
Tue, 14 Jul 2020 10:51:52 +0000
Usage

Hello,

I have a CMake project with several targets and I wish to set global compile options through add_compile_options . These are the flags that I need to set:

ifort | icc
-qno-opt-dynamic-align | -qno-opt-dynamic-align
-convert big_endian | -fp-model precise
-assume byterecl | -O2
-ftz | -debug minimal
-traceback |
-assume realloc_lhs |
-fp-model source |
-O2 |
-debug minimal |
-free |

First I validated the flags via icc and ifort (v19.0.5.281). No compiler warnings generated and compilation is successful.

ifort -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source -O2 -debug minimal -free -o hello_F90.out hello.F90
icc -qno-opt-dynamic-align -fp-model precise -O2 -debug minimal -o hello_C.out hello.c

Next, I created a test project which tries to achieve the same result through add_compile_options.

cmake_minimum_required (VERSION 3.14)

project (helloworld LANGUAGES C Fortran)

# CASE 1: unquoted flags, space-separated
set(fflags -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source -O2 -debug minimal -free)
set(cflags -qno-opt-dynamic-align -fp-model precise -O2 -debug minimal)
add_compile_options("$<$<COMPILE_LANGUAGE:Fortran>:${fflags}>")
add_compile_options("$<$<COMPILE_LANGUAGE:C>:${cflags}>")

add_library(helloworld STATIC hello.c hello.F90)

Triggering the build on my Bash terminal,

$ cmake -S . -B bld -DCMAKE_C_COMPILER=icc -DCMAKE_Fortran_COMPILER=ifort
-- The C compiler identification is Intel 19.0.5.20190815
-- The Fortran compiler identification is Intel 19.0.5.20190815
-- Check for working C compiler: /opt/software/icc/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/icc
-- Check for working C compiler: /opt/software/icc/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/icc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working Fortran compiler: /opt/software/ifort/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/ifort
-- Check for working Fortran compiler: /opt/software/ifort/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/ifort  -- works
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - done
-- Checking whether /opt/software/ifort/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/ifort supports Fortran 90
-- Checking whether /opt/software/ifort/2019.5.281-GCC-8.3.0/compilers_and_libraries_2019.5.281/linux/bin/intel64/ifort supports Fortran 90 -- yes
-- Configuring done
-- Generating done
-- Build files have been written to: /home/projectuser/cmake-hello/bld
$ cmake --build bld
Scanning dependencies of target helloworld
[ 33%] Building C object CMakeFiles/helloworld.dir/hello.c.o
[ 66%] Building Fortran object CMakeFiles/helloworld.dir/hello.F90.o
ifort: error #10236: File not found:  'realloc_lhs'
gmake[2]: *** [CMakeFiles/helloworld.dir/hello.F90.o] Error 1
gmake[2]: *** Deleting file `CMakeFiles/helloworld.dir/hello.F90.o'
gmake[1]: *** [CMakeFiles/helloworld.dir/all] Error 2
gmake: *** [all] Error 2

I get the error File not found: 'realloc_lhs'. Inspecting bld/CMakeFiles/helloworld.dir/flags.make reveals the flags used:

C_FLAGS =   -qno-opt-dynamic-align -fp-model precise -O2 -debug minimal
Fortran_FLAGS =   -qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback realloc_lhs -fp-model source -O2 -debug minimal -free

I tried different variations of setting compiler flags and was able to successfully compile the project, but the compiler warnings suggest that some flags were not recognized.

CASE 2: Enclosed in quotes, space-separated

Syntax
set(fflags "-qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source -O2 -debug minimal -free")
set(cflags "-qno-opt-dynamic-align -fp-model precise -O2 -debug minimal")

Result
$ cmake --build bld
[ 33%] Building C object CMakeFiles/helloworld.dir/hello.c.o
icc: command line warning #10006: ignoring unknown option '-qno-opt-dynamic-align -fp-model precise -O2 -debug minimal'
[ 66%] Building Fortran object CMakeFiles/helloworld.dir/hello.F90.o
ifort: command line warning #10006: ignoring unknown option '-qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source -O2 -debug minimal -free'
[100%] Linking Fortran static library libhelloworld.a
[100%] Built target helloworld

bld/CMakeFiles/helloworld.dir/flags.make
C_FLAGS =   "-qno-opt-dynamic-align -fp-model precise -O2 -debug minimal"
Fortran_FLAGS =   "-qno-opt-dynamic-align -convert big_endian -assume byterecl -ftz -traceback -assume realloc_lhs -fp-model source -O2 -debug minimal -free"

CASE 3: Enclosed in quotes, semicolon separated

Syntax
set(fflags "-qno-opt-dynamic-align;-convert big_endian;-assume byterecl;-ftz;-traceback;-assume realloc_lhs;-fp-model source;-O2;-debug minimal;-free")
set(cflags "-qno-opt-dynamic-align;-fp-model precise;-O2;-debug minimal")

Result
$ cmake --build bld
Scanning dependencies of target helloworld
[ 33%] Building C object CMakeFiles/helloworld.dir/hello.c.o
icc: command line warning #10159: invalid argument for option '-fp-model'
icc: command line warning #10006: ignoring unknown option '-debug minimal'
[ 66%] Building Fortran object CMakeFiles/helloworld.dir/hello.F90.o
ifort: command line warning #10006: ignoring unknown option '-convert big_endian'
ifort: command line warning #10006: ignoring unknown option '-assume byterecl'
ifort: command line warning #10006: ignoring unknown option '-assume realloc_lhs'
ifort: command line warning #10159: invalid argument for option '-fp-model'
ifort: command line warning #10006: ignoring unknown option '-debug minimal'
[100%] Linking Fortran static library libhelloworld.a
[100%] Built target helloworld

bld/CMakeFiles/helloworld.dir/flags.make
C_FLAGS =   -qno-opt-dynamic-align "-fp-model precise" -O2 "-debug minimal"`
Fortran_FLAGS =   -qno-opt-dynamic-align "-convert big_endian" "-assume byterecl" -ftz -traceback "-assume realloc_lhs" "-fp-model source" -O2 "-debug minimal" -free`

CASE 4: Key-value pair options enclosed in quotes, space-separated

Syntax
set(fflags -qno-opt-dynamic-align "-convert big_endian" "-assume byterecl" -ftz -traceback "-assume realloc_lhs" "-fp-model source" -O2 "-debug minimal" -free)
set(cflags -qno-opt-dynamic-align "-fp-model precise" -O2 "-debug minimal")

Result: same as CASE 3

bld/CMakeFiles/helloworld.dir/flags.make: same as CASE 3

To summarize this post, how can I pass a compiler option of the form -key value to add_compiler_options (minimum CMake v3.14)? Note that I don’t wish to use target_compile_options since my goaI is to “enforce” compiler-dependent flags on all my targets.

If it helps, these are the Hello World programs that I used for testing.

C
#include <stdio.h>

int main() {
   printf("Hello World!");
   return 0;
}

Fortran
program hello
  print *, 'Hello, World!'
end program hello

10 posts - 3 participants