Skip to content

Commit

Permalink
Better document <Project>_IMPORTED_NO_SYSTEM and workarounds (TriBITS…
Browse files Browse the repository at this point in the history
…Pub#443)

* Mentioned dependence on CMake 3.23+

* Mentioned the behavior differences between -I and -isystem

* Mentioned it restores backward compatibility for the move to modern CMake

* Fixed typos and misspellings
  • Loading branch information
bartlettroscoe committed Mar 4, 2022
1 parent 6853204 commit 7ebae56
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 32 deletions.
25 changes: 19 additions & 6 deletions tribits/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,23 @@ ChangeLog for TriBITS

## 2022-03-02:

* **Added:** Added project-level cache varaible `<Project>_IMPORTED_NO_SYSTEM`
to set the `IMPORTED_NO_SYSTEM` property on the exported IMPORTED library
targets in the installed `<Package>Config.cmake` files (see updated TriBITS
documentation for `<Project>_IMPORTED_NO_SYSTEM`).
* **Added:** The project-level cache variable `<Project>_IMPORTED_NO_SYSTEM`
was added to set the `IMPORTED_NO_SYSTEM` property (CMake versions 3.23+
only) on the exported IMPORTED library targets in the installed
`<Package>Config.cmake` files (see updated TriBITS users guide and build
reference documentation for `<Project>_IMPORTED_NO_SYSTEM`). Setting this
to `ON` results in the include directories for this project's IMPORTED
library targets to be listed on the compile lines in downstream CMake
projects using `-I` instead of the default `-isystem` for IMPORTED library
targets. Therefore, setting this option to `ON` returns backward
compatibility for the move to modern CMake targets which involved setting
the include directories on the IMPORTED library targets using
`target_include_directories()` described below (which changed the include
directories from being listed as `-I` to `-isystem` by default).<br>
**Workaround:** As a workaround for CMake versions less than 3.23,
downstream CMake project's can set `CMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE` in
their CMake configure as described below.<br> For more details, see
[TriBITSPub/TriBITS#443](https://github.com/TriBITSPub/TriBITS/issues/443).

## 2021-11-18:

Expand All @@ -23,7 +36,7 @@ ChangeLog for TriBITS

* **Changed:** The `<Package>Config.cmake` for each enabled package generated
in the build directory tree have been moved from
`<buildDir>/packages/<packageDir>/` to
`<buildDir>/packages/<packaged>/` to
`<buildDir>/cmake_packages/<PackageName>/`. (This makes it easy for
`find_package(<PackageName>)` to find these files by simply adding the
directory `<buildDir>/cmake_packages` to `CMAKE_PREFIX_PATH` and then
Expand All @@ -43,7 +56,7 @@ ChangeLog for TriBITS
environments that have the same header file names in multiple include
directories searched by the compiler. Also, this will silence any regular
compiler warnings from headers found under these include
directories. ***Workarounds:*** One workaround for this is for the
directories.<br> ***Workarounds:*** One workaround for this is for the
downstream CMake project to set the cache variable
`CMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE` which will restore the include
directories for the IMPORTED library targets for the TriBITS project as
Expand Down
48 changes: 37 additions & 11 deletions tribits/doc/build_ref/TribitsBuildReferenceBody.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1405,20 +1405,46 @@ Changing include directories in downstream CMake projects to non-system
-----------------------------------------------------------------------

By default, include directories from IMPORTED library targets from the
<Project>'s installed ``<Project>Config.cmake`` files will be considered
``SYSTEM`` headers and therefore be included on the compile lines of
downstream CMake projects with ``-isystem`` with most compilers. However,
if::
<Project> project's installed ``<Package>Config.cmake`` files will be
considered ``SYSTEM`` headers and therefore will be included on the compile
lines of downstream CMake projects with ``-isystem`` with most compilers.
However, when using CMake 3.23+, by configuring with::

-D ${PROJECT_NAME}_IMPORTED_NO_SYSTEM=ON

is set, then all of the IMPORTED library targets exported into the set of
installed ``<Package>Config.cmake`` files will have the ``IMPORTED_NO_SYSTEM``
target property set. This will cause downstream customer CMake projects to
apply the include directories from these IMPORTED library targets as
non-system include directories. On most compilers, that means that the
include directories will be listed on the compile lines with ``-I`` instead of
with ``-isystem``.
then all of the IMPORTED library targets exported into the set of installed
``<Package>Config.cmake`` files will have the ``IMPORTED_NO_SYSTEM`` target
property set. This will cause downstream customer CMake projects to apply the
include directories from these IMPORTED library targets as non-system include
directories. On most compilers, that means that the include directories will
be listed on the compile lines with ``-I`` instead of with ``-isystem`` (for
compilers that support the ``-isystem`` option). (Changing from ``-isystem
<incl-dir>`` to ``-I <incl-dir>`` moves ``<incl-dir>`` forward in the
compiler's include directory search order and could also result in the found
header files emitting compiler warnings that would other otherwise be silenced
when the headers were found in include directories pulled in with
``-isystem``.)

**NOTE:** Setting ``${PROJECT_NAME}_IMPORTED_NO_SYSTEM=ON`` when using a CMake
version less than 3.23 will result in a fatal configure error (so don't do
that).

**A workaround for CMake versions less than 3.23** is for **downstream
customer CMake projects** to set the native CMake cache variable::

-D CMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE

This will result in **all** include directories from **all** IMPORTED library
targets used in the downstream customer CMake project to be listed on the
compile lines using ``-I`` instead of ``-isystem``, and not just for the
IMPORTED library targets from this <Project> project's installed
``<Package>Config.cmake`` files!

**NOTE:** Setting ``CMAKE_NO_SYSTEM_FROM_IMPORTED=TRUE`` the <Project> CMake
configure will **not** result in changing how include directories from
<Project>'s IMPORTED targets are handled in a downstream customer CMake
project! It will only change how include directories from upstream package's
IMPORTED targets are handled in the <Project> CMake project build itself.


Enabling the usage of resource files to reduce length of build lines
Expand Down
36 changes: 21 additions & 15 deletions tribits/doc/guides/TribitsCoreDetailedReference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -497,24 +497,30 @@ These options are described below.
**${PROJECT_NAME}_IMPORTED_NO_SYSTEM**

By default, include directories from IMPORTED library targets from the
TriBITS project's installed ``<Project>Config.cmake`` files will be
TriBITS project's installed ``<Package>Config.cmake`` files will be
considered ``SYSTEM`` headers and therefore be included on the compile lines
of downstream CMake projects with ``-isystem`` with most compilers.
However, if ``${PROJECT_NAME}_IMPORTED_NO_SYSTEM`` is set to ``ON``, then
all of the IMPORTED library targets exported into the set of installed
``<Package>Config.cmake`` files will have the ``IMPORTED_NO_SYSTEM``
property set. This will cause downstream customer CMake projects to apply
the include directories from these IMPORTED library targets as non-system
include directories. On most compilers, that means that the include
directories will be listed on the compile lines with ``-I`` instead of with
``-isystem``.

The default is ``OFF`` but a TriBITS project can set a different default by
setting::

set(${PROJECT_NAME}_IMPORTED_NO_SYSTEM_DEFAULT ON)
However, if ``${PROJECT_NAME}_IMPORTED_NO_SYSTEM`` is set to ``ON`` (only
supported for CMake versions 3.23 or greater), then all of the IMPORTED
library targets exported into the set of installed ``<Package>Config.cmake``
files will have the ``IMPORTED_NO_SYSTEM`` property set. This will cause
downstream customer CMake projects to apply the include directories from
these IMPORTED library targets as non-system include directories. On most
compilers, that means that the include directories will be listed on the
compile lines with ``-I`` instead of with ``-isystem``.

The default is ``OFF`` but a TriBITS project can default to ``ON`` by
adding::

if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.23)
set(${PROJECT_NAME}_IMPORTED_NO_SYSTEM_DEFAULT ON)
endif()

in the `<projectDir>/ProjectName.cmake`_ file.
in the `<projectDir>/ProjectName.cmake`_ file. (NOTE: The above ``if()``
statement ensures that a configure error will not occur if a version of
CMake less than 3.23 is used. But if the TriBITS project minimum CMake
version is 3.23 or greater, then the above ``if()`` statement guard can be
removed.)


.. _${PROJECT_NAME}_INSTALL_LIBRARIES_AND_HEADERS:
Expand Down

0 comments on commit 7ebae56

Please sign in to comment.