mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-05 21:31:08 -06:00
Merge topic 'clarify_inherited_properties'
ff6234509eHelp: Clarify behavior of INHERITED properties9cc97ab4dcTests: Add tests for INHERITED property chaining Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !1879
This commit is contained in:
@@ -34,10 +34,24 @@ actual scope needs to be given; only the kind of scope is important.
|
||||
The required ``PROPERTY`` option is immediately followed by the name of
|
||||
the property being defined.
|
||||
|
||||
If the ``INHERITED`` option then the :command:`get_property` command will
|
||||
chain up to the next higher scope when the requested property is not set
|
||||
in the scope given to the command. ``DIRECTORY`` scope chains to
|
||||
``GLOBAL``. ``TARGET``, ``SOURCE``, and ``TEST`` chain to ``DIRECTORY``.
|
||||
If the ``INHERITED`` option is given, then the :command:`get_property` command
|
||||
will chain up to the next higher scope when the requested property is not set
|
||||
in the scope given to the command.
|
||||
|
||||
* ``DIRECTORY`` scope chains to its parent directory's scope, continuing the
|
||||
walk up parent directories until a directory has the property set or there
|
||||
are no more parents. If still not found at the top level directory, it
|
||||
chains to the ``GLOBAL`` scope.
|
||||
* ``TARGET``, ``SOURCE`` and ``TEST`` properties chain to ``DIRECTORY`` scope,
|
||||
including further chaining up the directories, etc. as needed.
|
||||
|
||||
Note that this scope chaining behavior only applies to calls to
|
||||
:command:`get_property`, :command:`get_directory_property`,
|
||||
:command:`get_target_property`, :command:`get_source_file_property` and
|
||||
:command:`get_test_property`. There is no inheriting behavior when *setting*
|
||||
properties, so using ``APPEND`` or ``APPEND_STRING`` with the
|
||||
:command:`set_property` command will not consider inherited values when working
|
||||
out the contents to append to.
|
||||
|
||||
The ``BRIEF_DOCS`` and ``FULL_DOCS`` options are followed by strings to be
|
||||
associated with the property as its brief and full documentation.
|
||||
|
||||
@@ -7,11 +7,16 @@ Get a property of ``DIRECTORY`` scope.
|
||||
|
||||
get_directory_property(<variable> [DIRECTORY <dir>] <prop-name>)
|
||||
|
||||
Store a property of directory scope in the named variable. If the
|
||||
property is not defined the empty-string is returned. The ``DIRECTORY``
|
||||
argument specifies another directory from which to retrieve the
|
||||
property value. The specified directory must have already been
|
||||
traversed by CMake.
|
||||
Store a property of directory scope in the named ``<variable>``.
|
||||
The ``DIRECTORY`` argument specifies another directory from which
|
||||
to retrieve the property value instead of the current directory.
|
||||
The specified directory must have already been traversed by CMake.
|
||||
|
||||
If the property is not defined for the nominated directory scope,
|
||||
an empty string is returned. In the case of ``INHERITED`` properties,
|
||||
if the property is not found for the nominated directory scope,
|
||||
the search will chain to a parent scope as described for the
|
||||
:command:`define_property` command.
|
||||
|
||||
::
|
||||
|
||||
|
||||
@@ -50,7 +50,10 @@ be one of the following:
|
||||
|
||||
The required ``PROPERTY`` option is immediately followed by the name of
|
||||
the property to get. If the property is not set an empty value is
|
||||
returned. If the ``SET`` option is given the variable is set to a boolean
|
||||
returned, although some properties support inheriting from a parent scope
|
||||
if defined to behave that way (see :command:`define_property`).
|
||||
|
||||
If the ``SET`` option is given the variable is set to a boolean
|
||||
value indicating whether the property has been set. If the ``DEFINED``
|
||||
option is given the variable is set to a boolean value indicating
|
||||
whether the property has been defined such as with the
|
||||
|
||||
@@ -8,9 +8,15 @@ Get a property for a source file.
|
||||
get_source_file_property(VAR file property)
|
||||
|
||||
Get a property from a source file. The value of the property is
|
||||
stored in the variable ``VAR``. If the property is not found, ``VAR``
|
||||
will be set to "NOTFOUND". Use :command:`set_source_files_properties`
|
||||
to set property values. Source file properties usually control how the
|
||||
file is built. One property that is always there is :prop_sf:`LOCATION`
|
||||
stored in the variable ``VAR``. If the source property is not found, the
|
||||
behavior depends on whether it has been defined to be an ``INHERITED`` property
|
||||
or not (see :command:`define_property`). Non-inherited properties will set
|
||||
``VAR`` to "NOTFOUND", whereas inheritied properties will search the relevent
|
||||
parent scope as described for the :command:`define_property` command and
|
||||
if still unable to find the property, ``VAR`` will be set to an empty string.
|
||||
|
||||
Use :command:`set_source_files_properties` to set property values. Source
|
||||
file properties usually control how the file is built. One property that is
|
||||
always there is :prop_sf:`LOCATION`.
|
||||
|
||||
See also the more general :command:`get_property` command.
|
||||
|
||||
@@ -8,8 +8,15 @@ Get a property from a target.
|
||||
get_target_property(VAR target property)
|
||||
|
||||
Get a property from a target. The value of the property is stored in
|
||||
the variable ``VAR``. If the property is not found, ``VAR`` will be set to
|
||||
"NOTFOUND". Use :command:`set_target_properties` to set property values.
|
||||
the variable ``VAR``. If the target property is not found, the behavior
|
||||
depends on whether it has been defined to be an ``INHERITED`` property
|
||||
or not (see :command:`define_property`). Non-inherited properties will
|
||||
set ``VAR`` to "NOTFOUND", whereas inheritied properties will search the
|
||||
relevent parent scope as described for the :command:`define_property`
|
||||
command and if still unable to find the property, ``VAR`` will be set to
|
||||
an empty string.
|
||||
|
||||
Use :command:`set_target_properties` to set target property values.
|
||||
Properties are usually used to control how a target is built, but some
|
||||
query the target instead. This command can get properties for any
|
||||
target so far created. The targets do not need to be in the current
|
||||
|
||||
@@ -8,8 +8,14 @@ Get a property of the test.
|
||||
get_test_property(test property VAR)
|
||||
|
||||
Get a property from the test. The value of the property is stored in
|
||||
the variable ``VAR``. If the test or property is not found, ``VAR`` will
|
||||
be set to "NOTFOUND". For a list of standard properties you can type
|
||||
``cmake --help-property-list``.
|
||||
the variable ``VAR``. If the test property is not found, the behavior
|
||||
depends on whether it has been defined to be an ``INHERITED`` property
|
||||
or not (see :command:`define_property`). Non-inherited properties will
|
||||
set ``VAR`` to "NOTFOUND", whereas inheritied properties will search the
|
||||
relevent parent scope as described for the :command:`define_property`
|
||||
command and if still unable to find the property, ``VAR`` will be set to
|
||||
an empty string.
|
||||
|
||||
For a list of standard properties you can type ``cmake --help-property-list``.
|
||||
|
||||
See also the more general :command:`get_property` command.
|
||||
|
||||
@@ -59,11 +59,17 @@ be one of the following:
|
||||
|
||||
The required ``PROPERTY`` option is immediately followed by the name of
|
||||
the property to set. Remaining arguments are used to compose the
|
||||
property value in the form of a semicolon-separated list. If the
|
||||
``APPEND`` option is given the list is appended to any existing property
|
||||
value. If the ``APPEND_STRING`` option is given the string is append to any
|
||||
existing property value as string, i.e. it results in a longer string
|
||||
and not a list of strings.
|
||||
property value in the form of a semicolon-separated list.
|
||||
|
||||
If the ``APPEND`` option is given the list is appended to any existing
|
||||
property value. If the ``APPEND_STRING`` option is given the string is
|
||||
appended to any existing property value as string, i.e. it results in a
|
||||
longer string and not a list of strings. When using ``APPEND`` or
|
||||
``APPEND_STRING`` with a property defined to support ``INHERITED``
|
||||
behavior (see :command:`define_property`), no inheriting occurs when
|
||||
finding the initial value to append to. If the property is not already
|
||||
directly set in the nominated scope, the command will behave as though
|
||||
``APPEND`` or ``APPEND_STRING`` had not been given.
|
||||
|
||||
See the :manual:`cmake-properties(7)` manual for a list of properties
|
||||
in each scope.
|
||||
|
||||
@@ -9,3 +9,4 @@ run_cmake(LINK_LIBRARIES)
|
||||
run_cmake(SOURCES)
|
||||
run_cmake(TYPE)
|
||||
run_cmake(USER_PROP)
|
||||
run_cmake(USER_PROP_INHERITED)
|
||||
|
||||
29
Tests/RunCMake/set_property/USER_PROP_INHERITED-stdout.txt
Normal file
29
Tests/RunCMake/set_property/USER_PROP_INHERITED-stdout.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
-- TopDir-to-nothing chaining: ''
|
||||
-- TopDir-to-global chaining: 'vGlobal'
|
||||
-- TopDir no chaining required: 'vTopDir'
|
||||
-- TopDir unset append chaining: 'aTopDir'
|
||||
-- TopDir preset append chaining: 'vTopDir;aTopDir'
|
||||
-- Subdir-to-parent chaining: 'vTopDir'
|
||||
-- Subdir-to-global chaining: 'vGlobal'
|
||||
-- Subdir no chaining required: 'vSubdir'
|
||||
-- Subdir preset append chaining: 'vSubdir;aSubdir'
|
||||
-- Subdir unset append chaining: 'aSubdir'
|
||||
-- Subdir undefined append chaining: 'aSubdir'
|
||||
-- Target-to-directory chaining: 'vTopDir'
|
||||
-- Target unset append chaining: 'aTarget'
|
||||
-- Target no chaining required: 'vTarget'
|
||||
-- Target preset append chaining: 'vTarget;aTarget'
|
||||
-- Target undefined get chaining: ''
|
||||
-- Target undefined append chaining: 'aTarget'
|
||||
-- Source-to-directory chaining: 'vTopDir'
|
||||
-- Source unset append chaining: 'aSource'
|
||||
-- Source no chaining required: 'vSource'
|
||||
-- Source preset append chaining: 'vSource;aSource'
|
||||
-- Source undefined get chaining: ''
|
||||
-- Source undefined append chaining: 'aSource'
|
||||
-- Test-to-directory chaining: 'vTopDir'
|
||||
-- Test unset append chaining: 'aTest'
|
||||
-- Test no chaining required: 'vTest'
|
||||
-- Test preset append chaining: 'vTest;aTest'
|
||||
-- Test undefined get chaining: ''
|
||||
-- Test undefined append chaining: 'aTest'
|
||||
83
Tests/RunCMake/set_property/USER_PROP_INHERITED.cmake
Normal file
83
Tests/RunCMake/set_property/USER_PROP_INHERITED.cmake
Normal file
@@ -0,0 +1,83 @@
|
||||
# Needed for source property tests
|
||||
enable_language(C)
|
||||
|
||||
#=================================================
|
||||
# Directory property chaining
|
||||
#=================================================
|
||||
|
||||
foreach(i RANGE 1 5)
|
||||
foreach(propType DIRECTORY TARGET SOURCE TEST)
|
||||
define_property(${propType} PROPERTY USER_PROP${i} INHERITED
|
||||
BRIEF_DOCS "Brief" FULL_DOCS "Full"
|
||||
)
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP1)
|
||||
message(STATUS "TopDir-to-nothing chaining: '${val}'")
|
||||
|
||||
set_property(GLOBAL PROPERTY USER_PROP1 vGlobal)
|
||||
set_property(GLOBAL PROPERTY USER_PROP2 vGlobal)
|
||||
set_property(DIRECTORY PROPERTY USER_PROP2 vTopDir)
|
||||
set_property(GLOBAL PROPERTY USER_PROP3 vGlobal)
|
||||
set_property(DIRECTORY PROPERTY USER_PROP4 vTopDir)
|
||||
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP1)
|
||||
message(STATUS "TopDir-to-global chaining: '${val}'")
|
||||
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP2)
|
||||
message(STATUS "TopDir no chaining required: '${val}'")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY USER_PROP3 aTopDir)
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP3)
|
||||
message(STATUS "TopDir unset append chaining: '${val}'")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY USER_PROP4 aTopDir)
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP4)
|
||||
message(STATUS "TopDir preset append chaining: '${val}'")
|
||||
|
||||
add_subdirectory(USER_PROP_INHERITED)
|
||||
|
||||
#=================================================
|
||||
# The other property types all chain the same way
|
||||
#=================================================
|
||||
macro(__chainToDirTests propType)
|
||||
string(TOUPPER ${propType} propTypeUpper)
|
||||
|
||||
get_property(val ${propTypeUpper} ${propType}1 PROPERTY USER_PROP2)
|
||||
message(STATUS "${propType}-to-directory chaining: '${val}'")
|
||||
|
||||
set_property(${propTypeUpper} ${propType}1 APPEND PROPERTY USER_PROP2 a${propType})
|
||||
get_property(val ${propTypeUpper} ${propType}1 PROPERTY USER_PROP2)
|
||||
message(STATUS "${propType} unset append chaining: '${val}'")
|
||||
|
||||
set_property(${propTypeUpper} ${propType}1 PROPERTY USER_PROP1 v${propType})
|
||||
get_property(val ${propTypeUpper} ${propType}1 PROPERTY USER_PROP1)
|
||||
message(STATUS "${propType} no chaining required: '${val}'")
|
||||
|
||||
set_property(${propTypeUpper} ${propType}1 APPEND PROPERTY USER_PROP1 a${propType})
|
||||
get_property(val ${propTypeUpper} ${propType}1 PROPERTY USER_PROP1)
|
||||
message(STATUS "${propType} preset append chaining: '${val}'")
|
||||
|
||||
get_property(val ${propTypeUpper} ${propType}2 PROPERTY USER_PROP5)
|
||||
message(STATUS "${propType} undefined get chaining: '${val}'")
|
||||
|
||||
set_property(${propTypeUpper} ${propType}2 APPEND PROPERTY USER_PROP5 a${propType})
|
||||
get_property(val ${propTypeUpper} ${propType}2 PROPERTY USER_PROP5)
|
||||
message(STATUS "${propType} undefined append chaining: '${val}'")
|
||||
endmacro()
|
||||
|
||||
add_custom_target(Target1)
|
||||
add_custom_target(Target2)
|
||||
__chainToDirTests(Target)
|
||||
|
||||
foreach(i RANGE 1 2)
|
||||
set(Source${i} "${CMAKE_CURRENT_BINARY_DIR}/src${i}.c")
|
||||
file(WRITE ${Source${i}} "int foo${i}() { return ${i}; }")
|
||||
endforeach()
|
||||
add_library(srcProps OBJECT ${Source1} ${Source2})
|
||||
__chainToDirTests(Source)
|
||||
|
||||
add_test(NAME Test1 COMMAND ${CMAKE_COMMAND} -E touch_nocreate iDoNotExist)
|
||||
add_test(NAME Test2 COMMAND ${CMAKE_COMMAND} -E touch_nocreate iDoNotExist)
|
||||
__chainToDirTests(Test)
|
||||
@@ -0,0 +1,21 @@
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP2)
|
||||
message(STATUS "Subdir-to-parent chaining: '${val}'")
|
||||
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP1)
|
||||
message(STATUS "Subdir-to-global chaining: '${val}'")
|
||||
|
||||
set_property(DIRECTORY PROPERTY USER_PROP1 vSubdir)
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP1)
|
||||
message(STATUS "Subdir no chaining required: '${val}'")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY USER_PROP1 aSubdir)
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP1)
|
||||
message(STATUS "Subdir preset append chaining: '${val}'")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY USER_PROP2 aSubdir)
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP2)
|
||||
message(STATUS "Subdir unset append chaining: '${val}'")
|
||||
|
||||
set_property(DIRECTORY APPEND PROPERTY USER_PROP5 aSubdir)
|
||||
get_property(val DIRECTORY PROPERTY USER_PROP5)
|
||||
message(STATUS "Subdir undefined append chaining: '${val}'")
|
||||
Reference in New Issue
Block a user