[CMake] complete change of compilation flags for a single file

Michael Hertling mhertling at online.de
Fri Oct 14 07:59:25 EDT 2011


On 10/11/2011 11:42 AM, Ilias Miroslav wrote:
> Dear experts,
> 
> within our cmake project there are needs to change compilation flags of some individual files, especially we want sometimes to decrease optimization level.
> 
> For that there is a command "set_source_file_properties", but among PROPERTIES,
> 
> http://grip.espace-win.net/doc/apps/cmake/cmake-properties.txt , 
> 
> there is no flag to completely replace/modify  CMAKE_Fortran_FLAGS + CMAKE_Fortran_FLAGS_RELEASE for that file.
> 
> There is only "COMPILE_FLAGS" putting extra compiler flags for file 's compilation.
> 
> For instance, for chosen file "some_file.F90"
> SET_SOURCE_FILES_PROPERTIES( some_file.F90 PROPERTIES COMPILE_FLAGS "-O1l")
> 
> this command combines -O3 from CMAKE_Fortran_FLAGS_RELEASE with -O1 from COMPILE_FLAGS ... but we want only -O1.
> 
> Another example:
> 
>   set_source_files_properties( abacus/her2drv.F    PROPERTIES COMPILE_FLAGS "-O0 -no-ip"  )
> 
> make VERBOSE=1 abacus/her2drv.o
> 
> make -f CMakeFiles/dirac.dir/build.make CMakeFiles/dirac.dir/abacus/her2drv.F.o
> make[1]: Entering directory `/people/disk2/ilias/QCH_Work/qch_progs/dirac_git/trunk/build_ompi_ifort_icc_mkl_ilp64'
> /people/disk2/ilias/bin/cmake_install/bin/cmake -E cmake_progress_report /people/disk2/ilias/QCH_Work/qch_progs/dirac_git/trunk/build_ompi_ifort_icc_mkl_ilp64/CMakeFiles 
> Building Fortran object CMakeFiles/dirac.dir/abacus/her2drv.F.o
> /people/disk2/ilias/bin/openmpi_ifort_icc_ilp64/bin/mpif90  -o CMakeFiles/dirac.dir/abacus/her2drv.F.o -DPRG_DIRAC -DTHIS_IS_CMAKE_BUILD -DMOD_XML -DMOD_OPENRSP -DMOD_OOF -DMOD_ESR -DMOD_KRCC -DMOD_SRDFT -DMOD_XCFUN -DMOD_MAGNETIZ -DMOD_MCSCF_spinfree -DMOD_UNRELEASED -DMOD_CAP -DMOD_ERI -DMOD_DNF -DINSTALL_WRKMEM=64000000 -DSYS_LINUX -DINT_STAR8 -DVAR_MPI -DVAR_MPI2 -w -assume byterecl -DVAR_IFORT -g -traceback -i8  -O3 -ip -module modules -I/people/disk2/ilias/bin/openmpi_ifort_icc_ilp64_valgrind/include -I/people/disk2/ilias/QCH_Work/qch_progs/dirac_git/trunk/include -I/people/disk2/ilias/QCH_Work/qch_progs/dirac_git/trunk/build_ompi_ifort_icc_mkl_ilp64/modules -I/people/disk2/ilias/QCH_Work/qch_progs/dirac_git/trunk/build_ompi_ifort_icc_mkl_ilp64/xcint/xcfun/fortran   -O0 -no-ip -c /people/disk2/ilias/QCH_Work/qch_progs/dirac_git/trunk/abacus/her2drv.F
> make[1]: Leaving directory `/people/disk2/ilias/QCH_Work/qch_progs/dirac_git/trunk/build_ompi_ifort_icc_mkl_ilp64'
> 
> Here it combines  -O3 -ip "at the beginning" (in CMAKE_Fortran_FLAGS_RELEASE ) with -O0 -no-ip "at the end", but we don't want this.
> 
> Any help please ?
> 
> Miro

A thorough management of compilation flags is notoriously demanding
with CMake because these flags stem from several origins - multiple
variables, properties and even from environment variables when the
project is configured for the first time, e.g. CC - and aren't kept
at a central place and joint not until the generation step, AFAIK.

If you get along with Makefiles, you might use the RULE_LAUNCH_*
properties to make last-minute modifications; see the following:

# CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8 FATAL_ERROR)
PROJECT(RMFLAGS C)
SET(CMAKE_VERBOSE_MAKEFILE ON)
FILE(WRITE ${CMAKE_BINARY_DIR}/main.c "int main(void){return 0;}\n")
SET_SOURCE_FILES_PROPERTIES(main.c PROPERTIES COMPILE_FLAGS "-O1")
ADD_EXECUTABLE(main main.c)
SET(RMFLAGS "bash ${CMAKE_SOURCE_DIR}/rmflags.sh")
SET_TARGET_PROPERTIES(main PROPERTIES
    RULE_LAUNCH_COMPILE "${RMFLAGS} -O3 --")

# rmflags.sh:
FLAGS=()
while [ "$1" != "--" ]; do
    FLAGS[${#FLAGS[@]}]="$1"; shift
done
shift
CMD=("$1"); shift
declare -i OCCURS
for i in "$@"; do
    OCCURS=0
    for j in "${FLAGS[@]}"; do
        [ "$i" == "$j" ] && : $((++OCCURS))
    done
    [ $OCCURS -eq 0 ] && CMD[${#CMD[@]}]="$i"
done
echo "Executing ${CMD[@]}"
exec "${CMD[@]}"

Configure with CMAKE_BUILD_TYPE==release, and the rmflags.sh script
will drop the -O3 flag from the compiler command line. In this way,
you should be able to perform arbitrary manipulations. However, if
you use the GCC compilers only, you might rely on the following
assertion from gcc's manpage:

"If you use multiple -O options, with or without level numbers,
the last such option is the one that is effective."

'hope that helps.

Regards,

Michael


More information about the CMake mailing list