Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for subpackage-specific compiler flags (#10111) #10219

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,75 +58,87 @@ macro(tribits_apply_warnings_as_error_flags_lang LANG)
endmacro()


macro(tribits_set_package_language_flags LANG)
macro(tribits_set_package_compiler_lang_flags LANG)

#message("Entering tribits_set_package_language_flags(${LANG})")
#message("Entering tribits_set_package_compiler_lang_flags(${LANG})")
#print_var(${PROJECT_NAME}_ENABLE_STRONG_${LANG}_COMPILE_WARNINGS)

if (${PACKAGE_NAME}_${LANG}_FLAGS)
dual_scope_append_cmndline_args(CMAKE_${LANG}_FLAGS
"${${PACKAGE_NAME}_${LANG}_FLAGS}")
endif()

if(${PROJECT_NAME}_VERBOSE_CONFIGURE)
message(STATUS "Adding strong ${LANG} warning flags \"${${LANG}_STRONG_COMPILE_WARNING_FLAGS}\"")
print_var(CMAKE_${LANG}_FLAGS)
endif()

endmacro()


function(tribits_setup_add_package_compile_flags)
function(tribits_print_package_compiler_lang_flags LANG SUFFIX)
message("-- " "${PACKAGE_NAME}: CMAKE_${LANG}_FLAGS${SUFFIX}=\"${CMAKE_${LANG}_FLAGS${SUFFIX}}\"")
endfunction()


#message("Entering tribits_setup_add_package_compile_flags()")
# Function that appends package-specific compiler flags for each language
#
function(tribits_append_package_specific_compiler_flags)

#
# C compiler options
#
#message("Entering tribits_append_package_specific_compiler_flags() for ${PACKAGE_NAME}")

# C compiler options
assert_defined(${PROJECT_NAME}_ENABLE_C CMAKE_C_COMPILER_ID)
if (${PROJECT_NAME}_ENABLE_C)
tribits_set_package_language_flags(C)
tribits_set_package_compiler_lang_flags(C)
endif()

#
# C++ compiler options
#

assert_defined(${PROJECT_NAME}_ENABLE_CXX CMAKE_CXX_COMPILER_ID)
if (${PROJECT_NAME}_ENABLE_CXX)
tribits_set_package_language_flags(CXX)
tribits_set_package_compiler_lang_flags(CXX)
endif()

#
# Fortran compiler options
#

assert_defined(${PROJECT_NAME}_ENABLE_Fortran)
if (${PROJECT_NAME}_ENABLE_Fortran)
tribits_set_package_language_flags(Fortran)
tribits_set_package_compiler_lang_flags(Fortran)
endif()

endfunction()


# Function that prints out all of the compiler flags for a package
#
function(tribits_print_package_compiler_flags)

if(${PROJECT_NAME}_VERBOSE_CONFIGURE OR ${PROJECT_NAME}_PRINT_PACKAGE_COMPILER_FLAGS)

string(TOUPPER "${CMAKE_BUILD_TYPE}" upperBuildType)
set(buildNameSuffix "_${upperBuildType}")

# C compiler options
if (${PROJECT_NAME}_ENABLE_C)
tribits_print_package_compiler_lang_flags(C "")
tribits_print_package_compiler_lang_flags(C ${buildNameSuffix})
endif()

# C++ compiler options
if (${PROJECT_NAME}_ENABLE_CXX)
tribits_print_package_compiler_lang_flags(CXX "")
tribits_print_package_compiler_lang_flags(CXX ${buildNameSuffix})
endif()

# Fortran compiler options
if (${PROJECT_NAME}_ENABLE_Fortran)
tribits_print_package_compiler_lang_flags(Fortran "")
tribits_print_package_compiler_lang_flags(Fortran ${buildNameSuffix})
endif()

endif()

endfunction()




#
# Macro that sets up compiler flags for a package
# Macro that sets up compiler flags for a top-level package (not subpackage)
#
# This CMake code is broken out in order to allow it to be unit tested.
#

macro(tribits_setup_compiler_flags PACKAGE_NAME_IN)

# Set up strong warning flags
Expand All @@ -149,17 +161,11 @@ macro(tribits_setup_compiler_flags PACKAGE_NAME_IN)
tribits_apply_warnings_as_error_flags_lang(CXX)
endif()

# Append package specific options
tribits_setup_add_package_compile_flags()
tribits_append_package_specific_compiler_flags()

if (${PROJECT_NAME}_VERBOSE_CONFIGURE)
message("Final compiler flags:")
print_var(CMAKE_CXX_FLAGS)
print_var(CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE})
print_var(CMAKE_C_FLAGS)
print_var(CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE})
print_var(CMAKE_Fortran_FLAGS)
print_var(CMAKE_Fortran_FLAGS_${CMAKE_BUILD_TYPE})
if(${PROJECT_NAME}_VERBOSE_CONFIGURE)
message("Final package compiler flags:")
endif()
tribits_print_package_compiler_flags()

endmacro()
52 changes: 30 additions & 22 deletions cmake/tribits/core/package_arch/TribitsSubPackageMacros.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ include(TribitsPackageMacros)
include(TribitsReportInvalidTribitsUsage)


#
# @MACRO: tribits_subpackage()
#
# Forward declare a `TriBITS Subpackage`_ called at the top of the
Expand Down Expand Up @@ -78,18 +77,42 @@ macro(tribits_subpackage SUBPACKAGE_NAME_IN)
message("\nSUBPACKAGE: ${SUBPACKAGE_NAME_IN}")
endif()

tribits_subpackage_assert_call_context()

# To provide context for various macros
set(PACKAGE_NAME ${SUBPACKAGE_FULLNAME})

set(PARENT_PACKAGE_SOURCE_DIR "${PACKAGE_SOURCE_DIR}")
set(PARENT_PACKAGE_BINARY_DIR "${PACKAGE_BINARY_DIR}")

# Now override the package-like variables
tribits_set_common_vars(${SUBPACKAGE_FULLNAME})
tribits_define_linkage_vars(${SUBPACKAGE_FULLNAME})

tribits_append_package_specific_compiler_flags()
if(${PROJECT_NAME}_VERBOSE_CONFIGURE)
message("Final subpackage compiler flags:")
endif()
tribits_print_package_compiler_flags()

# Set flags that are used to check that macros are called in the correct order
set(${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_CALLED TRUE)
set(${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED FALSE)

endmacro()


function(tribits_subpackage_assert_call_context)

# check that this is not being called from a package
if (NOT CURRENTLY_PROCESSING_SUBPACKAGE)
# we are in a package

# we are in a package
tribits_report_invalid_tribits_usage(
"Cannot call tribits_subpackage() from a package."
" Use tribits_package() instead"
" ${CURRENT_PACKAGE_CMAKELIST_FILE}")

else()
# We are in a subpackage

# We are in a subpackage
# check to see if postprocess is called before subpackage
if(${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED)
tribits_report_invalid_tribits_usage(
Expand All @@ -113,25 +136,10 @@ macro(tribits_subpackage SUBPACKAGE_NAME_IN)
endif()
endif()

endfunction()

# To provide context for various macros
set(PACKAGE_NAME ${SUBPACKAGE_FULLNAME})

set(PARENT_PACKAGE_SOURCE_DIR "${PACKAGE_SOURCE_DIR}")
set(PARENT_PACKAGE_BINARY_DIR "${PACKAGE_BINARY_DIR}")

# Now override the package-like variables
tribits_set_common_vars(${SUBPACKAGE_FULLNAME})
tribits_define_linkage_vars(${SUBPACKAGE_FULLNAME})

# Set flags that are used to check that macros are called in the correct order
set(${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_CALLED TRUE)
set(${SUBPACKAGE_FULLNAME}_TRIBITS_SUBPACKAGE_POSTPROCESS_CALLED FALSE)

endmacro()


#
# @MACRO: tribits_subpackage_postprocess()
#
# Macro that performs standard post-processing after defining a `TriBITS
Expand Down
106 changes: 72 additions & 34 deletions cmake/tribits/doc/build_ref/TribitsBuildReferenceBody.rst
Original file line number Diff line number Diff line change
Expand Up @@ -769,19 +769,38 @@ then they must be the same or a configure error will occur.

Options can also be targeted to a specific TriBITS package using::

-D <TRIBITS_PACKAGE>_<LANG>_FLAGS="<EXTRA_COMPILER_OPTIONS>"
-D <TRIBITS_PACKAGE>_<LANG>_FLAGS="<PACKAGE_EXTRA_COMPILER_OPTIONS>"

The package-specific options get appended to those already in
The package-specific options get appended **after** those already in
``CMAKE_<LANG>_FLAGS`` and therefore override (but not replace) those set
globally in ``CMAKE_<LANG>_FLAGS`` (either internally or by the user in the
cache).
globally in ``CMAKE_<LANG>_FLAGS`` (either internally in the CMakeLists.txt
files or by the user in the cache).

In addition, flags can be targeted to a specific TriBITS subpackage using the
same syntax::

-D <TRIBITS_SUBPACKAGE>_<LANG>_FLAGS="<SUBPACKAGE_EXTRA_COMPILER_OPTIONS>"

If top-level package-specific flags and subpackage-specific flags are both set
for the same parent package such as with::

-D SomePackage_<LANG>_FLAGS="<Package-flags>" \
-D SomePackageSpkgA_<LANG>_FLAGS="<Subpackage-flags>" \

then the flags for the subpackage ``SomePackageSpkgA`` will be listed after
those for its parent package ``SomePackage`` on the compiler command-line as::

<Package-flags> <SubPackage-flags>

That way, compiler options for a subpackage override flags set for the parent
package.

NOTES:

1) Setting ``CMAKE_<LANG>_FLAGS`` will override but will not replace any
other internally set flags in ``CMAKE_<LANG>_FLAGS`` defined by the
<Project> CMake system because these flags will come after those set
internally. To get rid of these project/TriBITS default flags, see below.
1) Setting ``CMAKE_<LANG>_FLAGS`` as a cache varible by the user on input be
listed after and therefore override, but will not replace, any internally set
flags in ``CMAKE_<LANG>_FLAGS`` defined by the <Project> CMake system. To get
rid of these project/TriBITS set compiler flags/options, see the below items.

2) Given that CMake passes in flags in
``CMAKE_<LANG>_FLAGS_<CMAKE_BUILD_TYPE>`` after those in
Expand Down Expand Up @@ -830,30 +849,6 @@ internally by CMake and the new variable is needed to make the override
explicit.


Appending arbitrary libraries and link flags every executable
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

In order to append any set of arbitrary libraries and link flags to your
executables use::

-D<Project>_EXTRA_LINK_FLAGS="<EXTRA_LINK_LIBRARIES>" \
-DCMAKE_EXE_LINKER_FLAGS="<EXTRA_LINK_FLAGG>"

Above, you can pass any type of library and they will always be the last
libraries listed, even after all of the TPLs.

NOTE: This is how you must set extra libraries like Fortran libraries and
MPI libraries (when using raw compilers). Please only use this variable
as a last resort.

NOTE: You must only pass in libraries in ``<Project>_EXTRA_LINK_FLAGS`` and
*not* arbitrary linker flags. To pass in extra linker flags that are not
libraries, use the built-in CMake variable ``CMAKE_EXE_LINKER_FLAGS``
instead. The TriBITS variable ``<Project>_EXTRA_LINK_FLAGS`` is badly named
in this respect but the name remains due to backward compatibility
requirements.


Turning off strong warnings for individual packages
+++++++++++++++++++++++++++++++++++++++++++++++++++

Expand Down Expand Up @@ -934,8 +929,51 @@ To get the compiler to add debug symbols to the build, configure with::

-D <Project>_ENABLE_DEBUG_SYMBOLS=ON

This will add ``-g`` on most compilers. NOTE: One does **not** generally
need to create a fully debug build to get debug symbols on most compilers.
This will add ``-g`` on most compilers. NOTE: One does **not** generally need
to create a full debug build to get debug symbols on most compilers.


Printing out compiler flags for each package
++++++++++++++++++++++++++++++++++++++++++++

To print out the exact ``CMAKE_<LANG>_FLAGS`` that will be used for each
package, set::

-D <Project>_PRINT_PACKAGE_COMPILER_FLAGS=ON

That will print lines in STDOUT that are formatted as::

<TRIBITS_SUBPACKAGE>: CMAKE_<LANG>_FLAGS="<exact-flags-usedy-by-package>"
<TRIBITS_SUBPACKAGE>: CMAKE_<LANG>_FLAGS_<BUILD_TYPE>="<build-type-flags>"

This will print the value of the ``CMAKE_<LANG>_FLAGS`` and
``CMAKE_<LANG>_FLAGS_<BUILD_TYPE>`` variables that are used as each package is
being processed and will contain the flags in the exact order they are applied
by CMake


Appending arbitrary libraries and link flags every executable
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

In order to append any set of arbitrary libraries and link flags to your
executables use::

-D<Project>_EXTRA_LINK_FLAGS="<EXTRA_LINK_LIBRARIES>" \
-DCMAKE_EXE_LINKER_FLAGS="<EXTRA_LINK_FLAGG>"

Above, you can pass any type of library and they will always be the last
libraries listed, even after all of the TPLs.

NOTE: This is how you must set extra libraries like Fortran libraries and
MPI libraries (when using raw compilers). Please only use this variable
as a last resort.

NOTE: You must only pass in libraries in ``<Project>_EXTRA_LINK_FLAGS`` and
*not* arbitrary linker flags. To pass in extra linker flags that are not
libraries, use the built-in CMake variable ``CMAKE_EXE_LINKER_FLAGS``
instead. The TriBITS variable ``<Project>_EXTRA_LINK_FLAGS`` is badly named
in this respect but the name remains due to backward compatibility
requirements.


Enabling support for Ninja
Expand Down