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 (#442) #453

Merged
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
4 changes: 0 additions & 4 deletions test/core/CompilerOptions_UnitTests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -542,10 +542,6 @@ function(unitest_gcc_global_and_package_compiler_flags)
endfunction()






function(unitest_gcc_with_shadow_cleaned_checked_stl_coverage_options)

message("\n***")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,9 @@ endif()
get_regex_correct_cmake_lang_compiler(CXX)
get_regex_correct_cmake_lang_compiler(C)
get_regex_correct_cmake_lang_compiler(Fortran)

if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(COMPILER_IS_GNU TRUE)
else()
set(COMPILER_IS_GNU FALSE)
endif()
143 changes: 143 additions & 0 deletions test/core/ExamplesUnitTests/TribitsExampleProject_Tests.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2792,3 +2792,146 @@ tribits_add_advanced_test( TribitsExampleProject_DisableWithSubpackagesB_EnableW
# parent package is enabled at the end if any of its subpackages are enabled!
# This is also the only test that looks for the output that an optional
# package enable is not set.


########################################################################


tribits_add_advanced_test( TribitsExampleProject_compiler_flags
OVERALL_WORKING_DIRECTORY TEST_NAME
OVERALL_NUM_MPI_PROCS 1
EXCLUDE_IF_NOT_TRUE IS_REAL_LINUX_SYSTEM COMPILER_IS_GNU
${PROJECT_NAME}_ENABLE_Fortran

TEST_0
MESSAGE "Configure by setting targets compiler flags for some packages"
CMND ${CMAKE_COMMAND}
ARGS
-DTribitsExProj_TRIBITS_DIR=${${PROJECT_NAME}_TRIBITS_DIR}
-DTribitsExProj_ENABLE_Fortran=ON
-DTribitsExProj_ENABLE_ALL_PACKAGES=ON
-DTribitsExProj_ENABLE_SECONDARY_TESTED_CODE=ON
-DTribitsExProj_PRINT_PACKAGE_COMPILER_FLAGS=ON
-DCMAKE_C_FLAGS=-O2
-DCMAKE_CXX_FLAGS=-Og
-DCMAKE_Fortran_FLAGS=-Ofast
-DSimpleCxx_C_FLAGS="--scxx-c-flags1 --scxx-c-flags2"
-DSimpleCxx_CXX_FLAGS="--scxx-cxx-flags1 --scxx-cxx-flags2"
-DSimpleCxx_Fortran_FLAGS="--scxx-f-flags1 --scxx-f-flags2"
-DMixedLang_Fortran_FLAGS="--ml-f-flags1 --ml-f-flags2"
-DWithSubpackages_C_FLAGS="--wsp-c-flags1 --wsp-c-flags2"
-DWithSubpackages_CXX_FLAGS="--wsp-cxx-flags1 --wsp-cxx-flags2"
-DWithSubpackages_Fortran_FLAGS="--wsp-f-flags1 --wsp-f-flags2"
-DWithSubpackagesB_C_FLAGS="--wspb-c-flags1 --wspb-c-flags2"
-DWithSubpackagesB_CXX_FLAGS="--wspb-cxx-flags1 --wspb-cxx-flags2"
-DWithSubpackagesB_Fortarn_FLAGS="--wspb-f-flags1 --wspb-f-flags2"
${${PROJECT_NAME}_TRIBITS_DIR}/examples/TribitsExampleProject
PASS_REGULAR_EXPRESSION_ALL
"-- SimpleCxx: CMAKE_C_FLAGS=. -pedantic -Wall -Wno-long-long -std=c99 *-O2 --scxx-c-flags1 --scxx-c-flags2."
"-- SimpleCxx: CMAKE_C_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- SimpleCxx: CMAKE_CXX_FLAGS=. -pedantic -Wall -Wno-long-long -Wwrite-strings -Wshadow -Woverloaded-virtual *-Og --scxx-cxx-flags1 --scxx-cxx-flags2."
"-- SimpleCxx: CMAKE_CXX_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- SimpleCxx: CMAKE_Fortran_FLAGS=. *-Ofast --scxx-f-flags1 --scxx-f-flags2."
"-- SimpleCxx: CMAKE_Fortran_FLAGS_RELEASE=.-O3."
"-- Performing Test HAVE_SIMPLECXX___INT64"
"-- Performing Test HAVE_SIMPLECXX___INT64 - Failed"
"-- MixedLang: CMAKE_C_FLAGS=. -pedantic -Wall -Wno-long-long -std=c99."
"-- MixedLang: CMAKE_C_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- MixedLang: CMAKE_CXX_FLAGS=. -pedantic -Wall -Wno-long-long -Wwrite-strings -Wshadow -Woverloaded-virtual *-Og."
"-- MixedLang: CMAKE_CXX_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- MixedLang: CMAKE_Fortran_FLAGS=. *-Ofast ."
"-- MixedLang: CMAKE_Fortran_FLAGS_RELEASE=.-O3."
"-- WithSubpackages: CMAKE_C_FLAGS=. -pedantic -Wall -Wno-long-long -std=c99 *-O2 --wsp-c-flags1 --wsp-c-flags2."
"-- WithSubpackages: CMAKE_C_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- WithSubpackages: CMAKE_CXX_FLAGS=. -pedantic -Wall -Wno-long-long -Wwrite-strings *-Og --wsp-cxx-flags1 --wsp-cxx-flags2."
"-- WithSubpackages: CMAKE_CXX_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- WithSubpackages: CMAKE_Fortran_FLAGS=. *-Ofast --wsp-f-flags1 --wsp-f-flags2."
"-- WithSubpackages: CMAKE_Fortran_FLAGS_RELEASE=.-O3."
"-- WithSubpackagesA: CMAKE_C_FLAGS=. -pedantic -Wall -Wno-long-long -std=c99 *-O2 --wsp-c-flags1 --wsp-c-flags2."
"-- WithSubpackagesA: CMAKE_C_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- WithSubpackagesA: CMAKE_CXX_FLAGS=. -pedantic -Wall -Wno-long-long -Wwrite-strings *-Og --wsp-cxx-flags1 --wsp-cxx-flags2."
"-- WithSubpackagesA: CMAKE_CXX_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- WithSubpackagesA: CMAKE_Fortran_FLAGS=. *-Ofast --wsp-f-flags1 --wsp-f-flags2."
"-- WithSubpackagesA: CMAKE_Fortran_FLAGS_RELEASE=.-O3."
"-- WithSubpackagesB: CMAKE_C_FLAGS=. -pedantic -Wall -Wno-long-long -std=c99 *-O2 --wsp-c-flags1 --wsp-c-flags2 --wspb-c-flags1 --wspb-c-flags2."
"-- WithSubpackagesB: CMAKE_C_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- WithSubpackagesB: CMAKE_CXX_FLAGS=. -pedantic -Wall -Wno-long-long -Wwrite-strings *-Og --wsp-cxx-flags1 --wsp-cxx-flags2 --wspb-cxx-flags1 --wspb-cxx-flags2."
"-- WithSubpackagesB: CMAKE_CXX_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- WithSubpackagesB: CMAKE_Fortran_FLAGS=. *-Ofast --wsp-f-flags1 --wsp-f-flags2."
"-- WithSubpackagesB: CMAKE_Fortran_FLAGS_RELEASE=.-O3."
"-- WithSubpackagesC: CMAKE_C_FLAGS=. -pedantic -Wall -Wno-long-long -std=c99 *-O2 --wsp-c-flags1 --wsp-c-flags2."
"-- WithSubpackagesC: CMAKE_C_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- WithSubpackagesC: CMAKE_CXX_FLAGS=. -pedantic -Wall -Wno-long-long -Wwrite-strings *-Og --wsp-cxx-flags1 --wsp-cxx-flags2."
"-- WithSubpackagesC: CMAKE_CXX_FLAGS_RELEASE=.-O3 -DNDEBUG."
"-- WithSubpackagesC: CMAKE_Fortran_FLAGS=. *-Ofast --wsp-f-flags1 --wsp-f-flags2."
"-- WithSubpackagesC: CMAKE_Fortran_FLAGS_RELEASE=.-O3."
ALWAYS_FAIL_ON_NONZERO_RETURN
# NOTE: Above, we have to use real compiler options for CMAKE_<LANG>_FLAGS
# or the configure-time checks will not even work. We can only use dummy
# compiler options for the packages themselves.

TEST_1
MESSAGE "Build a SimpleCxx C++ file and check the compiler operations (we know build will fail)"
WORKING_DIRECTORY packages/simple_cxx/src
SKIP_CLEAN_WORKING_DIRECTORY
CMND make
ARGS
VERBOSE=1 SimpleCxx_HelloWorld.o
PASS_REGULAR_EXPRESSION_ALL
"-pedantic -Wall -Wno-long-long -Wwrite-strings -Wshadow -Woverloaded-virtual *-Og --scxx-cxx-flags1 --scxx-cxx-flags2 -O3 -DNDEBUG *-std=c[+][+]11"

TEST_2
MESSAGE "Build a MixedLang Fortran file and check the compiler operations (we know build will fail)"
WORKING_DIRECTORY packages/mixed_lang/src
SKIP_CLEAN_WORKING_DIRECTORY
CMND make
ARGS
VERBOSE=1 Parameters.o
PASS_REGULAR_EXPRESSION_ALL
"--ml-f-flags1 --ml-f-flags2 -O3 *-c"

TEST_3
MESSAGE "Build a WithSubpackagesA C++ file and check the compiler operations (we know build will fail)"
WORKING_DIRECTORY packages/with_subpackages/a
SKIP_CLEAN_WORKING_DIRECTORY
CMND make
ARGS
VERBOSE=1 A.o
PASS_REGULAR_EXPRESSION_ALL
"-pedantic -Wall -Wno-long-long -Wwrite-strings *-Og --wsp-cxx-flags1 --wsp-cxx-flags2 -O3 -DNDEBUG *-std=c[+][+]11"
# NOTE: Above regex ensures that flags for WithSubpackagesB are not listed

TEST_4
MESSAGE "Build a WithSubpackagesB C++ file and check the compiler operations (we know build will fail)"
WORKING_DIRECTORY packages/with_subpackages/b/src
SKIP_CLEAN_WORKING_DIRECTORY
CMND make
ARGS
VERBOSE=1 B.o
PASS_REGULAR_EXPRESSION_ALL
"-pedantic -Wall -Wno-long-long -Wwrite-strings *-Og --wsp-cxx-flags1 --wsp-cxx-flags2 --wspb-cxx-flags1 --wspb-cxx-flags2 -O3 -DNDEBUG *-std=c[+][+]11"
# NOTE: Above regex ensures subpackage flags come after parent package flags

TEST_5
MESSAGE "Build a WithSubpackagesC C++ file and check the compiler operations (we know build will fail)"
WORKING_DIRECTORY packages/with_subpackages/c
SKIP_CLEAN_WORKING_DIRECTORY
CMND make
ARGS
VERBOSE=1 C.o
PASS_REGULAR_EXPRESSION_ALL
"-pedantic -Wall -Wno-long-long -Wwrite-strings *-Og --wsp-cxx-flags1 --wsp-cxx-flags2 -O3 -DNDEBUG *-std=c[+][+]11"
# NOTE: Above regex ensures that flags for WithSubpackagesB are not listed

)
# NOTE: The above tests checks the compiler flags that are set by TriBITS for
# the various use cases. This is a hard test to make portable because we
# really need to check that the comiler options are set all the way down. To
# make this more portable, we only do this on Linux systems and only with GCC.
#
# We actaully build known targets with 'make VERBOSE=1 <target>' and then grep
# the output to make sure the compiler flags drill down all the way to the
# actual targets.
#
# Note that we expect that as TriBITS evolves that the exact compiler options
# we be changed. But that is okay.
78 changes: 42 additions & 36 deletions tribits/core/package_arch/TribitsPackageSetupCompilerFlags.cmake
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 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
Loading