Commit fa203ee3 authored by Robert Maynard's avatar Robert Maynard Committed by Brad King

Tutorial: Improve Step 10 generator expression example.

Use compiler flags and standard levels as the compelling argument
for using generator expressions and interface libraries
parent a1c6d7e9
cmake_minimum_required(VERSION 3.3)
cmake_minimum_required(VERSION 3.15)
project(Tutorial)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
# add compiler warning flags just when building this project via
# the BUILD_INTERFACE genex
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
# set the version number
set(Tutorial_VERSION_MAJOR 1)
......
......@@ -21,6 +21,7 @@ if(USE_MYMATH)
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
......@@ -44,14 +45,18 @@ if(USE_MYMATH)
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
target_compile_definitions(SqrtLibrary PRIVATE
"$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
"$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
)
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(SqrtLibrary
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>")
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# define the symbol stating we are using the declspec(dllexport) when
# building on windows
......@@ -62,7 +67,7 @@ set_property(TARGET MathFunctions PROPERTY VERSION "1.0.0")
set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
# install rules
install(TARGETS MathFunctions
install(TARGETS MathFunctions tutorial_compiler_flags
DESTINATION lib
EXPORT MathFunctionsTargets)
install(FILES MathFunctions.h DESTINATION include)
cmake_minimum_required(VERSION 3.3)
cmake_minimum_required(VERSION 3.15)
project(Tutorial)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
# add compiler warning flags just when building this project via
# the BUILD_INTERFACE genex
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
target_compile_options(tutorial_compiler_flags INTERFACE
"$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
"$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)
# set the version number
set(Tutorial_VERSION_MAJOR 1)
......
......@@ -19,6 +19,7 @@ if(USE_MYMATH)
# first we add the executable that generates the table
add_executable(MakeTable MakeTable.cxx)
target_link_libraries(MakeTable tutorial_compiler_flags)
# add the command to generate the source code
add_custom_command(
......@@ -42,14 +43,17 @@ if(USE_MYMATH)
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
target_compile_definitions(SqrtLibrary PRIVATE
"$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
"$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
)
target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(SqrtLibrary
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
endif()
target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>")
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# define the symbol stating we are using the declspec(dllexport) when
#building on windows
......
......@@ -598,27 +598,47 @@ expressions are the 0 and 1 expressions. A ``$<0:...>`` results in the empty
string, and ``<1:...>`` results in the content of "...". They can also be
nested.
For example:
A common usage of generator expressions is to conditionally add compiler
flags, such as those as language levels or warnings. A nice pattern is
to associate this information to an ``INTERFACE`` target allowing this
information to propagate. Lets start by constructing an ``INTERFACE``
target and specifying the required C++ standard level of ``11`` instead
of using ``CMAKE_CXX_STANDARD``.
.. code-block:: cmake
So the following code:
.. literalinclude:: Step10/CMakeLists.txt
:language: cmake
:start-after: project(Tutorial)
:end-before: # Set the version number
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(SqrtLibrary
PRIVATE "HAVE_LOG" "HAVE_EXP")
endif()
Would be replaced with:
Can be rewritten with generator expressions:
.. literalinclude:: Step11/CMakeLists.txt
:language: cmake
:start-after: project(Tutorial)
:end-before: # add compiler warning flags just when building this project via
Next we add the desired compiler warning flags that we want for our
project. As warning flags vary based on the compiler we use
the ``COMPILE_LANG_AND_ID`` generator expression to control which
flags to apply given a language and a set of compiler ids as seen
below:
.. literalinclude:: Step11/CMakeLists.txt
:language: cmake
:start-after: # the BUILD_INTERFACE genex
:end-before: # set the version number
Looking at this we see that the warning flags are encapsulated inside a
``BUILD_INTERFACE`` condition. This is done so that consumers of our installed
project will not inherit our warning flags.
.. code-block:: cmake
target_compile_definitions(SqrtLibrary PRIVATE
"$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
"$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
)
**Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that
all targets have a ``target_link_libraries()`` call to ``tutorial_compiler_flags``.
Note that ``${HAVE_LOG}`` is evaluated at CMake configure time while
``$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>`` is evaluated at build system generation
time.
Adding Export Configuration (Step 11)
=====================================
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment