Skip to content

Commit 4be34fe

Browse files
awnawabwdeconinck
authored andcommitted
Add ecbuild_override_compiler_flags macro
1 parent 28a6cbf commit 4be34fe

File tree

9 files changed

+187
-64
lines changed

9 files changed

+187
-64
lines changed

‎cmake/ecbuild_compiler_flags.cmake‎

Lines changed: 94 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -111,38 +111,99 @@ macro( ecbuild_purge_compiler_flags _lang )
111111

112112
endmacro()
113113

114-
macro( ecbuild_init_overrideable_compiler_flags )
114+
##############################################################################
115+
#.rst:
116+
#
117+
# ecbuild_linker_flags
118+
# ====================
119+
#
120+
# Apply user or toolchain specified linker flag overrides per object type (NOT written to cache)
121+
#
122+
# ecbuild_linker_flags()
123+
#
124+
##############################################################################
125+
126+
macro( ecbuild_linker_flags )
127+
foreach( _obj EXE SHARED MODULE )
128+
if( ECBUILD_${_obj}_LINKER_FLAGS )
129+
set( CMAKE_${_obj}_LINKER_FLAGS ${ECBUILD_${_obj}_LINKER_FLAGS} )
130+
endif()
131+
132+
if( NOT "$ENV{LD_RUN_PATH}" EQUAL "" )
133+
set( LD_RUN_PATH "$ENV{LD_RUN_PATH}" )
134+
string( REPLACE ":" ";" LD_RUN_PATH "$ENV{LD_RUN_PATH}" )
135+
foreach( rpath ${LD_RUN_PATH} )
136+
ecbuild_regex_escape( "${rpath}" rpath_escaped )
137+
if( NOT CMAKE_${_obj}_LINKER_FLAGS MATCHES ".*-Wl,-rpath,${rpath_escaped}.*")
138+
set( CMAKE_${_obj}_LINKER_FLAGS "${CMAKE_${_obj}_LINKER_FLAGS} -Wl,-rpath,${rpath}" )
139+
endif()
140+
endforeach()
141+
endif()
142+
endforeach()
143+
144+
foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
145+
146+
foreach( _obj EXE SHARED MODULE )
147+
if( ECBUILD_${_obj}_LINKER_FLAGS_${_btype} )
148+
set( CMAKE_${_obj}_LINKER_FLAGS_${_btype} ${ECBUILD_${_obj}_LINKER_FLAGS_${_btype}} )
149+
endif()
150+
endforeach()
151+
152+
endforeach()
153+
endmacro()
154+
155+
##############################################################################
156+
#.rst:
157+
#
158+
# ecbuild_override_compiler_flags
159+
# ======================
160+
#
161+
# Purge existing CMAKE_<lang>_FLAGS flags and trigger the use of per source
162+
# file overrideable flags (see ``Using custom compilation flags`` for an
163+
# explanation).
164+
#
165+
# ecbuild_override_compiler_flags()
166+
#
167+
##############################################################################
115168

116-
set( options CAPTURE_BUNDLE_FLAGS )
169+
macro( ecbuild_override_compiler_flags )
170+
171+
set( options "" )
117172
set( oneValueArgs SOURCE_FLAGS COMPILE_FLAGS )
118-
set( multiValueArgs LANGUAGES )
173+
set( multiValueArgs "" )
119174

120175
cmake_parse_arguments( _PAR "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
121176

122-
foreach(_lang ${_PAR_LANGUAGES} )
123-
ecbuild_purge_compiler_flags( ${_lang} WARN )
124-
endforeach()
125-
126-
if( ${_PAR_CAPTURE_BUNDLE_FLAGS} )
127-
foreach(_lang ${_PAR_LANGUAGES} )
128-
set( ${PNAME}_${_lang}_FLAGS "${${PNAME}_${_lang}_FLAGS} ${ECBUILD_${_lang}_FLAGS}" )
129-
foreach(_btype ALL RELEASE RELWITHDEBINFO PRODUCTION BIT DEBUG)
130-
set( ${PNAME}_${_lang}_FLAGS_${_btype} "${${PNAME}_${_lang}_FLAGS_${_btype}} ${ECBUILD_${_lang}_FLAGS_${_btype}}" )
131-
endforeach()
177+
# Ensure COMPILE/SOURCE_FLAGS is a valid file path
178+
if( DEFINED _PAR_COMPILE_FLAGS AND NOT EXISTS ${_PAR_COMPILE_FLAGS} )
179+
ecbuild_warn( "COMPILE_FLAGS points to non-existent file ${_PAR_COMPILE_FLAGS} and will be ignored" )
180+
unset( ECBUILD_COMPILE_FLAGS )
181+
unset( ECBUILD_COMPILE_FLAGS CACHE )
182+
elseif( DEFINED _PAR_SOURCE_FLAGS AND NOT EXISTS ${_PAR_SOURCE_FLAGS} )
183+
ecbuild_warn( "SOURCE_FLAGS points to non-existent file ${_PAR_SOURCE_FLAGS} and will be ignored" )
184+
unset( ECBUILD_SOURCE_FLAGS )
185+
unset( ECBUILD_SOURCE_FLAGS CACHE )
186+
elseif( DEFINED _PAR_SOURCE_FLAGS OR DEFINED _PAR_COMPILE_FLAGS )
187+
foreach( _lang C CXX Fortran )
188+
if( CMAKE_${_lang}_COMPILER_LOADED )
189+
ecbuild_purge_compiler_flags( ${_lang} WARN )
190+
endif()
132191
endforeach()
133-
endif()
134-
135-
if( DEFINED _PAR_COMPILE_FLAGS )
136-
if( DEFINED ECBUILD_COMPILE_FLAGS)
137-
ecbuild_debug( "Override ECBUILD_COMPILE_FLAGS (${ECBUILD_COMPILE_FLAGS}) with ${_PAR_COMPILE_FLAGS}" )
138-
endif()
139-
set( ECBUILD_COMPILE_FLAGS ${_PAR_COMPILE_FLAGS} )
140-
include( ${ECBUILD_COMPILE_FLAGS} )
141-
elseif( DEFINED _PAR_SOURCE_FLAGS )
142-
if( DEFINED ECBUILD_SOURCE_FLAGS)
143-
ecbuild_debug( "Override ECBUILD_SOURCE_FLAGS (${ECBUILD_SOURCE_FLAGS}) with ${_PAR_SOURCE_FLAGS}" )
192+
193+
if( DEFINED _PAR_COMPILE_FLAGS )
194+
if( DEFINED ECBUILD_COMPILE_FLAGS)
195+
ecbuild_debug( "Override ECBUILD_COMPILE_FLAGS (${ECBUILD_COMPILE_FLAGS}) with ${_PAR_COMPILE_FLAGS}" )
196+
endif()
197+
set( ECBUILD_COMPILE_FLAGS ${_PAR_COMPILE_FLAGS} )
198+
include( ${ECBUILD_COMPILE_FLAGS} )
199+
elseif( DEFINED _PAR_SOURCE_FLAGS )
200+
if( DEFINED ECBUILD_SOURCE_FLAGS)
201+
ecbuild_debug( "Override ECBUILD_SOURCE_FLAGS (${ECBUILD_SOURCE_FLAGS}) with ${_PAR_SOURCE_FLAGS}" )
202+
endif()
203+
set( ECBUILD_SOURCE_FLAGS ${_PAR_SOURCE_FLAGS} )
144204
endif()
145-
set( ECBUILD_SOURCE_FLAGS ${_PAR_SOURCE_FLAGS} )
205+
206+
ecbuild_linker_flags()
146207
endif()
147208

148209
endmacro()
@@ -247,56 +308,25 @@ foreach( _flags COMPILE SOURCE )
247308
endif()
248309
set( ECBUILD_${_flags}_FLAGS ${${PROJECT_NAME_CAPS}_ECBUILD_${_flags}_FLAGS} )
249310
endif()
250-
# Ensure ECBUILD_${_flags}_FLAGS is a valid file path
251-
if( DEFINED ECBUILD_${_flags}_FLAGS AND NOT EXISTS ${ECBUILD_${_flags}_FLAGS} )
252-
ecbuild_warn( "ECBUILD_${_flags}_FLAGS points to non-existent file ${ECBUILD_${_flags}_FLAGS} and will be ignored" )
253-
unset( ECBUILD_${_flags}_FLAGS )
254-
unset( ECBUILD_${_flags}_FLAGS CACHE )
255-
endif()
256311
endforeach()
257-
if( ECBUILD_COMPILE_FLAGS )
258-
include( "${ECBUILD_COMPILE_FLAGS}" )
312+
if( DEFINED ECBUILD_COMPILE_FLAGS )
313+
ecbuild_override_compiler_flags( COMPILE_FLAGS ${ECBUILD_COMPILE_FLAGS} )
314+
elseif( DEFINED ECBUILD_SOURCE_FLAGS )
315+
ecbuild_override_compiler_flags( SOURCE_FLAGS ${ECBUILD_SOURCE_FLAGS} )
259316
endif()
260317

261318
foreach( _lang C CXX Fortran )
262319
if( CMAKE_${_lang}_COMPILER_LOADED )
263320

264-
# Clear default compilation flags potentially inherited from parent scope
265-
# when using custom compilation flags
266-
if( ECBUILD_SOURCE_FLAGS OR ECBUILD_COMPILE_FLAGS )
267-
ecbuild_purge_compiler_flags( ${_lang} )
268321
# Load default compilation flags only if custom compilation flags not enabled
269-
else()
322+
if( NOT (DEFINED ECBUILD_SOURCE_FLAGS OR DEFINED ECBUILD_COMPILE_FLAGS) )
270323
ecbuild_compiler_flags( ${_lang} )
271324
endif()
272325

273326
endif()
274327
endforeach()
275328

276-
# Apply user or toolchain specified linker flag overrides per object type (NOT written to cache)
277-
foreach( _obj EXE SHARED MODULE )
278-
if( ECBUILD_${_obj}_LINKER_FLAGS )
279-
set( CMAKE_${_obj}_LINKER_FLAGS ${ECBUILD_${_obj}_LINKER_FLAGS} )
280-
endif()
281-
282-
if( NOT "$ENV{LD_RUN_PATH}" EQUAL "" )
283-
set( LD_RUN_PATH "$ENV{LD_RUN_PATH}" )
284-
string( REPLACE ":" ";" LD_RUN_PATH "$ENV{LD_RUN_PATH}" )
285-
foreach( rpath ${LD_RUN_PATH} )
286-
ecbuild_regex_escape( "${rpath}" rpath_escaped )
287-
if( NOT CMAKE_${_obj}_LINKER_FLAGS MATCHES ".*-Wl,-rpath,${rpath_escaped}.*")
288-
set( CMAKE_${_obj}_LINKER_FLAGS "${CMAKE_${_obj}_LINKER_FLAGS} -Wl,-rpath,${rpath}" )
289-
endif()
290-
endforeach()
291-
endif()
292-
endforeach()
293-
294-
foreach( _btype NONE DEBUG BIT PRODUCTION RELEASE RELWITHDEBINFO )
295-
296-
foreach( _obj EXE SHARED MODULE )
297-
if( ECBUILD_${_obj}_LINKER_FLAGS_${_btype} )
298-
set( CMAKE_${_obj}_LINKER_FLAGS_${_btype} ${ECBUILD_${_obj}_LINKER_FLAGS_${_btype}} )
299-
endif()
300-
endforeach()
329+
if( NOT DEFINED ECBUILD_COMPILE_FLAGS AND NOT DEFINED ECBUILD_SOURCE_FLAGS )
330+
ecbuild_linker_flags()
331+
endif()
301332

302-
endforeach()

‎tests/CMakeLists.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ add_subdirectory( ecbuild_shared_libs )
1111
add_subdirectory( interface_library )
1212
add_subdirectory( project_import )
1313
add_subdirectory( project_summary )
14+
add_subdirectory( ecbuild_override_compiler_flags )
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
set(_dir ${CMAKE_CURRENT_BINARY_DIR})
2+
configure_file(run-test.sh.in ${_dir}/run-test.sh @ONLY)
3+
configure_file(test_ecbuild_override_compiler_flags.cmake ${_dir}/CMakeLists.txt COPYONLY)
4+
configure_file(emptyfile.c ${_dir}/emptyfile.c COPYONLY)
5+
configure_file(emptyfile.cxx ${_dir}/emptyfile.cxx COPYONLY)
6+
configure_file(emptyfile.F90 ${_dir}/emptyfile.F90 COPYONLY)
7+
configure_file(compiler_flags.cmake ${_dir}/compiler_flags.cmake COPYONLY)
8+
9+
ecbuild_add_test(
10+
TARGET test_ecbuild_override_compiler_flags
11+
TYPE SCRIPT
12+
COMMAND run-test.sh
13+
)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
set( OVERRIDECOMPILERFLAGS_C_FLAGS "-g -fPIC" )
2+
set( OVERRIDECOMPILERFLAGS_CXX_FLAGS "-g -fPIC" )
3+
set( OVERRIDECOMPILERFLAGS_Fortran_FLAGS "-g -fortran_only_flag" )
4+
5+
set( OVERRIDECOMPILERFLAGS_C_FLAGS_DEBUG "-O0" )
6+
set( OVERRIDECOMPILERFLAGS_CXX_FLAGS_DEBUG "-O0" )
7+
8+
set( OVERRIDECOMPILERFLAGS_C_FLAGS_BIT "-O2" )
9+
set( OVERRIDECOMPILERFLAGS_CXX_FLAGS_BIT "-O2" )
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
! An empty file
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// An empty file
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// An empty file
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
HERE="$( cd $( dirname "${BASH_SOURCE[0]}" ) && pwd -P )"
6+
7+
cd $HERE
8+
9+
rm -rf build # cleanup
10+
mkdir build
11+
cd build
12+
13+
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 ..
14+
15+
cd ..
16+
17+
rm -rf build # cleanup
18+
mkdir build
19+
cd build
20+
21+
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 ..
22+
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
cmake_minimum_required( VERSION 3.12 FATAL_ERROR )
2+
3+
find_package( ecbuild 3.6 REQUIRED )
4+
5+
project(OverrideCompilerFlags VERSION 1.0 LANGUAGES C CXX Fortran)
6+
7+
ecbuild_override_compiler_flags( COMPILE_FLAGS compiler_flags.cmake )
8+
9+
ecbuild_add_library(
10+
TARGET overrideflags
11+
SOURCES emptyfile.c emptyfile.cxx emptyfile.F90
12+
)
13+
14+
get_property( _flags SOURCE emptyfile.c PROPERTY COMPILE_FLAGS )
15+
if( CMAKE_BUILD_TYPE MATCHES BIT )
16+
if( NOT ${_flags} MATCHES "-g -fPIC -O2" )
17+
message(${_flags})
18+
message(FATAL_ERROR "Incorrect BIT flags for emptyfile.c")
19+
endif()
20+
elseif( CMAKE_BUILD_TYPE MATCHES DEBUG )
21+
if( NOT ${_flags} MATCHES "-g -fPIC -O0" )
22+
message(${_flags})
23+
message(FATAL_ERROR "Incorrect DEBUG flags for emptyfile.c")
24+
endif()
25+
endif()
26+
27+
get_property( _flags SOURCE emptyfile.cxx PROPERTY COMPILE_FLAGS )
28+
if( CMAKE_BUILD_TYPE MATCHES BIT )
29+
if( NOT ${_flags} MATCHES "-g -fPIC -O2" )
30+
message(${_flags})
31+
message(FATAL_ERROR "Incorrect BIT flags for emptyfile.cxx")
32+
endif()
33+
elseif( CMAKE_BUILD_TYPE MATCHES DEBUG )
34+
if( NOT ${_flags} MATCHES "-g -fPIC -O0" )
35+
message(${_flags})
36+
message(FATAL_ERROR "Incorrect DEBUG flags for emptyfile.cxx")
37+
endif()
38+
endif()
39+
40+
get_property( _flags SOURCE emptyfile.F90 PROPERTY COMPILE_FLAGS )
41+
if( NOT ${_flags} MATCHES "-g -fortran_only_flag" )
42+
message(${_flags})
43+
message(FATAL_ERROR "Incorrect flags for emptyfile.F90")
44+
endif()
45+

0 commit comments

Comments
 (0)