Skip to content

Commit

Permalink
Honour build-type specific flags in source flag override
Browse files Browse the repository at this point in the history
  • Loading branch information
awnawab committed Oct 25, 2024
1 parent 5b95b66 commit ecb5fa9
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 13 deletions.
41 changes: 28 additions & 13 deletions cmake/gen_source_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,39 @@
import logging
from json import JSONDecoder
from os import path
from collections import defaultdict

log = logging.getLogger('gen_source_flags')


def match(source, pattern, op, flags, indent=0):
def match(source, pattern, op, flags, indent=0, btype='all'):
if fnmatch(source, pattern):

suff = '' if op[0] in ('+', '=', '/') else ' (nested pattern)'
log.debug('%s-> pattern "%s" matches "%s"%s',
' ' * (indent + 1), pattern, source, suff)

if op[0] == "+":
flags += [flag for flag in op[1:] if flag not in flags]
log.debug('%sappending %s --> flags: %s', ' ' * (indent + 2), op[1:], flags)
flags[btype] += [flag for flag in op[1:] if flag not in flags[btype]]
log.debug('%sappending %s --> flags: %s', ' ' * (indent + 2), op[1:], flags[btype])

elif op[0] == "=":
flags = op[1:]
log.debug('%ssetting %s --> flags: %s', ' ' * (indent + 2), op[1:], flags)
flags[btype] = op[1:]
log.debug('%ssetting %s --> flags: %s', ' ' * (indent + 2), op[1:], flags[btype])

elif op[0] == "/":
flags = [flag for flag in flags if flag not in op[1:]]
log.debug('%sremoving %s --> flags: %s', ' ' * (indent + 2), op[1:], flags)
flags[btype] = [flag for flag in flags[btype] if flag not in op[1:]]
log.debug('%sremoving %s --> flags: %s', ' ' * (indent + 2), op[1:], flags[btype])

else: # Nested rule
log.debug('%sapplying nested rules for "%s" (flags: %s)',
' ' * (indent + 2), pattern, flags)
' ' * (indent + 2), pattern, flags[btype])
for nested_pattern, nested_op in op:
flags = match(source, nested_pattern, nested_op, flags, indent + 2)
flags = match(source, nested_pattern, nested_op, flags, indent=indent + 2, btype=btype)

elif pattern.lower() in ['none', 'debug', 'bit', 'production', 'release', 'relwithdebinfo']:
for _rule in op:
flags = match(source, _rule[0], _rule[1], flags, indent=indent + 2, btype=pattern.lower())

return flags

Expand All @@ -58,14 +63,24 @@ def generate(rules, out, default_flags, sources, debug=False):
with open(path.expanduser(out), 'w') as f:
for source in sources:
log.debug('%s (default flags: "%s")', source, default_flags)
flags = default_flags.split()

flags = defaultdict(list)
flags['all'] += default_flags.split()
for pattern, op in rules:
flags = match(source, pattern, op, flags)

if flags:
log.debug(' ==> setting flags for %s to %s', source, ' '.join(flags))
f.write('set_source_files_properties(%s PROPERTIES COMPILE_FLAGS "%s")\n'
% (source, ' '.join(flags)))
for btype in ['all', 'debug', 'bit', 'production', 'release', 'relwithdebinfo']:
flags_list = ';'.join(flags[btype])
if btype == 'all':
log.debug(' ==> setting flags for %s to %s', source, flags_list)
f.write('set_source_files_properties(%s PROPERTIES COMPILE_FLAGS "%s")\n'
% (source, flags_list))
else:
if flags[btype]:
log.debug(' ==> setting flags for %s to %s for build-type %s', source, flags_list, btype)
f.write('set_source_files_properties(%s PROPERTIES COMPILE_OPTIONS $<$<CONFIG:{btype.upper()}>:"%s">)\n'
% (source, flags_list))
else:
log.debug(' ==> flags for %s empty', source)

Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ add_subdirectory( find_ecbuild )
add_subdirectory( project_import )
add_subdirectory( ecbuild_shared_libs )
add_subdirectory( interface_library )
add_subdirectory( ecbuild_source_flags )
12 changes: 12 additions & 0 deletions tests/ecbuild_source_flags/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
set(_dir ${CMAKE_CURRENT_BINARY_DIR})
configure_file(run-test.sh.in ${_dir}/run-test.sh @ONLY)
configure_file(test_ecbuild_source_flags.cmake ${_dir}/CMakeLists.txt COPYONLY)
configure_file(emptyfile.c ${_dir}/emptyfile.c COPYONLY)
configure_file(emptyfile.cxx ${_dir}/emptyfile.cxx COPYONLY)
configure_file(emptyfile.F90 ${_dir}/emptyfile.F90 COPYONLY)

ecbuild_add_test(
TARGET test_ecbuild_source_flags
TYPE SCRIPT
COMMAND run-test.sh
)
1 change: 1 addition & 0 deletions tests/ecbuild_source_flags/emptyfile.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
! An empty file
1 change: 1 addition & 0 deletions tests/ecbuild_source_flags/emptyfile.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// An empty file
1 change: 1 addition & 0 deletions tests/ecbuild_source_flags/emptyfile.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// An empty file
14 changes: 14 additions & 0 deletions tests/ecbuild_source_flags/flags-sourceflags.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"*" : [ "=", "-g" ],
"*.F90" : [ "+", "-fortran_only_flag" ],
"*.c" : [ "+", "-fPIC" ],
"*.cxx" : [ "+", "-fPIC" ],
"debug": {
"*.c": [ "+", "-O0" ],
"*.cxx": [ "+", "-O0" ]
},
"bit": {
"*.c": [ "+", "-O2" ],
"*.cxx": [ "+", "-O2" ]
}
}
22 changes: 22 additions & 0 deletions tests/ecbuild_source_flags/run-test.sh.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash

set -e

HERE="$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd -P )"

cd $HERE

rm -rf build # cleanup
mkdir build
cd build

cmake -DCMAKE_MODULE_PATH=@ECBUILD_MACROS_DIR@ -DECBUILD_LOG_LEVEL=DEBUG -DCMAKE_BUILD_TYPE=BIT -DECBUILD_SOURCE_FLAGS=@CMAKE_CURRENT_SOURCE_DIR@/flags-sourceflags.json ..

cd ..

rm -rf build # cleanup
mkdir build
cd build

cmake -DCMAKE_MODULE_PATH=@ECBUILD_MACROS_DIR@ -DECBUILD_LOG_LEVEL=DEBUG -DCMAKE_BUILD_TYPE=DEBUG -DECBUILD_SOURCE_FLAGS=@CMAKE_CURRENT_SOURCE_DIR@/flags-sourceflags.json ..

43 changes: 43 additions & 0 deletions tests/ecbuild_source_flags/test_ecbuild_source_flags.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
cmake_minimum_required( VERSION 3.12 FATAL_ERROR )

find_package( ecbuild 3.6 REQUIRED )

project(SourceFlags VERSION 1.0 LANGUAGES C CXX Fortran)

ecbuild_add_library(
TARGET overrideflags
SOURCES emptyfile.c emptyfile.cxx emptyfile.F90
)

get_property( _flags SOURCE emptyfile.c PROPERTY COMPILE_FLAGS )
if( CMAKE_BUILD_TYPE MATCHES BIT )
if( NOT ${_flags} MATCHES "-g -fPIC -O2" )
message(${_flags})
message(FATAL_ERROR "Incorrect BIT flags for emptyfile.c")
endif()
elseif( CMAKE_BUILD_TYPE MATCHES DEBUG )
if( NOT ${_flags} MATCHES "-g -fPIC -O0" )
message(${_flags})
message(FATAL_ERROR "Incorrect DEBUG flags for emptyfile.c")
endif()
endif()

get_property( _flags SOURCE emptyfile.cxx PROPERTY COMPILE_FLAGS )
if( CMAKE_BUILD_TYPE MATCHES BIT )
if( NOT ${_flags} MATCHES "-g -fPIC -O2" )
message(${_flags})
message(FATAL_ERROR "Incorrect BIT flags for emptyfile.cxx")
endif()
elseif( CMAKE_BUILD_TYPE MATCHES DEBUG )
if( NOT ${_flags} MATCHES "-g -fPIC -O0" )
message(${_flags})
message(FATAL_ERROR "Incorrect DEBUG flags for emptyfile.cxx")
endif()
endif()

get_property( _flags SOURCE emptyfile.F90 PROPERTY COMPILE_FLAGS )
if( NOT ${_flags} MATCHES "-g -fortran_only_flag" )
message(${_flags})
message(FATAL_ERROR "Incorrect flags for emptyfile.F90")
endif()

0 comments on commit ecb5fa9

Please sign in to comment.