diff options
99 files changed, 1864 insertions, 442 deletions
diff --git a/Help/command/add_library.rst b/Help/command/add_library.rst index 45f1102..2d69c89 100644 --- a/Help/command/add_library.rst +++ b/Help/command/add_library.rst @@ -109,12 +109,21 @@ The signature :: - add_library(<name> INTERFACE) + add_library(<name> INTERFACE [IMPORTED [GLOBAL]]) creates an interface target. An interface target does not directly create build output, though it may have properties set on it and it may be installed, exported and imported. Typically the INTERFACE_* properties are populated on the interface target using the -set_property(), target_link_libraries(), target_include_directories() -and target_compile_defintions() commands, and then it is used as an -argument to target_link_libraries() like any other target. +:command:`set_property`, :command:`target_link_libraries`, +:command:`target_include_directories` +and :command:`target_compile_defintions` commands, and then it is used as an +argument to :command:`target_link_libraries` like any other target. + +An ``INTERFACE`` :prop_tgt:`IMPORTED` target may also be created with this +signature. An :prop_tgt:`IMPORTED` library target references a library defined +outside the project. The target name has scope in the directory in which it is +created and below, but the ``GLOBAL`` option extends visibility. It may be +referenced like any target built within the project. :prop_tgt:`IMPORTED` +libraries are useful for convenient reference from commands like +:command:`target_link_libraries`. diff --git a/Help/index.rst b/Help/index.rst index a7a1bd9..551db75 100644 --- a/Help/index.rst +++ b/Help/index.rst @@ -25,6 +25,7 @@ Reference Manuals .. toctree:: :maxdepth: 1 + /manual/cmake-buildsystem.7 /manual/cmake-commands.7 /manual/cmake-developer.7 /manual/cmake-generator-expressions.7 diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst new file mode 100644 index 0000000..be60ebb --- /dev/null +++ b/Help/manual/cmake-buildsystem.7.rst @@ -0,0 +1,794 @@ +.. cmake-manual-description: CMake Buildsystem Reference + +cmake-buildsystem(7) +******************** + +.. only:: html or latex + + .. contents:: + +Introduction +============ + +A CMake-based buildsystem is organized as a set of high-level logical +targets. Each target corresponds to an executable or library, or +is a custom target containing custom commands. Dependencies between the +targets are expressed in the buildsystem to determine the build order +and the rules for regeneration in response to change. + +Binary Targets +============== + +Executables and libraries are defined using the :command:`add_library` +and :command:`add_executable` commands. The resulting binary files have +appropriate prefixes, suffixes and extensions for the platform targeted. +Dependencies between binary targets are expressed using the +:command:`target_link_libraries` command: + +.. code-block:: cmake + + add_library(archive archive.cpp zip.cpp lzma.cpp) + add_executable(zipapp zipapp.cpp) + target_link_libraries(zipapp archive) + +``archive`` is defined as a static library -- an archive containing objects +compiled from ``archive.cpp``, ``zip.cpp``, and ``lzma.cpp``. ``zipapp`` +is defined as an executable formed by compiling and linking ``zipapp.cpp``. +When linking the ``zipapp`` executable, the ``archive`` static library is +linked in. + +Binary Library Types +-------------------- + +By default, the :command:`add_library` command defines a static library, +unless a type is specified. A type may be specified when using the command: + +.. code-block:: cmake + + add_library(archive SHARED archive.cpp zip.cpp lzma.cpp) + +.. code-block:: cmake + + add_library(archive STATIC archive.cpp zip.cpp lzma.cpp) + +The :variable:`BUILD_SHARED_LIBS` variable may be enabled to change the +behavior of :command:`add_library` to build shared libraries by default. + +In the context of the buildsystem definition as a whole, it is largely +irrelevant whether particular libraries are ``SHARED`` or ``STATIC`` -- +the commands, dependency specifications and other APIs work similarly +regardless of the library type. The ``MODULE`` library type is +dissimilar in that it is generally not linked to -- it is not used in +the right-hand-side of the :command:`target_link_libraries` command. +It is a type which is loaded as a plugin using runtime techniques. + +.. code-block:: cmake + + add_library(archive MODULE 7z.cpp) + +The ``OBJECT`` library type is also not linked to. It defines a non-archival +collection of object files resulting from compiling the given source files. +The object files collection can be used as source inputs to other targets: + +.. code-block:: cmake + + add_library(archive OBJECT archive.cpp zip.cpp lzma.cpp) + + add_library(archiveExtras STATIC $<TARGET_OBJECTS:archive> extras.cpp) + + add_executable(test_exe $<TARGET_OBJECTS:archive> test.cpp) + +``OBJECT`` libraries may only be used locally as sources in a buildsystem -- +they may not be installed, exported, or used in the right hand side of +:command:`target_link_libraries`. They also may not be used as the ``TARGET`` +in a use of the :command:`add_custom_command(TARGET)` command signature. + +Commands such as :command:`add_custom_command`, which generates rules to be +run at build time can transparently use an :prop_tgt:`EXECUTABLE <TYPE>` +target as a ``COMMAND`` executable. The buildsystem rules will ensure that +the executable is built before attempting to run the command. + +Build Specification and Usage Requirements +========================================== + +The :command:`target_include_directories`, :command:`target_compile_definitions` +and :command:`target_compile_options` commands specify the build specifications +and the usage requirements of binary targets. The commands populate the +:prop_tgt:`INCLUDE_DIRECTORIES`, :prop_tgt:`COMPILE_DEFINITIONS` and +:prop_tgt:`COMPILE_OPTIONS` target properties respectively, and/or the +:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`, :prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` +and :prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties. + +Each of the commands has a ``PRIVATE``, ``PUBLIC`` and ``INTERFACE`` mode. The +``PRIVATE`` mode populates only the non-``INTERFACE_`` variant of the target +property and the ``INTERFACE`` mode populates only the ``INTERFACE_`` variants. +The ``PUBLIC`` mode populates both variants of the repective target property. +Each command may be invoked with multiple uses of each keyword: + +.. code-block:: cmake + + target_compile_definitions(archive + PRIVATE BUILDING_WITH_LZMA + INTERFACE USING_ARCHIVE_LIB + ) + +Target Properties +----------------- + +The contents of the :prop_tgt:`INCLUDE_DIRECTORIES`, +:prop_tgt:`COMPILE_DEFINITIONS` and :prop_tgt:`COMPILE_OPTIONS` target +properties are used appropriately when compiling the source files of a +binary target. + +Entries in the :prop_tgt:`INCLUDE_DIRECTORIES` are added to the compile line +with ``-I`` or ``-isystem`` prefixes and in the order of appearance in the +property value. + +Entries in the :prop_tgt:`COMPILE_DEFINITIONS` are prefixed with ``-D`` or +``/D`` and added to the compile line in an unspecified order. The +:prop_tgt:`DEFINE_SYMBOL` target property is also added as a compile +definition as a special convenience case for ``SHARED`` and ``MODULE`` +library targets. + +Entries in the :prop_tgt:`COMPILE_OPTIONS` are escaped for the shell and added +in the order of appearance in the property value. Several compile options have +special separate handling, such as :prop_tgt:`POSITION_INDEPENDENT_CODE`. + +The contents of the :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`, +:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` and +:prop_tgt:`INTERFACE_COMPILE_OPTIONS` target properties are +*Usage Requirements* -- they specify content which consumers +must use to correctly compile and link with the target they appear on. +For any binary target, the contents of each ``INTERFACE_`` property on +each target specified in a :command:`target_link_libraries` command is +consumed: + +.. code-block:: cmake + + set(srcs archive.cpp zip.cpp) + if (LZMA_FOUND) + list(APPEND srcs lzma.cpp) + endif() + add_library(archive SHARED ${srcs}) + if (LZMA_FOUND) + # The archive library sources are compiled with -DBUILDING_WITH_LZMA + target_compile_definitions(archive PRIVATE BUILDING_WITH_LZMA) + endif() + target_compile_definitions(archive INTERFACE USING_ARCHIVE_LIB) + + add_executable(consumer) + # Link consumer to archive and consume its usage requirements. The consumer + # executable sources are compiled with -DUSING_ARCHIVE_LIB. + target_link_libraries(consumer archive) + +Because it is common to require that the source directory and corresponding +build directory are added to the :prop_tgt:`INCLUDE_DIRECTORIES`, the +:variable:`CMAKE_INCLUDE_CURRENT_DIR` variable can be enabled to conveniently +add the corresponding directories to the :prop_tgt:`INCLUDE_DIRECTORIES` of +all targets. The variable :variable:`CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE` +can be enabled to add the corresponding directories to the +:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of all targets. This makes use of +targets in multiple different directories convenient through use of the +:command:`target_link_libraries` command. + +Transitive Usage Requirements +----------------------------- + +The usage requirements of a target can transitively propagate to dependents. +The :command:`target_link_libraries` command also has ``PRIVATE``, +``INTERFACE`` and ``PUBLIC`` keywords to control the propagation. + +.. code-block:: cmake + + add_library(archive archive.cpp) + target_compile_definitions(archive INTERFACE USING_ARCHIVE_LIB) + + add_library(serialization serialization.cpp) + target_compile_definitions(serialization INTERFACE USING_SERIALIZATION_LIB) + + add_library(archiveExtras extras.cpp) + target_link_libraries(archiveExtras PUBLIC archive) + target_link_libraries(archiveExtras PRIVATE serialization) + # archiveExtras is compiled with -DUSING_ARCHIVE_LIB + # and -DUSING_SERIALIZATION_LIB + + add_executable(consumer consumer.cpp) + # consumer is compiled with -DUSING_ARCHIVE_LIB + target_link_libraries(consumer archiveExtras) + +Because ``archive`` is a ``PUBLIC`` dependency of ``archiveExtras``, the +usage requirements of it are propagated to ``consumer`` too. Because +``serialization`` is a ``PRIVATE`` dependency of ``archive``, the usage +requirements of it are not propagated to ``consumer``. + +Generally, a dependency should be specified in a use of +:command:`target_link_libraries` with the ``PRIVATE`` keyword if it is used by +only the implementation of a library, and not in the header files. If a +dependency is additionally used in the header files of a library (e.g. for +class inheritance), then it should be specified as a ``PUBLIC`` dependency. +A dependency which is not used by the implementation of a library, but only by +its headers should be specified as an ``INTERFACE`` dependency. The +:command:`target_link_libraries` command may be invoked with multiple uses of +each keyword: + +.. code-block:: cmake + + target_link_libraries(archiveExtras + PUBLIC archive + PRIVATE serialization + ) + +Compatible Interface Properties +------------------------------- + +Some target properties are required to be compatible between a target and +the interface of each dependency. For example, the +:prop_tgt:`POSITION_INDEPENDENT_CODE` target property may specify a +boolean value of whether a target should be compiled as +position-independent-code, which has platform-specific consequences. +A target may also specify the usage requirement +:prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE` to communicate that +consumers must be compiled as position-independent-code. + +.. code-block:: cmake + + add_executable(exe1 exe1.cpp) + set_property(TARGET exe1 PROPERTY POSITION_INDEPENDENT_CODE ON) + + add_library(lib1 SHARED lib1.cpp) + set_property(TARGET lib1 PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) + + add_executable(exe2 exe2.cpp) + target_link_libraries(exe2 lib1) + +Here, both ``exe1`` and ``exe2`` will be compiled as position-independent-code. +``lib1`` will also be compiled as position-independent-code because that is the +default setting for ``SHARED`` libraries. If dependencies have conflicting, +non-compatible requirements :manual:`cmake(1)` issues a diagnostic: + +.. code-block:: cmake + + add_library(lib1 SHARED lib1.cpp) + set_property(TARGET lib1 PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) + + add_library(lib2 SHARED lib2.cpp) + set_property(TARGET lib2 PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 lib1) + set_property(TARGET exe1 PROPERTY POSITION_INDEPENDENT_CODE OFF) + + add_executable(exe2 exe2.cpp) + target_link_libraries(exe2 lib1 lib2) + +The ``lib1`` requirement ``INTERFACE_POSITION_INDEPENDENT_CODE`` is not +"compatible" with the ``POSITION_INDEPENDENT_CODE`` property of the ``exe1`` +target. The library requires that consumers are built as +position-independent-code, while the executable specifies to not built as +position-independent-code, so a diagnostic is issued. + +The ``lib1`` and ``lib2`` requirements are not "compatible". One of them +requires that consumers are built as position-independent-code, while +the other requires that consumers are not built as position-independent-code. +Because ``exe2`` links to both and they are in conflict, a diagnostic is +issued. + +To be "compatible", the :prop_tgt:`POSITION_INDEPENDENT_CODE` property, +if set must be either the same, in a boolean sense, as the +:prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE` property of all transitively +specified dependencies on which that property is set. + +This property of "compatible interface requirement" may be extended to other +properties by specifying the property in the content of the +:prop_tgt:`COMPATIBLE_INTERFACE_BOOL` target property. Each specified property +must be compatible between the consuming target and the corresponding property +with an ``INTERFACE_`` prefix from each dependency: + +.. code-block:: cmake + + add_library(lib1Version2 SHARED lib1_v2.cpp) + set_property(TARGET lib1Version2 PROPERTY INTERFACE_CUSTOM_PROP ON) + set_property(TARGET lib1Version2 APPEND PROPERTY + COMPATIBLE_INTERFACE_BOOL CUSTOM_PROP + ) + + add_library(lib1Version3 SHARED lib1_v3.cpp) + set_property(TARGET lib1Version3 PROPERTY INTERFACE_CUSTOM_PROP OFF) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 lib1Version2) # CUSTOM_PROP will be ON + + add_executable(exe2 exe2.cpp) + target_link_libraries(exe2 lib1Version2 lib1Version3) # Diagnostic + +Non-boolean properties may also participate in "compatible interface" +computations. Properties specified in the +:prop_tgt:`COMPATIBLE_INTERFACE_STRING` +property must be either unspecified or compare to the same string among +all transitively specified dependencies. This can be useful to ensure +that multiple incompatible versions of a library are not linked together +through transitive requirements of a target: + +.. code-block:: cmake + + add_library(lib1Version2 SHARED lib1_v2.cpp) + set_property(TARGET lib1Version2 PROPERTY INTERFACE_LIB_VERSION 2) + set_property(TARGET lib1Version2 APPEND PROPERTY + COMPATIBLE_INTERFACE_STRING LIB_VERSION + ) + + add_library(lib1Version3 SHARED lib1_v3.cpp) + set_property(TARGET lib1Version3 PROPERTY INTERFACE_LIB_VERSION 3) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 lib1Version2) # LIB_VERSION will be "2" + + add_executable(exe2 exe2.cpp) + target_link_libraries(exe2 lib1Version2 lib1Version3) # Diagnostic + +The :prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MAX` target property specifies +that content will be evaluated numerically and the maximum number among all +specified will be calculated: + +.. code-block:: cmake + + add_library(lib1Version2 SHARED lib1_v2.cpp) + set_property(TARGET lib1Version2 PROPERTY INTERFACE_CONTAINER_SIZE_REQUIRED 200) + set_property(TARGET lib1Version2 APPEND PROPERTY + COMPATIBLE_INTERFACE_NUMBER_MAX CONTAINER_SIZE_REQUIRED + ) + + add_library(lib1Version3 SHARED lib1_v3.cpp) + set_property(TARGET lib1Version2 PROPERTY INTERFACE_CONTAINER_SIZE_REQUIRED 1000) + + add_executable(exe1 exe1.cpp) + # CONTAINER_SIZE_REQUIRED will be "200" + target_link_libraries(exe1 lib1Version2) + + add_executable(exe2 exe2.cpp) + # CONTAINER_SIZE_REQUIRED will be "1000" + target_link_libraries(exe2 lib1Version2 lib1Version3) + +Similarly, the :prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MIN` may be used to +calculate the numeric minimum value for a property from dependencies. + +Each calculated "compatible" property value may be read in the consumer at +generate-time using generator expressions. + +Property Origin Debugging +------------------------- + +Because build specifications can be determined by dependencies, the lack of +locality of code which creates a target and code which is responsible for +setting build specifications may make the code more difficult to reason about. +:manual:`cmake(1)` provides a debugging facility to print the origin of the +contents of properties which may be determined by dependencies. The properties +which can be debugged are :prop_tgt:`INCLUDE_DIRECTORIES`, +:prop_tgt:`COMPILE_DEFINITIONS`, :prop_tgt:`COMPILE_OPTIONS`, +:prop_tgt:`AUTOUIC_OPTIONS`, and all properties listed in a +``COMPATIBLE_INTERFACE_*`` target property: + +.. code-block:: cmake + + set(CMAKE_DEBUG_TARGET_PROPERTIES + INCLUDE_DIRECTORIES + COMPILE_DEFINITIONS + POSITION_INDEPENDENT_CODE + CONTAINER_SIZE_REQUIRED + LIB_VERSION + ) + add_executable(exe1 exe1.cpp) + +In the case of properties listed in :prop_tgt:`COMPATIBLE_INTERFACE_BOOL` or +:prop_tgt:`COMPATIBLE_INTERFACE_STRING`, the debug output shows which target +was responsible for setting the property, and which other dependencies also +defined the property. In the case of +:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MAX` and +:prop_tgt:`COMPATIBLE_INTERFACE_NUMBER_MIN`, the debug output shows the +value of the property from each dependency, and whether the value determines +the new extreme. + +Build Specification with Generator Expressions +---------------------------------------------- + +Build specifications may use +:manual:`generator expressions <cmake-generator-expressions(7)>` containing +content which may be conditional or known only at generate-time. For example, +the calculated "compatible" value of a property may be read with the +``TARGET_PROPERTY`` expression: + +.. code-block:: cmake + + add_library(lib1Version2 SHARED lib1_v2.cpp) + set_property(TARGET lib1Version2 PROPERTY + INTERFACE_CONTAINER_SIZE_REQUIRED 200) + set_property(TARGET lib1Version2 APPEND PROPERTY + COMPATIBLE_INTERFACE_NUMBER_MAX CONTAINER_SIZE_REQUIRED + ) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 lib1Version2) + target_compile_definitions(exe1 PRIVATE + CONTAINER_SIZE=$<TARGET_PROPERTY:CONTAINER_SIZE_REQUIRED> + ) + +In this case, the ``exe1`` source files will be compiled with +``-DCONTAINER_SIZE=200``. + +Configuration determined build specifications may be conveniently set using +the ``CONFIG`` generator expression. + +.. code-block:: cmake + + target_compile_definitions(exe1 PRIVATE + $<$<CONFIG:Debug>:DEBUG_BUILD> + ) + +The ``CONFIG`` parameter is compared case-insensitively with the configuration +being built. In the presence of :prop_tgt:`IMPORTED` targets, the content of +:prop_tgt:`MAP_IMPORTED_CONFIG_DEBUG <MAP_IMPORTED_CONFIG_CONFIG>` is also +accounted for by this expression. + +Some buildsystems generated by :manual:`cmake(1)` have a predetermined +build-configuration set in the :variable:`CMAKE_BUILD_TYPE` variable. The +buildsystem for the IDEs such as Visual Studio and Xcode are generated +independent of the build-configuration, and the actual build configuration +is not known until build-time. Therefore, code such as + +.. code-block:: cmake + + string(TOLOWER ${CMAKE_BUILD_TYPE} _type) + if (_type STREQUAL debug) + target_compile_definitions(exe1 PRIVATE DEBUG_BUILD) + endif() + +may appear to work for ``Makefile`` based and ``Ninja`` generators, but is not +portable to IDE generators. Additionally, the :prop_tgt:`IMPORTED` +configuration-mappings are not accounted for with code like this, so it should +be avoided. + +The unary ``TARGET_PROPERTY`` generator expression and the ``TARGET_POLICY`` +generator expression are evaluated with the consuming target context. This +means that a usage requirement specification may be evaluated differently based +on the consumer: + +.. code-block:: cmake + + add_library(lib1 lib1.cpp) + target_compile_definitions(lib1 INTERFACE + $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,EXECUTABLE>:LIB1_WITH_EXE> + $<$<STREQUAL:$<TARGET_PROPERTY:TYPE>,SHARED_LIBRARY>:LIB1_WITH_SHARED_LIB> + $<$<TARGET_POLICY:CMP0041>:CONSUMER_CMP0041_NEW> + ) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 lib1) + + cmake_policy(SET CMP0041 NEW) + + add_library(shared_lib shared_lib.cpp) + target_link_libraries(shared_lib lib1) + +The ``exe1`` executable will be compiled with ``-DLIB1_WITH_EXE``, while the +``shared_lib`` shared library will be compiled with ``-DLIB1_WITH_SHARED_LIB`` +and ``-DCONSUMER_CMP0041_NEW``, because policy :policy:`CMP0041` is +``NEW`` at the point where the ``shared_lib`` target is created. + +The ``BUILD_INTERFACE`` expression wraps requirements which are only used when +consumed from a target in the same buildsystem, or when consumed from a target +exported to the build directory using the :command:`export` command. The +``INSTALL_INTERFACE`` expression wraps requirements which are only used when +consumed from a target which has been installed and exported with the +:command:`install(EXPORT)` command: + +.. code-block:: cmake + + add_library(ClimbingStats climbingstats.cpp) + target_compile_definitions(ClimbingStats INTERFACE + $<BUILD_INTERFACE:ClimbingStats_FROM_BUILD_LOCATION> + $<INSTALL_INTERFACE:ClimbingStats_FROM_INSTALLED_LOCATION> + ) + install(TARGETS ClimbingStats EXPORT libExport ${InstallArgs}) + install(EXPORT libExport NAMESPACE Upstream:: + DESTINATION lib/cmake/ClimbingStats) + export(EXPORT libExport NAMESPACE Upstream::) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 ClimbingStats) + +In this case, the ``exe1`` executable will be compiled with +``-DClimbingStats_FROM_BUILD_LOCATION``. The exporting commands generate +:prop_tgt:`IMPORTED` targets with either the ``INSTALL_INTERFACE`` or the +``BUILD_INTERFACE`` omitted, and the ``*_INTERFACE`` marker stripped away. +A separate project consuming the ``ClimbingStats`` package would contain: + +.. code-block:: cmake + + find_package(ClimbingStats REQUIRED) + + add_executable(Downstream main.cpp) + target_link_libraries(Downstream Upstream::ClimbingStats) + +Depending on whether the ``ClimbingStats`` package was used from the build +location or the install location, the ``Downstream`` target would be compiled +with either ``-DClimbingStats_FROM_BUILD_LOCATION`` or +``-DClimbingStats_FROM_INSTALL_LOCATION``. For more about packages and +exporting see the :manual:`cmake-packages(7)` manual. + +Include Directories and Usage Requirements +'''''''''''''''''''''''''''''''''''''''''' + +Include directories require some special consideration when specified as usage +requirements and when used with generator expressions. The +:command:`target_include_directories` command accepts both relative and +absolute include directories: + +.. code-block:: cmake + + add_library(lib1 lib1.cpp) + target_include_directories(lib1 PRIVATE + /absolute/path + relative/path + ) + +Relative paths are interpreted relative to the source directory where the +command appears. Relative paths are not allowed in the +:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of :prop_tgt:`IMPORTED` targets. + +In cases where a non-trivial generator expression is used, the +``INSTALL_PREFIX`` expression may be used within the argument of an +``INSTALL_INTERFACE`` expression. It is a replacement marker which +expands to the installation prefix when imported by a consuming project. + +Include directories usage requirements commonly differ between the build-tree +and the install-tree. The ``BUILD_INTERFACE`` and ``INSTALL_INTERFACE`` +generator expressions can be used to describe separate usage requirements +based on the usage location. Relative paths are allowed within these +expressions, and are interpreted relative to the current source directory +or the installation prefix, as appropriate. + +Two convenience APIs are provided relating to include directories usage +requirements. The :variable:`CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE` variable +may be enabled, with an equivalent effect to: + +.. code-block:: cmake + + set_property(TARGET tgt APPEND PROPERTY + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_BINARY_DIR}> + ) + +for each target affected. The convenience for installed targets is +an ``INCLUDES DESTINATION`` component with the :command:`install(TARGETS)` +command: + +.. code-block:: cmake + + install(TARGETS foo bar bat EXPORT tgts ${dest_args} + INCLUDES DESTINATION include + ) + install(EXPORT tgts ${other_args}) + install(FILES ${headers} DESTINATION include) + +This is equivalent to appending ``${CMAKE_INSTALL_PREFIX}/include`` to the +:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` of each of the installed +:prop_tgt:`IMPORTED` targets when generated by :command:`install(EXPORT)`. + +If a binary target is linked transitively to a Mac OX framework, the +``Headers`` directory of the framework is also treated as a usage requirement. +This has the same effect as passing the framework directory as an include +directory. + +Link Libraries and Generator Expressions +---------------------------------------- + +Like build specifications, :prop_tgt:`link libraries <LINK_LIBRARIES>` may be +specified with generator expression conditions. However, as consumption of +usage requirements is based on collection from linked dependencies, there is +an additional limitation that the link dependencies must form a "directed +acyclic graph". That is, if linking to a target is dependent on the value of +a target property, that target property may not be dependent on the linked +dependencies: + +.. code-block:: cmake + + add_library(lib1 lib1.cpp) + add_library(lib2 lib2.cpp) + target_link_libraries(lib1 PUBLIC + $<$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>:lib2> + ) + add_library(lib3 lib3.cpp) + set_property(TARGET lib3 PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 lib1 lib3) + +As the value of the :prop_tgt:`POSITION_INDEPENDENT_CODE` property of +the ``exe1`` target is dependent on the linked libraries (``lib3``), and the +edge of linking ``exe1`` is determined by the same +:prop_tgt:`POSITION_INDEPENDENT_CODE` property, the dependency graph above +contains a cycle. :manual:`cmake(1)` issues a diagnostic in this case. + +Output Files +------------ + +The buildsystem targets created by the :command:`add_library` and +:command:`add_executable` commands create rules to create binary outputs. +The exact output location of the binaries can only be determined at +generate-time because it can depend on the build-configuration and the +link-language of linked dependencies etc. ``TARGET_FILE``, +``TARGET_LINKER_FILE`` and related expressions can be used to access the +name and location of generated binaries. These expressions do not work +for ``OBJECT`` libraries however, as there is no single file generated +by such libraries which is relevant to the expressions. + +Directory-Scoped Commands +------------------------- + +The :command:`target_include_directories`, +:command:`target_compile_definitions` and +:command:`target_compile_options` commands have an effect on only one +target at a time. The commands :command:`add_definitions`, +:command:`add_compile_options` and :command:`include_directories` have +a similar function, but operate at directory scope instead of target +scope for convenience. + +Psuedo Targets +============== + +Some target types do not represent outputs of the buildsystem, but only inputs +such as external dependencies, aliases or other non-build artifacts. Pseudo +targets are not represented in the generated buildsystem. + +Imported Targets +---------------- + +An :prop_tgt:`IMPORTED` target represents a pre-existing dependency. Usually +such targets are defined by an upstream package and should be treated as +immutable. It is not possible to use an :prop_tgt:`IMPORTED` target in the +left-hand-side of the :command:`target_compile_definitions`, +:command:`target_include_directories`, :command:`target_compile_options` or +:command:`target_link_libraries` commands, as that would be an attempt to +modify it. :prop_tgt:`IMPORTED` targets are designed to be used only in the +right-hand-side of those commands. + +:prop_tgt:`IMPORTED` targets may have the same usage requirement properties +populated as binary targets, such as +:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`, +:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS`, +:prop_tgt:`INTERFACE_COMPILE_OPTIONS`, +:prop_tgt:`INTERFACE_LINK_LIBRARIES`, and +:prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE`. + +The :prop_tgt:`LOCATION` may also be read from an IMPORTED target, though there +is rarely reason to do so. Commands such as :command:`add_custom_command` can +transparently use an :prop_tgt:`IMPORTED` :prop_tgt:`EXECUTABLE <TYPE>` target +as a ``COMMAND`` executable. + +The scope of the definition of an :prop_tgt:`IMPORTED` target is the directory +where it was defined. It may be accessed and used from subdirectories, but +not from parent directories or sibling directories. The scope is similar to +the scope of a cmake variable. + +It is also possible to define a ``GLOBAL`` :prop_tgt:`IMPORTED` target which is +accessible globally in the buildsystem. + +See the :manual:`cmake-packages(7)` manual for more on creating packages +with :prop_tgt:`IMPORTED` targets. + +Alias Targets +------------- + +An ``ALIAS`` target is a name which may be used interchangably with +a binary target name in read-only contexts. A primary use-case for ``ALIAS`` +targets is for example or unit test executables accompanying a library, which +may be part of the same buildsystem or built separately based on user +configuration. + +.. code-block:: cmake + + add_library(lib1 lib1.cpp) + install(TARGETS lib1 EXPORT lib1Export ${dest_args}) + install(EXPORT lib1Export NAMESPACE Upstream:: ${other_args}) + + add_library(Upstream::lib1 ALIAS lib1) + +In another directory, we can link unconditionally to the ``Upstream::lib1`` +target, which may be an :prop_tgt:`IMPORTED` target from a package, or an +``ALIAS`` target if built as part of the same buildsystem. + +.. code-block:: cmake + + if (NOT TARGET Upstream::lib1) + find_package(lib1 REQUIRED) + endif() + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 Upstream::lib1) + +``ALIAS`` targets are not mutable, installable or exportable. They are +entirely local to the buildsystem description. A name can be tested for +whether it is an ``ALIAS`` name by reading the :prop_tgt:`ALIASED_TARGET` +property from it: + +.. code-block:: cmake + + get_target_property(_aliased Upstream::lib1 ALIASED_TARGET) + if(_aliased) + message(STATUS "The name Upstream::lib1 is an ALIAS for ${_aliased}.") + endif() + +Interface Libraries +------------------- + +An ``INTERFACE`` target has no :prop_tgt:`LOCATION` and is mutable, but is +otherwise similar to an :prop_tgt:`IMPORTED` target. + +It may specify usage requirements such as +:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`, +:prop_tgt:`INTERFACE_COMPILE_DEFINITIONS`, +:prop_tgt:`INTERFACE_COMPILE_OPTIONS`, +:prop_tgt:`INTERFACE_LINK_LIBRARIES`, and +:prop_tgt:`INTERFACE_POSITION_INDEPENDENT_CODE`. +Only the ``INTERFACE`` modes of the :command:`target_include_directories`, +:command:`target_compile_definitions`, :command:`target_compile_options`, +and :command:`target_link_libraries` commands may be used with ``INTERFACE`` +libraries. + +A primary use-case for ``INTERFACE`` libraries is header-only libraries. + +.. code-block:: cmake + + add_library(Eigen INTERFACE) + target_include_directories(Eigen INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> + $<INSTALL_INTERFACE:include/Eigen> + ) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 Eigen) + +Here, the usage requirements from the ``Eigen`` target are consumed and used +when compiling, but it has no effect on linking. + +Another use-case is to employ an entirely target-focussed design for usage +requirements: + +.. code-block:: cmake + + add_library(pic_on INTERFACE) + set_property(TARGET pic_on PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON) + add_library(pic_off INTERFACE) + set_property(TARGET pic_off PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF) + + add_library(enable_rtti INTERFACE) + target_compile_options(enable_rtti INTERFACE + $<$<OR:$<COMPILER_ID:GNU>,$<COMPILER_ID:Clang>>:-rtti> + ) + + add_executable(exe1 exe1.cpp) + target_link_libraries(exe1 pic_on enable_rtti) + +This way, the build specification of ``exe1`` is expressed entirely as linked +targets, and the complexity of compiler-specific flags is encapsulated in an +``INTERFACE`` library target. + +``INTERFACE`` libraries may be installed and exported. Any content they refer +to must be installed separately: + +.. code-block:: cmake + + add_library(Eigen INTERFACE) + target_include_directories(Eigen INTERFACE + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src> + $<INSTALL_INTERFACE:include/Eigen> + ) + + install(TARGETS Eigen EXPORT eigenExport) + install(EXPORT eigenExport NAMESPACE Upstream:: + DESTINATION lib/cmake/Eigen + ) + install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/src/eigen.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/vector.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/matrix.h + DESTINATION include/Eigen + ) diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index ed28abd..12cfaf8 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -55,6 +55,8 @@ otherwise expands to nothing. ``0`` if ``?`` is ``1``, else ``1`` ``$<STREQUAL:a,b>`` ``1`` if ``a`` is STREQUAL ``b``, else ``0`` +``$<EQUAL:a,b>`` + ``1`` if ``a`` is EQUAL ``b`` in a numeric comparison, else ``0`` ``$<CONFIG:cfg>`` ``1`` if config is ``cfg``, else ``0``. This is a case-insensitive comparison. The mapping in :prop_tgt:`MAP_IMPORTED_CONFIG_<CONFIG>` is also considered by diff --git a/Help/manual/cmake-packages.7.rst b/Help/manual/cmake-packages.7.rst index dc301ba..376ec78 100644 --- a/Help/manual/cmake-packages.7.rst +++ b/Help/manual/cmake-packages.7.rst @@ -131,7 +131,9 @@ It may also provide a CMake package configuration file:: <prefix>/lib/cmake/foo-1.2/FooConfig.cmake with content defining :prop_tgt:`IMPORTED` targets, or defining variables, such -as:: +as: + +.. code-block:: cmake # ... # (compute PREFIX relative to file location) diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst index d467c36..9138660 100644 --- a/Help/manual/cmake-policies.7.rst +++ b/Help/manual/cmake-policies.7.rst @@ -22,7 +22,9 @@ The :command:`cmake_minimum_required` command does more than report an error if a too-old version of CMake is used to build a project. It also sets all policies introduced in that CMake version or earlier to NEW behavior. To manage policies without increasing the minimum required -CMake version, the :command:`if(POLICY)` command may be used:: +CMake version, the :command:`if(POLICY)` command may be used: + +.. code-block:: cmake if(POLICY CMP0990) cmake_policy(SET CMP0990 NEW) diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst index fbe546e..97cd650 100644 --- a/Help/manual/cmake-toolchains.7.rst +++ b/Help/manual/cmake-toolchains.7.rst @@ -22,17 +22,23 @@ Languages Languages are enabled by the :command:`project` command. If no project command is in the top-level CMakeLists file, one will be implicitly generated. By default -the enabled languages are C and CXX:: +the enabled languages are C and CXX: + +.. code-block:: cmake project(C_Only C) A special value of NONE can also be used with the :command:`project` command -to enable no languages:: +to enable no languages: + +.. code-block:: cmake project(MyProject NONE) The :command:`enable_language` command can be used to enable languages after the -:command:`project` command:: +:command:`project` command: + +.. code-block:: cmake enable_language(CXX) @@ -86,7 +92,9 @@ Cross Compiling If :manual:`cmake(1)` is invoked with the command line parameter ``-DCMAKE_TOOLCHAIN_FILE=path/to/file``, the file will be loaded early to set values for the compilers. A typical cross-compiling toolchain has content such -as:: +as: + +.. code-block:: cmake set(CMAKE_SYSTEM_NAME Linux) @@ -127,7 +135,9 @@ the ``CMAKE_FIND_ROOT_PATH_MODE_*`` variables. Some compilers are inherently cross compilers, such as Clang and the QNX QCC compiler. The :variable:`CMAKE_<LANG>_COMPILER_TARGET` can be set to pass a -value to those supported compilers when compiling:: +value to those supported compilers when compiling: + +.. code-block:: cmake set(CMAKE_SYSTEM_NAME Linux) @@ -138,7 +148,9 @@ value to those supported compilers when compiling:: set(CMAKE_CXX_COMPILER clang++) set(CMAKE_CXX_COMPILER_TARGET ${triple}) -Or, for QCC:: +Or, for QCC: + +.. code-block:: cmake set(CMAKE_SYSTEM_NAME QNX) diff --git a/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst b/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst index 48cc8a1..5a69ef3 100644 --- a/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst +++ b/Help/prop_gbl/AUTOGEN_TARGETS_FOLDER.rst @@ -1,8 +1,9 @@ AUTOGEN_TARGETS_FOLDER ---------------------- -Name of FOLDER for ``*_automoc`` targets that are added automatically by CMake for targets for which AUTOMOC is enabled. +Name of :prop_tgt:`FOLDER` for ``*_automoc`` targets that are added automatically by +CMake for targets for which :prop_tgt:`AUTOMOC` is enabled. -If not set, CMake uses the FOLDER property of the parent target as a +If not set, CMake uses the :prop_tgt:`FOLDER` property of the parent target as a default value for this property. See also the documentation for the -FOLDER target property and the AUTOMOC target property. +:prop_tgt:`FOLDER` target property and the :prop_tgt:`AUTOMOC` target property. diff --git a/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst b/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst index 185e0ec..671f86a 100644 --- a/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst +++ b/Help/prop_gbl/AUTOMOC_TARGETS_FOLDER.rst @@ -1,10 +1,11 @@ AUTOMOC_TARGETS_FOLDER ---------------------- -Name of FOLDER for ``*_automoc`` targets that are added automatically by CMake for targets for which AUTOMOC is enabled. +Name of :prop_tgt:`FOLDER` for ``*_automoc`` targets that are added automatically by +CMake for targets for which :prop_tgt:`AUTOMOC` is enabled. -This property is obsolete. Use AUTOGEN_TARGETS_FOLDER instead. +This property is obsolete. Use :prop_gbl:`AUTOGEN_TARGETS_FOLDER` instead. -If not set, CMake uses the FOLDER property of the parent target as a +If not set, CMake uses the :prop_tgt:`FOLDER` property of the parent target as a default value for this property. See also the documentation for the -FOLDER target property and the AUTOMOC target property. +:prop_tgt:`FOLDER` target property and the :prop_tgt:`AUTOMOC` target property. diff --git a/Help/prop_sf/AUTORCC_OPTIONS.rst b/Help/prop_sf/AUTORCC_OPTIONS.rst index 4b6bb10..d9dc4d3 100644 --- a/Help/prop_sf/AUTORCC_OPTIONS.rst +++ b/Help/prop_sf/AUTORCC_OPTIONS.rst @@ -1,14 +1,13 @@ AUTORCC_OPTIONS --------------- -Additional options for rcc when using autorcc (see the :prop_tgt:`AUTORCC` target -property) +Additional options for ``rcc`` when using :prop_tgt:`AUTORCC` This property holds additional command line options which will be used when -rcc is executed during the build via autorcc, i.e. it is equivalent to the -optional OPTIONS argument of the qt4_add_resources() macro. +``rcc`` is executed during the build via :prop_tgt:`AUTORCC`, i.e. it is equivalent to the +optional ``OPTIONS`` argument of the :module:`qt4_add_resources() <FindQt4>` macro. By default it is empty. -The options set on the .qrc source file may override :prop_tgt:`AUTORCC_OPTIONS` set +The options set on the ``.qrc`` source file may override :prop_tgt:`AUTORCC_OPTIONS` set on the target. diff --git a/Help/prop_sf/AUTOUIC_OPTIONS.rst b/Help/prop_sf/AUTOUIC_OPTIONS.rst index a38b2f8..6dfabb0 100644 --- a/Help/prop_sf/AUTOUIC_OPTIONS.rst +++ b/Help/prop_sf/AUTOUIC_OPTIONS.rst @@ -1,14 +1,14 @@ AUTOUIC_OPTIONS --------------- -Additional options for uic when using autouic (see the :prop_tgt:`AUTOUIC` target property) +Additional options for ``uic`` when using :prop_tgt:`AUTOUIC` This property holds additional command line options -which will be used when uic is executed during the build via autouic, -i.e. it is equivalent to the optional OPTIONS argument of the -qt4_wrap_ui() macro. +which will be used when ``uic`` is executed during the build via :prop_tgt:`AUTOUIC`, +i.e. it is equivalent to the optional ``OPTIONS`` argument of the +:module:`qt4_wrap_ui()<FindQt4>` macro. By default it is empty. -The options set on the .ui source file may override :prop_tgt:`AUTOUIC_OPTIONS` set +The options set on the ``.ui`` source file may override :prop_tgt:`AUTOUIC_OPTIONS` set on the target. diff --git a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst index 006c83a..2bc1881 100644 --- a/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst +++ b/Help/prop_tgt/AUTOGEN_TARGET_DEPENDS.rst @@ -3,10 +3,10 @@ AUTOGEN_TARGET_DEPENDS Target dependencies of the corresponding ``_automoc`` target. -Targets which have their :prop_tgt:`AUTOMOC` target set to true have a +Targets which have their :prop_tgt:`AUTOMOC` target set to ``TRUE`` have a corresponding ``_automoc`` target which is used to autogenerate generate moc files. As this ``_automoc`` target is created at generate-time, it is not -possible to define dependencies of it, such as to create inputs for the moc +possible to define dependencies of it, such as to create inputs for the ``moc`` executable. The ``AUTOGEN_TARGET_DEPENDS`` target can be set instead to a list of dependencies diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst index 8af1116..16094c7 100644 --- a/Help/prop_tgt/AUTOMOC.rst +++ b/Help/prop_tgt/AUTOMOC.rst @@ -3,29 +3,29 @@ AUTOMOC Should the target be processed with automoc (for Qt projects). -AUTOMOC is a boolean specifying whether CMake will handle the Qt moc +AUTOMOC is a boolean specifying whether CMake will handle the Qt ``moc`` preprocessor automatically, i.e. without having to use the -QT4_WRAP_CPP() or QT5_WRAP_CPP() macro. Currently Qt4 and Qt5 are -supported. When this property is set to TRUE, CMake will scan the -source files at build time and invoke moc accordingly. If an #include -statement like #include "moc_foo.cpp" is found, the Q_OBJECT class -declaration is expected in the header, and moc is run on the header -file. If an #include statement like #include "foo.moc" is found, then -a Q_OBJECT is expected in the current source file and moc is run on +:module:`QT4_WRAP_CPP() <FindQt4>` or QT5_WRAP_CPP() macro. Currently Qt4 and Qt5 are +supported. When this property is set to ``TRUE``, CMake will scan the +source files at build time and invoke moc accordingly. If an ``#include`` +statement like ``#include "moc_foo.cpp"`` is found, the ``Q_OBJECT`` class +declaration is expected in the header, and ``moc`` is run on the header +file. If an ``#include`` statement like ``#include "foo.moc"`` is found, then +a ``Q_OBJECT`` is expected in the current source file and ``moc`` is run on the file itself. Additionally, all header files are parsed for -Q_OBJECT macros, and if found, moc is also executed on those files. +``Q_OBJECT`` macros, and if found, ``moc`` is also executed on those files. The resulting moc files, which are not included as shown above in any of the source files are included in a generated -<targetname>_automoc.cpp file, which is compiled as part of the -target.This property is initialized by the value of the variable -CMAKE_AUTOMOC if it is set when a target is created. +``<targetname>_automoc.cpp`` file, which is compiled as part of the +target. This property is initialized by the value of the variable +:variable:`CMAKE_AUTOMOC` if it is set when a target is created. Additional command line options for moc can be set via the -AUTOMOC_MOC_OPTIONS property. +:prop_tgt:`AUTOMOC_MOC_OPTIONS` property. -By setting the CMAKE_AUTOMOC_RELAXED_MODE variable to TRUE the rules -for searching the files which will be processed by moc can be relaxed. +By setting the :variable:`CMAKE_AUTOMOC_RELAXED_MODE` variable to ``TRUE`` the +rules for searching the files which will be processed by moc can be relaxed. See the documentation for this variable for more details. -The global property AUTOMOC_TARGETS_FOLDER can be used to group the +The global property :prop_gbl:`AUTOMOC_TARGETS_FOLDER` can be used to group the automoc targets together in an IDE, e.g. in MSVS. diff --git a/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst b/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst index 6ab5c85..d086bf5 100644 --- a/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst +++ b/Help/prop_tgt/AUTOMOC_MOC_OPTIONS.rst @@ -1,12 +1,12 @@ AUTOMOC_MOC_OPTIONS ------------------- -Additional options for moc when using automoc (see the AUTOMOC property) +Additional options for moc when using :prop_tgt:`AUTOMOC` -This property is only used if the AUTOMOC property is set to TRUE for -this target. In this case, it holds additional command line options -which will be used when moc is executed during the build, i.e. it is -equivalent to the optional OPTIONS argument of the qt4_wrap_cpp() +This property is only used if the :prop_tgt:`AUTOMOC` property is set to ``TRUE`` +for this target. In this case, it holds additional command line options +which will be used when ``moc`` is executed during the build, i.e. it is +equivalent to the optional ``OPTIONS`` argument of the :module:`qt4_wrap_cpp() <FindQt4>` macro. By default it is empty. diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst index ef2c9c8..f6409ea 100644 --- a/Help/prop_tgt/AUTORCC.rst +++ b/Help/prop_tgt/AUTORCC.rst @@ -4,18 +4,18 @@ AUTORCC Should the target be processed with autorcc (for Qt projects). -AUTORCC is a boolean specifying whether CMake will handle -the Qt rcc code generator automatically, i.e. without having to use -the QT4_ADD_RESOURCES() or QT5_ADD_RESOURCES() macro. Currently Qt4 and Qt5 are -supported. +``AUTORCC`` is a boolean specifying whether CMake will handle +the Qt ``rcc`` code generator automatically, i.e. without having to use +the :module:`QT4_ADD_RESOURCES() <FindQt4>` or QT5_ADD_RESOURCES() macro. +Currently Qt4 and Qt5 are supported. -When this property is set to TRUE, CMake will handle .qrc files added -as target sources at build time and invoke rcc accordingly. +When this property is set to ``TRUE``, CMake will handle ``.qrc`` files added +as target sources at build time and invoke ``rcc`` accordingly. This property is initialized by the value of the :variable:`CMAKE_AUTORCC` variable if it is set when a target is created. Additional command line options for rcc can be set via the -:prop_sf:`AUTORCC_OPTIONS` source file property on the .qrc file. +:prop_sf:`AUTORCC_OPTIONS` source file property on the ``.qrc`` file. The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the autouic targets together in an IDE, e.g. in MSVS. diff --git a/Help/prop_tgt/AUTORCC_OPTIONS.rst b/Help/prop_tgt/AUTORCC_OPTIONS.rst index 489e277..1dd82ee 100644 --- a/Help/prop_tgt/AUTORCC_OPTIONS.rst +++ b/Help/prop_tgt/AUTORCC_OPTIONS.rst @@ -1,12 +1,12 @@ AUTORCC_OPTIONS --------------- -Additional options for rcc when using autorcc (see the :prop_tgt:`AUTORCC` target property) +Additional options for ``rcc`` when using :prop_tgt:`AUTORCC` This property holds additional command line options -which will be used when rcc is executed during the build via autorcc, -i.e. it is equivalent to the optional OPTIONS argument of the -qt4_add_resources() macro. +which will be used when ``rcc`` is executed during the build via :prop_tgt:`AUTORCC`, +i.e. it is equivalent to the optional ``OPTIONS`` argument of the +:module:`qt4_add_resources() <FindQt4>` macro. By default it is empty. @@ -14,4 +14,4 @@ This property is initialized by the value of the variable :variable:`CMAKE_AUTORCC` if it is set when a target is created. The options set on the target may be overridden by :prop_sf:`AUTORCC_OPTIONS` set -on the .qrc source file. +on the ``.qrc`` source file. diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst index 548c259..010c027 100644 --- a/Help/prop_tgt/AUTOUIC.rst +++ b/Help/prop_tgt/AUTOUIC.rst @@ -3,20 +3,20 @@ AUTOUIC Should the target be processed with autouic (for Qt projects). -AUTOUIC is a boolean specifying whether CMake will handle -the Qt uic code generator automatically, i.e. without having to use -the QT4_WRAP_UI() or QT5_WRAP_UI() macro. Currently Qt4 and Qt5 are -supported. +``AUTOUIC`` is a boolean specifying whether CMake will handle +the Qt ``uic`` code generator automatically, i.e. without having to use +the :module:`QT4_WRAP_UI() <FindQt4>` or QT5_WRAP_UI() macro. Currently Qt4 +and Qt5 are supported. -When this property is set to TRUE, CMake will scan the source files -at build time and invoke uic accordingly. -If an #include statement like #include "ui_foo.h" is found in -foo.cpp, a foo.ui file is expected next to foo.cpp, and uic is -run on the foo.ui file. +When this property is set to ``TRUE``, CMake will scan the source files +at build time and invoke ``uic`` accordingly. +If an ``#include`` statement like ``#include "ui_foo.h"`` is found in +``foo.cpp``, a ``foo.ui`` file is expected next to ``foo.cpp``, and ``uic`` is +run on the ``foo.ui`` file. This property is initialized by the value of the :variable:`CMAKE_AUTOUIC` variable if it is set when a target is created. Additional command line options for uic can be set via the -:prop_sf:`AUTOUIC_OPTIONS` source file property on the foo.ui file. +:prop_sf:`AUTOUIC_OPTIONS` source file property on the ``foo.ui`` file. The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the autouic targets together in an IDE, e.g. in MSVS. diff --git a/Help/prop_tgt/AUTOUIC_OPTIONS.rst b/Help/prop_tgt/AUTOUIC_OPTIONS.rst index aeec38b..d0f865c 100644 --- a/Help/prop_tgt/AUTOUIC_OPTIONS.rst +++ b/Help/prop_tgt/AUTOUIC_OPTIONS.rst @@ -1,12 +1,12 @@ AUTOUIC_OPTIONS --------------- -Additional options for uic when using autouic (see the :prop_tgt:`AUTOUIC` target property) +Additional options for uic when using :prop_tgt:`AUTOUIC` This property holds additional command line options -which will be used when uic is executed during the build via autouic, -i.e. it is equivalent to the optional OPTIONS argument of the -qt4_wrap_ui() macro. +which will be used when ``uic`` is executed during the build via :prop_tgt:`AUTOUIC`, +i.e. it is equivalent to the optional ``OPTIONS`` argument of the +:module:`qt4_wrap_ui() <FindQt4>` macro. By default it is empty. @@ -14,7 +14,7 @@ This property is initialized by the value of the variable :variable:`CMAKE_AUTOUIC` if it is set when a target is created. The options set on the target may be overridden by :prop_sf:`AUTOUIC_OPTIONS` set -on the .ui source file. +on the ``.ui`` source file. This property may use "generator expressions" with the syntax "$<...>". See the :manual:`cmake-generator-expressions(7)` manual for available diff --git a/Help/variable/CMAKE_AUTOMOC.rst b/Help/variable/CMAKE_AUTOMOC.rst index 87e8a9b..02e5eb5 100644 --- a/Help/variable/CMAKE_AUTOMOC.rst +++ b/Help/variable/CMAKE_AUTOMOC.rst @@ -1,7 +1,7 @@ CMAKE_AUTOMOC ------------- -Whether to handle moc automatically for Qt targets. +Whether to handle ``moc`` automatically for Qt targets. -This variable is used to initialize the AUTOMOC property on all the +This variable is used to initialize the :prop_tgt:`AUTOMOC` property on all the targets. See that target property for additional information. diff --git a/Help/variable/CMAKE_AUTOMOC_MOC_OPTIONS.rst b/Help/variable/CMAKE_AUTOMOC_MOC_OPTIONS.rst index bdbed85..09bf5cd 100644 --- a/Help/variable/CMAKE_AUTOMOC_MOC_OPTIONS.rst +++ b/Help/variable/CMAKE_AUTOMOC_MOC_OPTIONS.rst @@ -1,8 +1,7 @@ CMAKE_AUTOMOC_MOC_OPTIONS ------------------------- -Additional options for moc when using automoc (see CMAKE_AUTOMOC). +Additional options for ``moc`` when using :variable:`CMAKE_AUTOMOC`. -This variable is used to initialize the AUTOMOC_MOC_OPTIONS property -on all the targets. See that target property for additional -information. +This variable is used to initialize the :prop_tgt:`AUTOMOC_MOC_OPTIONS` property +on all the targets. See that target property for additional information. diff --git a/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst b/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst index 8858410..a814d40 100644 --- a/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst +++ b/Help/variable/CMAKE_AUTOMOC_RELAXED_MODE.rst @@ -3,11 +3,11 @@ CMAKE_AUTOMOC_RELAXED_MODE Switch between strict and relaxed automoc mode. -By default, automoc behaves exactly as described in the documentation -of the AUTOMOC target property. When set to TRUE, it accepts more -input and tries to find the correct input file for moc even if it +By default, :prop_tgt:`AUTOMOC` behaves exactly as described in the documentation +of the :prop_tgt:`AUTOMOC` target property. When set to ``TRUE``, it accepts more +input and tries to find the correct input file for ``moc`` even if it differs from the documented behaviour. In this mode it e.g. also checks whether a header file is intended to be processed by moc when a -"foo.moc" file has been included. +``"foo.moc"`` file has been included. Relaxed mode has to be enabled for KDE4 compatibility. diff --git a/Help/variable/CMAKE_AUTORCC.rst b/Help/variable/CMAKE_AUTORCC.rst index d213993..067f766 100644 --- a/Help/variable/CMAKE_AUTORCC.rst +++ b/Help/variable/CMAKE_AUTORCC.rst @@ -1,7 +1,7 @@ CMAKE_AUTORCC ------------- -Whether to handle rcc automatically for Qt targets. +Whether to handle ``rcc`` automatically for Qt targets. This variable is used to initialize the :prop_tgt:`AUTORCC` property on all the targets. See that target property for additional information. diff --git a/Help/variable/CMAKE_AUTORCC_OPTIONS.rst b/Help/variable/CMAKE_AUTORCC_OPTIONS.rst index 5efbfa3..298cb6b 100644 --- a/Help/variable/CMAKE_AUTORCC_OPTIONS.rst +++ b/Help/variable/CMAKE_AUTORCC_OPTIONS.rst @@ -1,7 +1,7 @@ CMAKE_AUTORCC_OPTIONS --------------------- -Whether to handle rcc automatically for Qt targets. +Whether to handle ``rcc`` automatically for Qt targets. This variable is used to initialize the :prop_tgt:`AUTORCC_OPTIONS` property on all the targets. See that target property for additional information. diff --git a/Help/variable/CMAKE_AUTOUIC.rst b/Help/variable/CMAKE_AUTOUIC.rst index 3b016b0..0beb555 100644 --- a/Help/variable/CMAKE_AUTOUIC.rst +++ b/Help/variable/CMAKE_AUTOUIC.rst @@ -1,7 +1,7 @@ CMAKE_AUTOUIC ------------- -Whether to handle uic automatically for Qt targets. +Whether to handle ``uic`` automatically for Qt targets. This variable is used to initialize the :prop_tgt:`AUTOUIC` property on all the targets. See that target property for additional information. diff --git a/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst b/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst index 6a88669..3c9b8c4 100644 --- a/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst +++ b/Help/variable/CMAKE_AUTOUIC_OPTIONS.rst @@ -1,7 +1,7 @@ CMAKE_AUTOUIC_OPTIONS --------------------- -Whether to handle uic automatically for Qt targets. +Whether to handle ``uic`` automatically for Qt targets. This variable is used to initialize the :prop_tgt:`AUTOUIC_OPTIONS` property on all the targets. See that target property for additional information. diff --git a/Modules/FindDevIL.cmake b/Modules/FindDevIL.cmake index 22a82b5..865d061 100644 --- a/Modules/FindDevIL.cmake +++ b/Modules/FindDevIL.cmake @@ -49,7 +49,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) find_path(IL_INCLUDE_DIR il.h PATH_SUFFIXES include IL - DOC "The path the the directory that contains il.h" + DOC "The path to the directory that contains il.h" ) #message("IL_INCLUDE_DIR is ${IL_INCLUDE_DIR}") diff --git a/Modules/FindSDL.cmake b/Modules/FindSDL.cmake index ec1f881..3905e54 100644 --- a/Modules/FindSDL.cmake +++ b/Modules/FindSDL.cmake @@ -15,7 +15,7 @@ # # # -# This module responds to the the flag: +# This module responds to the flag: # # :: # @@ -23,7 +23,7 @@ # If this is defined, then no SDL_main will be linked in because # only applications need main(). # Otherwise, it is assumed you are building an application and this -# module will attempt to locate and set the the proper link flags +# module will attempt to locate and set the proper link flags # as part of the returned SDL_LIBRARY variable. # # diff --git a/Modules/GenerateExportHeader.cmake b/Modules/GenerateExportHeader.cmake index 5baf9e0..f83f992 100644 --- a/Modules/GenerateExportHeader.cmake +++ b/Modules/GenerateExportHeader.cmake @@ -6,14 +6,11 @@ # # This module provides the function GENERATE_EXPORT_HEADER(). # -# The GENERATE_EXPORT_HEADER function can be used to generate a file +# The ``GENERATE_EXPORT_HEADER`` function can be used to generate a file # suitable for preprocessor inclusion which contains EXPORT macros to be -# used in library classes. -# -# GENERATE_EXPORT_HEADER( LIBRARY_TARGET -# -# :: +# used in library classes:: # +# GENERATE_EXPORT_HEADER( LIBRARY_TARGET # [BASE_NAME <base_name>] # [EXPORT_MACRO_NAME <export_macro_name>] # [EXPORT_FILE_NAME <export_file_name>] @@ -23,20 +20,21 @@ # [NO_DEPRECATED_MACRO_NAME <no_deprecated_macro_name>] # [DEFINE_NO_DEPRECATED] # [PREFIX_NAME <prefix_name>] +# ) # -# ) # -# The target properties CXX_VISIBILITY_PRESET and -# VISIBILITY_INLINES_HIDDEN can be used to add the appropriate compile -# flags for targets. See the documentation of those target properties, -# and the convenience variables CMAKE_CXX_VISIBILITY_PRESET and -# CMAKE_VISIBILITY_INLINES_HIDDEN. +# The target properties :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>` +# and :prop_tgt:`VISIBILITY_INLINES_HIDDEN` can be used to add the appropriate +# compile flags for targets. See the documentation of those target properties, +# and the convenience variables +# :variable:`CMAKE_CXX_VISIBILITY_PRESET <CMAKE_<LANG>_VISIBILITY_PRESET>` and +# :variable:`CMAKE_VISIBILITY_INLINES_HIDDEN`. # -# By default GENERATE_EXPORT_HEADER() generates macro names in a file +# By default ``GENERATE_EXPORT_HEADER()`` generates macro names in a file # name determined by the name of the library. This means that in the -# simplest case, users of generate_export_header will be equivalent to: +# simplest case, users of ``GenerateExportHeader`` will be equivalent to: # -# :: +# .. code-block:: cmake # # set(CMAKE_CXX_VISIBILITY_PRESET hidden) # set(CMAKE_VISIBILITY_INLINES_HIDDEN 1) @@ -49,10 +47,9 @@ # ) # # -# # And in the ABI header files: # -# :: +# .. code-block:: c++ # # #include "somelib_export.h" # class SOMELIB_EXPORT SomeClass { @@ -60,17 +57,16 @@ # }; # # -# # The CMake fragment will generate a file in the -# ${CMAKE_CURRENT_BINARY_DIR} called somelib_export.h containing the -# macros SOMELIB_EXPORT, SOMELIB_NO_EXPORT, SOMELIB_DEPRECATED, -# SOMELIB_DEPRECATED_EXPORT and SOMELIB_DEPRECATED_NO_EXPORT. The +# ``${CMAKE_CURRENT_BINARY_DIR}`` called ``somelib_export.h`` containing the +# macros ``SOMELIB_EXPORT``, ``SOMELIB_NO_EXPORT``, ``SOMELIB_DEPRECATED``, +# ``SOMELIB_DEPRECATED_EXPORT`` and ``SOMELIB_DEPRECATED_NO_EXPORT``. The # resulting file should be installed with other headers in the library. # -# The BASE_NAME argument can be used to override the file name and the -# names used for the macros +# The ``BASE_NAME`` argument can be used to override the file name and the +# names used for the macros: # -# :: +# .. code-block:: cmake # # add_library(somelib someclass.cpp) # generate_export_header(somelib @@ -78,14 +74,14 @@ # ) # # +# Generates a file called ``other_name_export.h`` containing the macros +# ``OTHER_NAME_EXPORT``, ``OTHER_NAME_NO_EXPORT`` and ``OTHER_NAME_DEPRECATED`` +# etc. # -# Generates a file called other_name_export.h containing the macros -# OTHER_NAME_EXPORT, OTHER_NAME_NO_EXPORT and OTHER_NAME_DEPRECATED etc. -# -# The BASE_NAME may be overridden by specifiying other options in the +# The ``BASE_NAME`` may be overridden by specifiying other options in the # function. For example: # -# :: +# .. code-block:: cmake # # add_library(somelib someclass.cpp) # generate_export_header(somelib @@ -93,11 +89,10 @@ # ) # # +# creates the macro ``OTHER_NAME_EXPORT`` instead of ``SOMELIB_EXPORT``, but +# other macros and the generated file name is as default: # -# creates the macro OTHER_NAME_EXPORT instead of SOMELIB_EXPORT, but -# other macros and the generated file name is as default. -# -# :: +# .. code-block:: cmake # # add_library(somelib someclass.cpp) # generate_export_header(somelib @@ -105,17 +100,16 @@ # ) # # +# creates the macro ``KDE_DEPRECATED`` instead of ``SOMELIB_DEPRECATED``. # -# creates the macro KDE_DEPRECATED instead of SOMELIB_DEPRECATED. -# -# If LIBRARY_TARGET is a static library, macros are defined without +# If ``LIBRARY_TARGET`` is a static library, macros are defined without # values. # # If the same sources are used to create both a shared and a static -# library, the uppercased symbol ${BASE_NAME}_STATIC_DEFINE should be -# used when building the static library +# library, the uppercased symbol ``${BASE_NAME}_STATIC_DEFINE`` should be +# used when building the static library: # -# :: +# .. code-block:: cmake # # add_library(shared_variant SHARED ${lib_SRCS}) # add_library(static_variant ${lib_SRCS}) @@ -123,16 +117,14 @@ # set_target_properties(static_variant PROPERTIES # COMPILE_FLAGS -DLIBSHARED_AND_STATIC_STATIC_DEFINE) # -# -# # This will cause the export macros to expand to nothing when building # the static library. # -# If DEFINE_NO_DEPRECATED is specified, then a macro -# ${BASE_NAME}_NO_DEPRECATED will be defined This macro can be used to -# remove deprecated code from preprocessor output. +# If ``DEFINE_NO_DEPRECATED`` is specified, then a macro +# ``${BASE_NAME}_NO_DEPRECATED`` will be defined This macro can be used to +# remove deprecated code from preprocessor output: # -# :: +# .. code-block:: cmake # # option(EXCLUDE_DEPRECATED "Exclude deprecated parts of the library" FALSE) # if (EXCLUDE_DEPRECATED) @@ -141,10 +133,9 @@ # generate_export_header(somelib ${NO_BUILD_DEPRECATED}) # # -# # And then in somelib: # -# :: +# .. code-block:: c++ # # class SOMELIB_EXPORT SomeClass # { @@ -154,42 +145,38 @@ # #endif # }; # -# -# -# :: +# .. code-block:: c++ # # #ifndef SOMELIB_NO_DEPRECATED # void SomeClass::oldMethod() { } # #endif # # -# -# If PREFIX_NAME is specified, the argument will be used as a prefix to +# If ``PREFIX_NAME`` is specified, the argument will be used as a prefix to # all generated macros. # # For example: # -# :: +# .. code-block:: cmake # # generate_export_header(somelib PREFIX_NAME VTK_) # +# Generates the macros ``VTK_SOMELIB_EXPORT`` etc. # +# :: # -# Generates the macros VTK_SOMELIB_EXPORT etc. -# -# -# -# ADD_COMPILER_EXPORT_FLAGS( [<output_variable>] ) +# ADD_COMPILER_EXPORT_FLAGS( [<output_variable>] ) # -# The ADD_COMPILER_EXPORT_FLAGS function adds -fvisibility=hidden to -# CMAKE_CXX_FLAGS if supported, and is a no-op on Windows which does not -# need extra compiler flags for exporting support. You may optionally -# pass a single argument to ADD_COMPILER_EXPORT_FLAGS that will be -# populated with the required CXX_FLAGS required to enable visibility +# The ``ADD_COMPILER_EXPORT_FLAGS`` function adds ``-fvisibility=hidden`` to +# :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>` if supported, and is a no-op +# on Windows which does not need extra compiler flags for exporting support. +# You may optionally pass a single argument to ``ADD_COMPILER_EXPORT_FLAGS`` +# that will be populated with the ``CXX_FLAGS`` required to enable visibility # support for the compiler/architecture in use. # # This function is deprecated. Set the target properties -# CXX_VISIBILITY_PRESET and VISIBILITY_INLINES_HIDDEN instead. +# :prop_tgt:`CXX_VISIBILITY_PRESET <<LANG>_VISIBILITY_PRESET>` and +# :prop_tgt:`VISIBILITY_INLINES_HIDDEN` instead. #============================================================================= # Copyright 2011 Stephen Kelly <steveire@gmail.com> diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index 937a5fe..90d311c 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -2,5 +2,5 @@ set(CMake_VERSION_MAJOR 2) set(CMake_VERSION_MINOR 8) set(CMake_VERSION_PATCH 12) -set(CMake_VERSION_TWEAK 20140104) +set(CMake_VERSION_TWEAK 20140107) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx index 438b16d..a19b778 100644 --- a/Source/CPack/cpack.cxx +++ b/Source/CPack/cpack.cxx @@ -25,6 +25,7 @@ #include <cmsys/CommandLineArguments.hxx> #include <cmsys/SystemTools.hxx> +#include <cmsys/Encoding.hxx> //---------------------------------------------------------------------------- static const char * cmDocumentationName[][2] = @@ -97,8 +98,13 @@ int cpackDefinitionArgument(const char* argument, const char* cValue, //---------------------------------------------------------------------------- // this is CPack. -int main (int argc, char *argv[]) +int main (int argc, char const* const* argv) { + cmsys::Encoding::CommandLineArguments args = + cmsys::Encoding::CommandLineArguments::Main(argc, argv); + argc = args.argc(); + argv = args.argv(); + cmSystemTools::FindCMakeResources(argv[0]); cmCPackLog log; diff --git a/Source/CursesDialog/ccmake.cxx b/Source/CursesDialog/ccmake.cxx index ce50845..2d1ef5c 100644 --- a/Source/CursesDialog/ccmake.cxx +++ b/Source/CursesDialog/ccmake.cxx @@ -19,6 +19,7 @@ #include "cmCursesMainForm.h" #include "cmCursesStandardIncludes.h" +#include <cmsys/Encoding.hxx> #include <form.h> @@ -78,8 +79,13 @@ void CMakeErrorHandler(const char* message, const char* title, bool&, void* clie self->AddError(message, title); } -int main(int argc, char** argv) +int main(int argc, char const* const* argv) { + cmsys::Encoding::CommandLineArguments encoding_args = + cmsys::Encoding::CommandLineArguments::Main(argc, argv); + argc = encoding_args.argc(); + argv = encoding_args.argv(); + cmSystemTools::FindCMakeResources(argv[0]); cmDocumentation doc; doc.addCMakeStandardDocSections(); diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 408bb4c..821121e 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -21,6 +21,7 @@ #include "cmVersion.h" #include <cmsys/CommandLineArguments.hxx> #include <cmsys/SystemTools.hxx> +#include <cmsys/Encoding.hxx> //---------------------------------------------------------------------------- static const char * cmDocumentationName[][2] = @@ -48,12 +49,17 @@ static const char * cmDocumentationOptions[][2] = int main(int argc, char** argv) { - cmSystemTools::FindCMakeResources(argv[0]); + cmsys::Encoding::CommandLineArguments encoding_args = + cmsys::Encoding::CommandLineArguments::Main(argc, argv); + int argc2 = encoding_args.argc(); + char const* const* argv2 = encoding_args.argv(); + + cmSystemTools::FindCMakeResources(argv2[0]); // check docs first so that X is not need to get docs // do docs, if args were given cmDocumentation doc; doc.addCMakeStandardDocSections(); - if(argc >1 && doc.CheckOptions(argc, argv)) + if(argc2 >1 && doc.CheckOptions(argc2, argv2)) { // Construct and print requested documentation. cmake hcm; @@ -80,9 +86,9 @@ int main(int argc, char** argv) } // if arg for install - for(int i =0; i < argc; i++) + for(int i =0; i < argc2; i++) { - if(strcmp(argv[i], "--mac-install") == 0) + if(strcmp(argv2[i], "--mac-install") == 0) { QMacInstallDialog setupdialog(0); setupdialog.exec(); @@ -116,7 +122,7 @@ int main(int argc, char** argv) dialog.show(); cmsys::CommandLineArguments arg; - arg.Initialize(argc, argv); + arg.Initialize(argc2, argv2); std::string binaryDirectory; std::string sourceDirectory; typedef cmsys::CommandLineArguments argT; diff --git a/Source/cmAddDependenciesCommand.cxx b/Source/cmAddDependenciesCommand.cxx index e4d7f7f..87bfb3c 100644 --- a/Source/cmAddDependenciesCommand.cxx +++ b/Source/cmAddDependenciesCommand.cxx @@ -33,6 +33,15 @@ bool cmAddDependenciesCommand } if(cmTarget* target = this->Makefile->FindTargetToUse(target_name.c_str())) { + if (target->GetType() == cmTarget::INTERFACE_LIBRARY) + { + cmOStringStream e; + e << "Cannot add target-level dependencies to INTERFACE library " + "target \"" << target_name << "\".\n"; + this->SetError(e.str().c_str()); + return false; + } + std::vector<std::string>::const_iterator s = args.begin(); ++s; // skip over target_name for (; s != args.end(); ++s) diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 0f98f35..2627445 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -49,47 +49,117 @@ bool cmAddLibraryCommand std::string libType = *s; if(libType == "STATIC") { + if (type == cmTarget::INTERFACE_LIBRARY) + { + cmOStringStream e; + e << "INTERFACE library specified with conflicting STATIC type."; + this->SetError(e.str().c_str()); + return false; + } ++s; type = cmTarget::STATIC_LIBRARY; haveSpecifiedType = true; } else if(libType == "SHARED") { + if (type == cmTarget::INTERFACE_LIBRARY) + { + cmOStringStream e; + e << "INTERFACE library specified with conflicting SHARED type."; + this->SetError(e.str().c_str()); + return false; + } ++s; type = cmTarget::SHARED_LIBRARY; haveSpecifiedType = true; } else if(libType == "MODULE") { + if (type == cmTarget::INTERFACE_LIBRARY) + { + cmOStringStream e; + e << "INTERFACE library specified with conflicting MODULE type."; + this->SetError(e.str().c_str()); + return false; + } ++s; type = cmTarget::MODULE_LIBRARY; haveSpecifiedType = true; } else if(libType == "OBJECT") { + if (type == cmTarget::INTERFACE_LIBRARY) + { + cmOStringStream e; + e << "INTERFACE library specified with conflicting OBJECT type."; + this->SetError(e.str().c_str()); + return false; + } ++s; type = cmTarget::OBJECT_LIBRARY; haveSpecifiedType = true; } else if(libType == "UNKNOWN") { + if (type == cmTarget::INTERFACE_LIBRARY) + { + cmOStringStream e; + e << "INTERFACE library specified with conflicting UNKNOWN type."; + this->SetError(e.str().c_str()); + return false; + } ++s; type = cmTarget::UNKNOWN_LIBRARY; haveSpecifiedType = true; } else if(libType == "ALIAS") { + if (type == cmTarget::INTERFACE_LIBRARY) + { + cmOStringStream e; + e << "INTERFACE library specified with conflicting ALIAS type."; + this->SetError(e.str().c_str()); + return false; + } ++s; isAlias = true; } else if(libType == "INTERFACE") { + if (haveSpecifiedType) + { + cmOStringStream e; + e << "INTERFACE library specified with conflicting/multiple types."; + this->SetError(e.str().c_str()); + return false; + } + if (isAlias) + { + cmOStringStream e; + e << "INTERFACE library specified with conflicting ALIAS type."; + this->SetError(e.str().c_str()); + return false; + } + if (excludeFromAll) + { + cmOStringStream e; + e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL."; + this->SetError(e.str().c_str()); + return false; + } ++s; type = cmTarget::INTERFACE_LIBRARY; haveSpecifiedType = true; } else if(*s == "EXCLUDE_FROM_ALL") { + if (type == cmTarget::INTERFACE_LIBRARY) + { + cmOStringStream e; + e << "INTERFACE library may not be used with EXCLUDE_FROM_ALL."; + this->SetError(e.str().c_str()); + return false; + } ++s; excludeFromAll = true; } @@ -109,6 +179,24 @@ bool cmAddLibraryCommand } } + if (type == cmTarget::INTERFACE_LIBRARY) + { + if (s != args.end()) + { + cmOStringStream e; + e << "INTERFACE library requires no source arguments."; + this->SetError(e.str().c_str()); + return false; + } + if (importGlobal && !importTarget) + { + cmOStringStream e; + e << "INTERFACE library specified as GLOBAL, but not as IMPORTED."; + this->SetError(e.str().c_str()); + return false; + } + } + bool nameOk = cmGeneratorExpression::IsValidTargetName(libName) && !cmGlobalGenerator::IsReservedTarget(libName); diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx index b6bf870..7c97d8d 100644 --- a/Source/cmExportCommand.cxx +++ b/Source/cmExportCommand.cxx @@ -236,8 +236,14 @@ bool cmExportCommand { ebfg->AddConfiguration(""); } - - gg->AddBuildExportSet(ebfg); + if (this->ExportSet) + { + gg->AddBuildExportExportSet(ebfg); + } + else + { + gg->AddBuildExportSet(ebfg); + } return true; } diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx index d5f81ce..13bff19 100644 --- a/Source/cmExportFileGenerator.cxx +++ b/Source/cmExportFileGenerator.cxx @@ -826,36 +826,36 @@ cmExportFileGenerator ::SetImportLinkProperty(std::string const& suffix, cmTarget* target, const char* propName, - std::vector<std::string> const& libs, + std::vector<std::string> const& entries, ImportPropertyMap& properties, std::vector<std::string>& missingTargets ) { - // Skip the property if there are no libraries. - if(libs.empty()) + // Skip the property if there are no entries. + if(entries.empty()) { return; } // Construct the property value. - std::string link_libs; + std::string link_entries; const char* sep = ""; - for(std::vector<std::string>::const_iterator li = libs.begin(); - li != libs.end(); ++li) + for(std::vector<std::string>::const_iterator li = entries.begin(); + li != entries.end(); ++li) { // Separate this from the previous entry. - link_libs += sep; + link_entries += sep; sep = ";"; std::string temp = *li; this->AddTargetNamespace(temp, target, missingTargets); - link_libs += temp; + link_entries += temp; } // Store the property. std::string prop = propName; prop += suffix; - properties[prop] = link_libs; + properties[prop] = link_entries; } diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h index 6fd23b0..1438f4d 100644 --- a/Source/cmExportFileGenerator.h +++ b/Source/cmExportFileGenerator.h @@ -82,7 +82,7 @@ protected: std::vector<std::string>& missingTargets); void SetImportLinkProperty(std::string const& suffix, cmTarget* target, const char* propName, - std::vector<std::string> const& libs, + std::vector<std::string> const& entries, ImportPropertyMap& properties, std::vector<std::string>& missingTargets); diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx index 1025dc0..73e9b31 100644 --- a/Source/cmExportInstallFileGenerator.cxx +++ b/Source/cmExportInstallFileGenerator.cxx @@ -114,13 +114,18 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) std::vector<std::string> missingTargets; bool require2_8_12 = false; - bool require2_8_13 = false; + bool require3_0_0 = false; + bool requiresConfigFiles = false; // Create all the imported targets. for(std::vector<cmTargetExport*>::const_iterator tei = allTargets.begin(); tei != allTargets.end(); ++tei) { cmTarget* te = (*tei)->Target; + + requiresConfigFiles = requiresConfigFiles + || te->GetType() != cmTarget::INTERFACE_LIBRARY; + this->GenerateImportTargetCode(os, te); ImportPropertyMap properties; @@ -160,7 +165,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) } if (te->GetType() == cmTarget::INTERFACE_LIBRARY) { - require2_8_13 = true; + require3_0_0 = true; } this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE", te, properties); @@ -169,7 +174,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) this->GenerateInterfaceProperties(te, os, properties); } - if (require2_8_13) + if (require3_0_0) { this->GenerateRequiredCMakeVersion(os, "2.8.12.20131007"); } @@ -197,15 +202,19 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os) } this->GenerateImportedFileCheckLoop(os); - // Generate an import file for each configuration. bool result = true; - for(std::vector<std::string>::const_iterator - ci = this->Configurations.begin(); - ci != this->Configurations.end(); ++ci) + // Generate an import file for each configuration. + // Don't do this if we only export INTERFACE_LIBRARY targets. + if (requiresConfigFiles) { - if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets)) + for(std::vector<std::string>::const_iterator + ci = this->Configurations.begin(); + ci != this->Configurations.end(); ++ci) { - result = false; + if(!this->GenerateImportFileConfig(ci->c_str(), missingTargets)) + { + result = false; + } } } diff --git a/Source/cmExportTryCompileFileGenerator.cxx b/Source/cmExportTryCompileFileGenerator.cxx index d9bc04c..8d37b62 100644 --- a/Source/cmExportTryCompileFileGenerator.cxx +++ b/Source/cmExportTryCompileFileGenerator.cxx @@ -36,6 +36,8 @@ bool cmExportTryCompileFileGenerator::GenerateMainFile(std::ostream& os) CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(FIND_TARGETS) +#undef FIND_TARGETS + this->PopulateProperties(te, properties, emittedDeps); this->GenerateInterfaceProperties(te, os, properties); diff --git a/Source/cmExtraEclipseCDT4Generator.cxx b/Source/cmExtraEclipseCDT4Generator.cxx index 755b445..c93187e 100644 --- a/Source/cmExtraEclipseCDT4Generator.cxx +++ b/Source/cmExtraEclipseCDT4Generator.cxx @@ -40,6 +40,7 @@ cmExtraEclipseCDT4Generator this->SupportsVirtualFolders = true; this->GenerateLinkedResources = true; this->SupportsGmakeErrorParser = true; + this->SupportsMachO64Parser = true; } //---------------------------------------------------------------------------- @@ -93,6 +94,7 @@ void cmExtraEclipseCDT4Generator::Generate() if (version < 3006) // 3.6 is Helios { this->SupportsVirtualFolders = false; + this->SupportsMachO64Parser = false; } if (version < 3007) // 3.7 is Indigo { @@ -754,7 +756,9 @@ void cmExtraEclipseCDT4Generator::CreateCProjectFile() const } else if (systemName == "Darwin") { - fout << "<extension id=\"org.eclipse.cdt.core.MachO\"" + fout << "<extension id=\"" << + (this->SupportsMachO64Parser ? "org.eclipse.cdt.core.MachO64" + : "org.eclipse.cdt.core.MachO") << "\"" " point=\"org.eclipse.cdt.core.BinaryParser\">\n" "<attribute key=\"c++filt\" value=\"c++filt\"/>\n" "</extension>\n" diff --git a/Source/cmExtraEclipseCDT4Generator.h b/Source/cmExtraEclipseCDT4Generator.h index 9c89f85..d88b247 100644 --- a/Source/cmExtraEclipseCDT4Generator.h +++ b/Source/cmExtraEclipseCDT4Generator.h @@ -115,6 +115,7 @@ private: bool GenerateLinkedResources; bool SupportsVirtualFolders; bool SupportsGmakeErrorParser; + bool SupportsMachO64Parser; }; diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index 92f74f3..c2c4e20 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -40,6 +40,7 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker( CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(TEST_TRANSITIVE_PROPERTY_METHOD) false) ) +#undef TEST_TRANSITIVE_PROPERTY_METHOD { std::map<cmStdString, std::set<cmStdString> >::const_iterator it = top->Seen.find(target); @@ -191,7 +192,8 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingSystemIncludeDirectories() const { const char *prop = this->Property.c_str(); - return strcmp(prop, "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES") == 0; + return (strcmp(prop, "SYSTEM_INCLUDE_DIRECTORIES") == 0 + || strcmp(prop, "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES") == 0); } //---------------------------------------------------------------------------- diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index fd47ad7..98ffd36 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -56,7 +56,9 @@ struct cmGeneratorExpressionDAGChecker #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) \ bool METHOD () const; -CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD) + CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(DECLARE_TRANSITIVE_PROPERTY_METHOD) + +#undef DECLARE_TRANSITIVE_PROPERTY_METHOD bool GetTransitivePropertiesOnly(); void SetTransitivePropertiesOnly() diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index c8010d0..f0e40ea 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -19,6 +19,7 @@ #include <cmsys/String.h> #include <assert.h> +#include <errno.h> //---------------------------------------------------------------------------- #if !defined(__SUNPRO_CC) || __SUNPRO_CC > 0x510 @@ -48,7 +49,7 @@ struct cmGeneratorExpressionNode enum { DynamicParameters = 0, OneOrMoreParameters = -1, - ZeroOrMoreParameters = -2 + OneOrZeroParameters = -2 }; virtual ~cmGeneratorExpressionNode() {} @@ -197,6 +198,92 @@ static const struct StrEqualNode : public cmGeneratorExpressionNode } strEqualNode; //---------------------------------------------------------------------------- +static const struct EqualNode : public cmGeneratorExpressionNode +{ + EqualNode() {} + + virtual int NumExpectedParameters() const { return 2; } + + std::string Evaluate(const std::vector<std::string> ¶meters, + cmGeneratorExpressionContext *context, + const GeneratorExpressionContent *content, + cmGeneratorExpressionDAGChecker *) const + { + char *pEnd; + + int base = 0; + bool flipSign = false; + + const char *lhs = parameters[0].c_str(); + if (cmHasLiteralPrefix(lhs, "0b")) + { + base = 2; + lhs += 2; + } + if (cmHasLiteralPrefix(lhs, "-0b")) + { + base = 2; + lhs += 3; + flipSign = true; + } + if (cmHasLiteralPrefix(lhs, "+0b")) + { + base = 2; + lhs += 3; + } + + long lnum = strtol(lhs, &pEnd, base); + if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) + { + reportError(context, content->GetOriginalExpression(), + "$<EQUAL> parameter " + parameters[0] + " is not a valid integer."); + return std::string(); + } + + if (flipSign) + { + lnum = -lnum; + } + + base = 0; + flipSign = false; + + const char *rhs = parameters[1].c_str(); + if (cmHasLiteralPrefix(rhs, "0b")) + { + base = 2; + rhs += 2; + } + if (cmHasLiteralPrefix(rhs, "-0b")) + { + base = 2; + rhs += 3; + flipSign = true; + } + if (cmHasLiteralPrefix(rhs, "+0b")) + { + base = 2; + rhs += 3; + } + + long rnum = strtol(rhs, &pEnd, base); + if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) + { + reportError(context, content->GetOriginalExpression(), + "$<EQUAL> parameter " + parameters[1] + " is not a valid integer."); + return std::string(); + } + + if (flipSign) + { + rnum = -rnum; + } + + return lnum == rnum ? "1" : "0"; + } +} equalNode; + +//---------------------------------------------------------------------------- static const struct LowerCaseNode : public cmGeneratorExpressionNode { LowerCaseNode() {} @@ -297,7 +384,7 @@ struct CompilerIdNode : public cmGeneratorExpressionNode { CompilerIdNode() {} - virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; } + virtual int NumExpectedParameters() const { return OneOrZeroParameters; } std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters, cmGeneratorExpressionContext *context, @@ -343,12 +430,6 @@ static const struct CCompilerIdNode : public CompilerIdNode const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *dagChecker) const { - if (parameters.size() != 0 && parameters.size() != 1) - { - reportError(context, content->GetOriginalExpression(), - "$<C_COMPILER_ID> expression requires one or two parameters"); - return std::string(); - } if (!context->HeadTarget) { reportError(context, content->GetOriginalExpression(), @@ -371,12 +452,6 @@ static const struct CXXCompilerIdNode : public CompilerIdNode const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *dagChecker) const { - if (parameters.size() != 0 && parameters.size() != 1) - { - reportError(context, content->GetOriginalExpression(), - "$<CXX_COMPILER_ID> expression requires one or two parameters"); - return std::string(); - } if (!context->HeadTarget) { reportError(context, content->GetOriginalExpression(), @@ -394,7 +469,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode { CompilerVersionNode() {} - virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; } + virtual int NumExpectedParameters() const { return OneOrZeroParameters; } std::string EvaluateWithLanguage(const std::vector<std::string> ¶meters, cmGeneratorExpressionContext *context, @@ -439,12 +514,6 @@ static const struct CCompilerVersionNode : public CompilerVersionNode const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *dagChecker) const { - if (parameters.size() != 0 && parameters.size() != 1) - { - reportError(context, content->GetOriginalExpression(), - "$<C_COMPILER_VERSION> expression requires one or two parameters"); - return std::string(); - } if (!context->HeadTarget) { reportError(context, content->GetOriginalExpression(), @@ -467,13 +536,6 @@ static const struct CxxCompilerVersionNode : public CompilerVersionNode const GeneratorExpressionContent *content, cmGeneratorExpressionDAGChecker *dagChecker) const { - if (parameters.size() != 0 && parameters.size() != 1) - { - reportError(context, content->GetOriginalExpression(), - "$<CXX_COMPILER_VERSION> expression requires one or two " - "parameters"); - return std::string(); - } if (!context->HeadTarget) { reportError(context, content->GetOriginalExpression(), @@ -492,7 +554,7 @@ struct PlatformIdNode : public cmGeneratorExpressionNode { PlatformIdNode() {} - virtual int NumExpectedParameters() const { return ZeroOrMoreParameters; } + virtual int NumExpectedParameters() const { return OneOrZeroParameters; } std::string Evaluate(const std::vector<std::string> ¶meters, cmGeneratorExpressionContext *context, @@ -710,6 +772,8 @@ static const char* targetPropertyTransitiveWhitelist[] = { CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME) }; +#undef TRANSITIVE_PROPERTY_NAME + std::string getLinkedTargetsContent(const std::vector<std::string> &libraries, cmTarget const* target, cmTarget const* headTarget, @@ -937,6 +1001,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode ASSERT_TRANSITIVE_PROPERTY_METHOD) false); } +#undef ASSERT_TRANSITIVE_PROPERTY_METHOD } std::string linkedTargetsContent; @@ -1492,6 +1557,8 @@ cmGeneratorExpressionNode* GetNode(const std::string &identifier) return &targetSoNameFileDirNode; else if (identifier == "STREQUAL") return &strEqualNode; + else if (identifier == "EQUAL") + return &equalNode; else if (identifier == "LOWER_CASE") return &lowerCaseNode; else if (identifier == "UPPER_CASE") @@ -1733,6 +1800,12 @@ std::string GeneratorExpressionContent::EvaluateParameters( reportError(context, this->GetOriginalExpression(), "$<" + identifier + "> expression requires at least one parameter."); } + if (numExpected == cmGeneratorExpressionNode::OneOrZeroParameters + && parameters.size() > 2) + { + reportError(context, this->GetOriginalExpression(), "$<" + identifier + + "> expression requires one or zero parameters."); + } return std::string(); } diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index fdd4e6d..6894cfc 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -18,9 +18,12 @@ #include "cmSourceFile.h" #include "cmGeneratorExpression.h" #include "cmGeneratorExpressionDAGChecker.h" +#include "cmComputeLinkInformation.h" #include <queue> +#include "assert.h" + //---------------------------------------------------------------------------- cmGeneratorTarget::cmGeneratorTarget(cmTarget* t): Target(t) { @@ -59,10 +62,50 @@ cmGeneratorTarget::GetSourceDepends(cmSourceFile* sf) const return 0; } +static void handleSystemIncludesDep(cmMakefile *mf, const std::string &name, + const char *config, cmTarget *headTarget, + cmGeneratorExpressionDAGChecker *dagChecker, + std::vector<std::string>& result) +{ + cmTarget* depTgt = mf->FindTargetToUse(name.c_str()); + + if (!depTgt) + { + return; + } + + cmListFileBacktrace lfbt; + + if (const char* dirs = + depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) + { + cmGeneratorExpression ge(lfbt); + cmSystemTools::ExpandListArgument(ge.Parse(dirs) + ->Evaluate(mf, + config, false, headTarget, + depTgt, dagChecker), result); + } + if (!depTgt->IsImported()) + { + return; + } + + if (const char* dirs = + depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) + { + cmGeneratorExpression ge(lfbt); + cmSystemTools::ExpandListArgument(ge.Parse(dirs) + ->Evaluate(mf, + config, false, headTarget, + depTgt, dagChecker), result); + } +} + //---------------------------------------------------------------------------- bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir, const char *config) const { + assert(this->GetType() != cmTarget::INTERFACE_LIBRARY); std::string config_upper; if(config && *config) { @@ -75,39 +118,81 @@ bool cmGeneratorTarget::IsSystemIncludeDirectory(const char *dir, if (iter == this->SystemIncludesCache.end()) { + cmTarget::LinkImplementation const* impl + = this->Target->GetLinkImplementation(config, this->Target); + if(!impl) + { + return false; + } + + cmListFileBacktrace lfbt; + cmGeneratorExpressionDAGChecker dagChecker(lfbt, + this->GetName(), + "SYSTEM_INCLUDE_DIRECTORIES", 0, 0); + std::vector<std::string> result; for (std::set<cmStdString>::const_iterator it = this->Target->GetSystemIncludeDirectories().begin(); it != this->Target->GetSystemIncludeDirectories().end(); ++it) { - cmListFileBacktrace lfbt; cmGeneratorExpression ge(lfbt); + cmSystemTools::ExpandListArgument(ge.Parse(*it) + ->Evaluate(this->Makefile, + config, false, this->Target, + &dagChecker), result); + } + + std::set<cmStdString> uniqueDeps; + for(std::vector<std::string>::const_iterator li = impl->Libraries.begin(); + li != impl->Libraries.end(); ++li) + { + if (uniqueDeps.insert(*li).second) + { + cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str()); - cmGeneratorExpressionDAGChecker dagChecker(lfbt, - this->GetName(), - "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", 0, 0); + if (!tgt) + { + continue; + } - cmSystemTools::ExpandListArgument(ge.Parse(*it) - ->Evaluate(this->Makefile, - config, false, this->Target, - &dagChecker), result); + handleSystemIncludesDep(this->Makefile, *li, config, this->Target, + &dagChecker, result); + + std::vector<std::string> deps; + tgt->GetTransitivePropertyLinkLibraries(config, this->Target, deps); + + for(std::vector<std::string>::const_iterator di = deps.begin(); + di != deps.end(); ++di) + { + if (uniqueDeps.insert(*di).second) + { + handleSystemIncludesDep(this->Makefile, *di, config, this->Target, + &dagChecker, result); + } + } + } } + std::set<cmStdString> unique; for(std::vector<std::string>::iterator li = result.begin(); li != result.end(); ++li) { cmSystemTools::ConvertToUnixSlashes(*li); + unique.insert(*li); + } + result.clear(); + for(std::set<cmStdString>::iterator li = unique.begin(); + li != unique.end(); ++li) + { + result.push_back(*li); } IncludeCacheType::value_type entry(config_upper, result); iter = this->SystemIncludesCache.insert(entry).first; } - if (std::find(iter->second.begin(), - iter->second.end(), dir) != iter->second.end()) - { - return true; - } - return false; + std::string dirString = dir; + return std::binary_search(iter->second.begin(), iter->second.end(), + dirString); } //---------------------------------------------------------------------------- diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx index faba7cd..a1454a3 100644 --- a/Source/cmGetPropertyCommand.cxx +++ b/Source/cmGetPropertyCommand.cxx @@ -298,7 +298,7 @@ bool cmGetPropertyCommand::HandleTargetMode() return this->StoreResult(target->GetName()); } } - return false; + return this->StoreResult((this->Variable + "-NOTFOUND").c_str()); } if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name.c_str())) { diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 780b072..82c9155 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -188,6 +188,13 @@ void cmGlobalGenerator::AddBuildExportSet(cmExportBuildFileGenerator* gen) this->BuildExportSets[gen->GetMainExportFileName()] = gen; } +void +cmGlobalGenerator::AddBuildExportExportSet(cmExportBuildFileGenerator* gen) +{ + this->BuildExportSets[gen->GetMainExportFileName()] = gen; + this->BuildExportExportSets[gen->GetMainExportFileName()] = gen; +} + bool cmGlobalGenerator::GenerateImportFile(const std::string &file) { std::map<std::string, cmExportBuildFileGenerator*>::iterator it @@ -208,7 +215,12 @@ cmGlobalGenerator::IsExportedTargetsFile(const std::string &filename) const { const std::map<std::string, cmExportBuildFileGenerator*>::const_iterator it = this->BuildExportSets.find(filename); - return it != this->BuildExportSets.end(); + if (it == this->BuildExportSets.end()) + { + return false; + } + return this->BuildExportExportSets.find(filename) + == this->BuildExportExportSets.end(); } // Find the make program for the generator, required for try compiles @@ -1165,17 +1177,6 @@ void cmGlobalGenerator::Generate() // it builds by default. this->FillLocalGeneratorToTargetMap(); - for (i = 0; i < this->LocalGenerators.size(); ++i) - { - cmMakefile* mf = this->LocalGenerators[i]->GetMakefile(); - cmTargets* targets = &(mf->GetTargets()); - for ( cmTargets::iterator it = targets->begin(); - it != targets->end(); ++ it ) - { - it->second.FinalizeSystemIncludeDirectories(); - } - } - // Generate project files for (i = 0; i < this->LocalGenerators.size(); ++i) { @@ -1338,13 +1339,13 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo() { cmTarget* t = &ti->second; + t->AppendBuildInterfaceIncludes(); + if (t->GetType() == cmTarget::INTERFACE_LIBRARY) { continue; } - t->AppendBuildInterfaceIncludes(); - for (std::vector<cmValueWithOrigin>::const_iterator it = noconfig_compile_definitions.begin(); it != noconfig_compile_definitions.end(); ++it) @@ -1909,7 +1910,8 @@ bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, bool cmGlobalGenerator::IsExcluded(cmLocalGenerator* root, cmTarget& target) { - if(target.GetPropertyAsBool("EXCLUDE_FROM_ALL")) + if(target.GetType() == cmTarget::INTERFACE_LIBRARY + || target.GetPropertyAsBool("EXCLUDE_FROM_ALL")) { // This target is excluded from its directory. return true; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 049b0e6..fc5cab9 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -311,6 +311,7 @@ public: std::map<std::string, cmExportBuildFileGenerator*>& GetBuildExportSets() {return this->BuildExportSets;} void AddBuildExportSet(cmExportBuildFileGenerator*); + void AddBuildExportExportSet(cmExportBuildFileGenerator*); bool IsExportedTargetsFile(const std::string &filename) const; bool GenerateImportFile(const std::string &file); cmExportBuildFileGenerator* @@ -375,6 +376,7 @@ protected: // Sets of named target exports cmExportSetMap ExportSets; std::map<std::string, cmExportBuildFileGenerator*> BuildExportSets; + std::map<std::string, cmExportBuildFileGenerator*> BuildExportExportSets; // Manifest of all targets that will be built for each configuration. // This is computed just before local generators generate. diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index b5a46d0..381c1f5 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -488,7 +488,8 @@ cmGlobalXCodeGenerator::AddExtraTargets(cmLocalGenerator* root, dir.c_str()); } - if(!target.GetPropertyAsBool("EXCLUDE_FROM_ALL")) + if(target.GetType() != cmTarget::INTERFACE_LIBRARY + && !target.GetPropertyAsBool("EXCLUDE_FROM_ALL")) { allbuild->AddUtility(target.GetName()); } diff --git a/Source/cmIncludeDirectoryCommand.cxx b/Source/cmIncludeDirectoryCommand.cxx index 30c1743..e20fe02 100644 --- a/Source/cmIncludeDirectoryCommand.cxx +++ b/Source/cmIncludeDirectoryCommand.cxx @@ -55,7 +55,7 @@ bool cmIncludeDirectoryCommand std::vector<std::string> includes; - GetIncludes(*i, includes); + this->GetIncludes(*i, includes); if (before) { diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 401ea5b..35b65b4 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -4045,8 +4045,8 @@ cmMakefile::AddImportedTarget(const char* name, cmTarget::TargetType type, // Create the target. cmsys::auto_ptr<cmTarget> target(new cmTarget); target->SetType(type, name); - target->SetMakefile(this); target->MarkAsImported(); + target->SetMakefile(this); // Add to the set of available imported targets. this->ImportedTargets[name] = target.get(); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 9faf0d9..b06480b 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -24,6 +24,7 @@ #include <set> #include <stdlib.h> // required for atof #include <assert.h> +#include <errno.h> const char* cmTarget::GetTargetTypeName(TargetType targetType) { @@ -136,7 +137,7 @@ public: std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries; std::vector<TargetPropertyEntry*> CompileOptionsEntries; std::vector<TargetPropertyEntry*> CompileDefinitionsEntries; - std::vector<cmValueWithOrigin> LinkInterfacePropertyEntries; + std::vector<cmValueWithOrigin> LinkImplementationPropertyEntries; mutable std::map<std::string, std::vector<TargetPropertyEntry*> > CachedLinkInterfaceIncludeDirectoriesEntries; @@ -330,34 +331,36 @@ void cmTarget::SetMakefile(cmMakefile* mf) // Save the backtrace of target construction. this->Makefile->GetBacktrace(this->Internal->Backtrace); - // Initialize the INCLUDE_DIRECTORIES property based on the current value - // of the same directory property: - const std::vector<cmValueWithOrigin> parentIncludes = - this->Makefile->GetIncludeDirectoriesEntries(); - - for (std::vector<cmValueWithOrigin>::const_iterator it - = parentIncludes.begin(); it != parentIncludes.end(); ++it) + if (!this->IsImported()) { - this->InsertInclude(*it); - } + // Initialize the INCLUDE_DIRECTORIES property based on the current value + // of the same directory property: + const std::vector<cmValueWithOrigin> parentIncludes = + this->Makefile->GetIncludeDirectoriesEntries(); - const std::set<cmStdString> parentSystemIncludes = - this->Makefile->GetSystemIncludeDirectories(); + for (std::vector<cmValueWithOrigin>::const_iterator it + = parentIncludes.begin(); it != parentIncludes.end(); ++it) + { + this->InsertInclude(*it); + } + const std::set<cmStdString> parentSystemIncludes = + this->Makefile->GetSystemIncludeDirectories(); - for (std::set<cmStdString>::const_iterator it - = parentSystemIncludes.begin(); - it != parentSystemIncludes.end(); ++it) - { - this->SystemIncludeDirectories.insert(*it); - } + for (std::set<cmStdString>::const_iterator it + = parentSystemIncludes.begin(); + it != parentSystemIncludes.end(); ++it) + { + this->SystemIncludeDirectories.insert(*it); + } - const std::vector<cmValueWithOrigin> parentOptions = - this->Makefile->GetCompileOptionsEntries(); + const std::vector<cmValueWithOrigin> parentOptions = + this->Makefile->GetCompileOptionsEntries(); - for (std::vector<cmValueWithOrigin>::const_iterator it - = parentOptions.begin(); it != parentOptions.end(); ++it) - { - this->InsertCompileOption(*it); + for (std::vector<cmValueWithOrigin>::const_iterator it + = parentOptions.begin(); it != parentOptions.end(); ++it) + { + this->InsertCompileOption(*it); + } } if (this->GetType() != INTERFACE_LIBRARY) @@ -1039,62 +1042,6 @@ cmTarget::AddSystemIncludeDirectories(const std::vector<std::string> &incs) } //---------------------------------------------------------------------------- -void cmTarget::FinalizeSystemIncludeDirectories() -{ - for (std::vector<cmValueWithOrigin>::const_iterator - it = this->Internal->LinkInterfacePropertyEntries.begin(), - end = this->Internal->LinkInterfacePropertyEntries.end(); - it != end; ++it) - { - if (!cmGeneratorExpression::IsValidTargetName(it->Value) - && cmGeneratorExpression::Find(it->Value) == std::string::npos) - { - continue; - } - { - cmListFileBacktrace lfbt; - cmGeneratorExpression ge(lfbt); - cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = - ge.Parse(it->Value); - std::string targetName = cge->Evaluate(this->Makefile, 0, - false, this, 0, 0); - cmTarget *tgt = this->Makefile->FindTargetToUse(targetName.c_str()); - if (!tgt || tgt == this) - { - continue; - } - if (tgt->IsImported() - && tgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES") - && !this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED")) - { - std::string includeGenex = "$<TARGET_PROPERTY:" + - it->Value + ",INTERFACE_INCLUDE_DIRECTORIES>"; - if (cmGeneratorExpression::Find(it->Value) != std::string::npos) - { - // Because it->Value is a generator expression, ensure that it - // evaluates to the non-empty string before being used in the - // TARGET_PROPERTY expression. - includeGenex = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">"; - } - this->SystemIncludeDirectories.insert(includeGenex); - return; // The INTERFACE_SYSTEM_INCLUDE_DIRECTORIES are a subset - // of the INTERFACE_INCLUDE_DIRECTORIES - } - } - std::string includeGenex = "$<TARGET_PROPERTY:" + - it->Value + ",INTERFACE_SYSTEM_INCLUDE_DIRECTORIES>"; - if (cmGeneratorExpression::Find(it->Value) != std::string::npos) - { - // Because it->Value is a generator expression, ensure that it - // evaluates to the non-empty string before being used in the - // TARGET_PROPERTY expression. - includeGenex = "$<$<BOOL:" + it->Value + ">:" + includeGenex + ">"; - } - this->SystemIncludeDirectories.insert(includeGenex); - } -} - -//---------------------------------------------------------------------------- void cmTarget::AnalyzeLibDependencies( const cmMakefile& mf ) { @@ -1400,14 +1347,10 @@ static bool whiteListedInterfaceProperty(const char *prop) "COMPATIBLE_INTERFACE_NUMBER_MAX", "COMPATIBLE_INTERFACE_NUMBER_MIN", "COMPATIBLE_INTERFACE_STRING", - "EXCLUDE_FROM_ALL", - "EXCLUDE_FROM_DEFAULT_BUILD", "EXPORT_NAME", - "IMPORTED_LINK_INTERFACE_LANGUAGES", "IMPORTED", "NAME", - "TYPE", - "VERSION" + "TYPE" }; if (std::binary_search(cmArrayBegin(builtIns), @@ -1418,9 +1361,7 @@ static bool whiteListedInterfaceProperty(const char *prop) return true; } - if (cmHasLiteralPrefix(prop, "EXCLUDE_FROM_DEFAULT_BUILD_") - || cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LANGUAGES_") - || cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) + if (cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_")) { return true; } @@ -1495,11 +1436,11 @@ void cmTarget::SetProperty(const char* prop, const char* value) } if (strcmp(prop, "LINK_LIBRARIES") == 0) { - this->Internal->LinkInterfacePropertyEntries.clear(); + this->Internal->LinkImplementationPropertyEntries.clear(); cmListFileBacktrace lfbt; this->Makefile->GetBacktrace(lfbt); cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfacePropertyEntries.push_back(entry); + this->Internal->LinkImplementationPropertyEntries.push_back(entry); return; } this->Properties.SetProperty(prop, value, cmProperty::TARGET); @@ -1570,7 +1511,7 @@ void cmTarget::AppendProperty(const char* prop, const char* value, cmListFileBacktrace lfbt; this->Makefile->GetBacktrace(lfbt); cmValueWithOrigin entry(value, lfbt); - this->Internal->LinkInterfacePropertyEntries.push_back(entry); + this->Internal->LinkImplementationPropertyEntries.push_back(entry); return; } this->Properties.AppendProperty(prop, value, cmProperty::TARGET, asString); @@ -1603,6 +1544,7 @@ void cmTarget::AppendBuildInterfaceIncludes() if(this->GetType() != cmTarget::SHARED_LIBRARY && this->GetType() != cmTarget::STATIC_LIBRARY && this->GetType() != cmTarget::MODULE_LIBRARY && + this->GetType() != cmTarget::INTERFACE_LIBRARY && !this->IsExecutableWithExports()) { return; @@ -1882,8 +1824,8 @@ cmTarget::GetIncludeDirectories(const char *config) const if (!this->Internal->CacheLinkInterfaceIncludeDirectoriesDone[configString]) { for (std::vector<cmValueWithOrigin>::const_iterator - it = this->Internal->LinkInterfacePropertyEntries.begin(), - end = this->Internal->LinkInterfacePropertyEntries.end(); + it = this->Internal->LinkImplementationPropertyEntries.begin(), + end = this->Internal->LinkImplementationPropertyEntries.end(); it != end; ++it) { if (!cmGeneratorExpression::IsValidTargetName(it->Value) @@ -2111,8 +2053,8 @@ void cmTarget::GetCompileOptions(std::vector<std::string> &result, if (!this->Internal->CacheLinkInterfaceCompileOptionsDone[configString]) { for (std::vector<cmValueWithOrigin>::const_iterator - it = this->Internal->LinkInterfacePropertyEntries.begin(), - end = this->Internal->LinkInterfacePropertyEntries.end(); + it = this->Internal->LinkImplementationPropertyEntries.begin(), + end = this->Internal->LinkImplementationPropertyEntries.end(); it != end; ++it) { if (!cmGeneratorExpression::IsValidTargetName(it->Value) @@ -2224,8 +2166,8 @@ void cmTarget::GetCompileDefinitions(std::vector<std::string> &list, if (!this->Internal->CacheLinkInterfaceCompileDefinitionsDone[configString]) { for (std::vector<cmValueWithOrigin>::const_iterator - it = this->Internal->LinkInterfacePropertyEntries.begin(), - end = this->Internal->LinkInterfacePropertyEntries.end(); + it = this->Internal->LinkImplementationPropertyEntries.begin(), + end = this->Internal->LinkImplementationPropertyEntries.end(); it != end; ++it) { if (!cmGeneratorExpression::IsValidTargetName(it->Value) @@ -2572,6 +2514,8 @@ void cmTarget::GetTargetVersion(bool soversion, minor = 0; patch = 0; + assert(this->GetType() != INTERFACE_LIBRARY); + // Look for a VERSION or SOVERSION property. const char* prop = soversion? "SOVERSION" : "VERSION"; if(const char* version = this->GetProperty(prop)) @@ -2685,7 +2629,6 @@ const char *cmTarget::GetProperty(const char* prop, this->GetType() == cmTarget::STATIC_LIBRARY || this->GetType() == cmTarget::SHARED_LIBRARY || this->GetType() == cmTarget::MODULE_LIBRARY || - this->GetType() == cmTarget::INTERFACE_LIBRARY || this->GetType() == cmTarget::UNKNOWN_LIBRARY) { if(strcmp(prop,"LOCATION") == 0) @@ -2720,25 +2663,6 @@ const char *cmTarget::GetProperty(const char* prop, this->GetLocation(configName.c_str()), cmProperty::TARGET); } - else - { - // Support "<CONFIG>_LOCATION" for compatibility. - int len = static_cast<int>(strlen(prop)); - if(len > 9 && strcmp(prop+len-9, "_LOCATION") == 0) - { - std::string configName(prop, len-9); - if(configName != "IMPORTED") - { - if (!this->HandleLocationPropertyPolicy()) - { - return 0; - } - this->Properties.SetProperty(prop, - this->GetLocation(configName.c_str()), - cmProperty::TARGET); - } - } - } } if(strcmp(prop,"INCLUDE_DIRECTORIES") == 0) { @@ -2800,8 +2724,8 @@ const char *cmTarget::GetProperty(const char* prop, output = ""; std::string sep; for (std::vector<cmValueWithOrigin>::const_iterator - it = this->Internal->LinkInterfacePropertyEntries.begin(), - end = this->Internal->LinkInterfacePropertyEntries.end(); + it = this->Internal->LinkImplementationPropertyEntries.begin(), + end = this->Internal->LinkImplementationPropertyEntries.end(); it != end; ++it) { output += sep; @@ -3604,6 +3528,8 @@ void cmTarget::GetLibraryNames(std::string& name, return; } + assert(this->GetType() != INTERFACE_LIBRARY); + // Check for library version properties. const char* version = this->GetProperty("VERSION"); const char* soversion = this->GetProperty("SOVERSION"); @@ -4179,6 +4105,8 @@ std::string cmTarget::GetOutputName(const char* config, bool implib) const //---------------------------------------------------------------------------- std::string cmTarget::GetFrameworkVersion() const { + assert(this->GetType() != INTERFACE_LIBRARY); + if(const char* fversion = this->GetProperty("FRAMEWORK_VERSION")) { return fversion; @@ -4257,20 +4185,23 @@ enum CompatibleType //---------------------------------------------------------------------------- template<typename PropertyType> -PropertyType consistentProperty(PropertyType lhs, PropertyType rhs, - CompatibleType t); +std::pair<bool, PropertyType> consistentProperty(PropertyType lhs, + PropertyType rhs, + CompatibleType t); //---------------------------------------------------------------------------- template<> -bool consistentProperty(bool lhs, bool rhs, CompatibleType) +std::pair<bool, bool> consistentProperty(bool lhs, bool rhs, CompatibleType) { - return lhs == rhs; + return std::make_pair(lhs == rhs, lhs); } //---------------------------------------------------------------------------- -const char * consistentStringProperty(const char *lhs, const char *rhs) +std::pair<bool, const char*> consistentStringProperty(const char *lhs, + const char *rhs) { - return strcmp(lhs, rhs) == 0 ? lhs : 0; + const bool b = strcmp(lhs, rhs) == 0; + return std::make_pair(b, b ? lhs : 0); } #if defined(_MSC_VER) && _MSC_VER <= 1200 @@ -4284,49 +4215,74 @@ cmMinimum(const T& l, const T& r) {return l < r ? l : r;} #endif //---------------------------------------------------------------------------- -const char * consistentNumberProperty(const char *lhs, const char *rhs, - CompatibleType t) +std::pair<bool, const char*> consistentNumberProperty(const char *lhs, + const char *rhs, + CompatibleType t) { - double lnum; - double rnum; - if(sscanf(lhs, "%lg", &lnum) != 1 || - sscanf(rhs, "%lg", &rnum) != 1) + char *pEnd; + +#if defined(_MSC_VER) + static const char* const null_ptr = 0; +#else +# define null_ptr 0 +#endif + + long lnum = strtol(lhs, &pEnd, 0); + if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) { - return 0; + return std::pair<bool, const char*>(false, null_ptr); + } + + long rnum = strtol(rhs, &pEnd, 0); + if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) + { + return std::pair<bool, const char*>(false, null_ptr); } +#if !defined(_MSC_VER) +#undef null_ptr +#endif + if (t == NumberMaxType) { - return cmMaximum(lnum, rnum) == lnum ? lhs : rhs; + return std::make_pair(true, cmMaximum(lnum, rnum) == lnum ? lhs : rhs); } else { - return cmMinimum(lnum, rnum) == lnum ? lhs : rhs; + return std::make_pair(true, cmMinimum(lnum, rnum) == lnum ? lhs : rhs); } } //---------------------------------------------------------------------------- template<> -const char* consistentProperty(const char *lhs, const char *rhs, - CompatibleType t) +std::pair<bool, const char*> consistentProperty(const char *lhs, + const char *rhs, + CompatibleType t) { if (!lhs && !rhs) { - return ""; + return std::make_pair(true, lhs); } if (!lhs) { - return rhs ? rhs : ""; + return std::make_pair(true, rhs); } if (!rhs) { - return lhs ? lhs : ""; + return std::make_pair(true, lhs); } + +#if defined(_MSC_VER) + static const char* const null_ptr = 0; +#else +# define null_ptr 0 +#endif + switch(t) { case BoolType: assert(!"consistentProperty for strings called with BoolType"); - return 0; + return std::pair<bool, const char*>(false, null_ptr); case StringType: return consistentStringProperty(lhs, rhs); case NumberMinType: @@ -4334,7 +4290,12 @@ const char* consistentProperty(const char *lhs, const char *rhs, return consistentNumberProperty(lhs, rhs, t); } assert(!"Unreachable!"); - return 0; + return std::pair<bool, const char*>(false, null_ptr); + +#if !defined(_MSC_VER) +#undef null_ptr +#endif + } template<typename PropertyType> @@ -4506,7 +4467,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, ("INTERFACE_" + p).c_str(), 0); std::string reportEntry; - if (ifacePropContent) + if (ifaceIsSet) { reportEntry += " * Target \""; reportEntry += li->Target->GetName(); @@ -4519,11 +4480,12 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, { if (ifaceIsSet) { - PropertyType consistent = consistentProperty(propContent, + std::pair<bool, PropertyType> consistent = + consistentProperty(propContent, ifacePropContent, t); report += reportEntry; - report += compatibilityAgree(t, propContent != consistent); - if (!consistent) + report += compatibilityAgree(t, propContent != consistent.second); + if (!consistent.first) { cmOStringStream e; e << "Property " << p << " on target \"" @@ -4535,7 +4497,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, } else { - propContent = consistent; + propContent = consistent.second; continue; } } @@ -4549,19 +4511,14 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, { propContent = impliedValue<PropertyType>(propContent); - reportEntry += " * Target \""; - reportEntry += li->Target->GetName(); - reportEntry += "\" property value \""; - reportEntry += valueAsString<PropertyType>(propContent); - reportEntry += "\" "; - if (ifaceIsSet) { - PropertyType consistent = consistentProperty(propContent, + std::pair<bool, PropertyType> consistent = + consistentProperty(propContent, ifacePropContent, t); report += reportEntry; - report += compatibilityAgree(t, propContent != consistent); - if (!consistent) + report += compatibilityAgree(t, propContent != consistent.second); + if (!consistent.first) { cmOStringStream e; e << "Property " << p << " on target \"" @@ -4574,7 +4531,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, } else { - propContent = consistent; + propContent = consistent.second; continue; } } @@ -4590,11 +4547,12 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, { if (propInitialized) { - PropertyType consistent = consistentProperty(propContent, + std::pair<bool, PropertyType> consistent = + consistentProperty(propContent, ifacePropContent, t); report += reportEntry; - report += compatibilityAgree(t, propContent != consistent); - if (!consistent) + report += compatibilityAgree(t, propContent != consistent.second); + if (!consistent.first) { cmOStringStream e; e << "The INTERFACE_" << p << " property of \"" @@ -4606,7 +4564,7 @@ PropertyType checkInterfacePropertyCompatibility(cmTarget const* tgt, } else { - propContent = consistent; + propContent = consistent.second; continue; } } @@ -5578,9 +5536,6 @@ void cmTarget::ComputeLinkImplementation(const char* config, LinkImplementation& impl, cmTarget const* head) const { - // Compute which library configuration to link. - cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); - // Collect libraries directly linked in this configuration. std::vector<std::string> llibs; this->GetDirectLinkLibraries(config, llibs, head); @@ -5673,6 +5628,7 @@ void cmTarget::ComputeLinkImplementation(const char* config, impl.Libraries.push_back(item); } + cmTarget::LinkLibraryType linkType = this->ComputeLinkType(config); LinkLibraryVectorType const& oldllibs = this->GetOriginalLinkLibraries(); for(cmTarget::LinkLibraryVectorType::const_iterator li = oldllibs.begin(); li != oldllibs.end(); ++li) @@ -6003,7 +5959,8 @@ void cmTarget::CheckPropertyCompatibility(cmComputeLinkInformation *info, << propsString << " property in the dependencies of target \"" << this->GetName() << "\". This is not allowed. A property may only require compatibility " - "in a boolean interpretation or a string interpretation, but not both."; + "in a boolean interpretation, a numeric minimum, a numeric maximum or a " + "string interpretation, but not a mixture."; this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str()); } } diff --git a/Source/cmTarget.h b/Source/cmTarget.h index e026c59..4916648 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -568,8 +568,6 @@ public: std::set<cmStdString> const & GetSystemIncludeDirectories() const { return this->SystemIncludeDirectories; } - void FinalizeSystemIncludeDirectories(); - bool LinkLanguagePropagatesToDependents() const { return this->TargetTypeValue == STATIC_LIBRARY; } diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx index 882b072..fcaa127 100644 --- a/Source/cmakemain.cxx +++ b/Source/cmakemain.cxx @@ -24,6 +24,7 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include <cmsys/Encoding.hxx> #ifdef CMAKE_BUILD_WITH_CMAKE //---------------------------------------------------------------------------- @@ -79,7 +80,7 @@ static const char * cmDocumentationOptions[][2] = #endif -static int do_command(int ac, char** av) +static int do_command(int ac, char const* const* av) { std::vector<std::string> args; args.push_back(av[0]); @@ -90,8 +91,8 @@ static int do_command(int ac, char** av) return cmcmd::ExecuteCMakeCommand(args); } -int do_cmake(int ac, char** av); -static int do_build(int ac, char** av); +int do_cmake(int ac, char const* const* av); +static int do_build(int ac, char const* const* av); static cmMakefile* cmakemainGetMakefile(void *clientdata) { @@ -159,8 +160,13 @@ static void cmakemainProgressCallback(const char *m, float prog, } -int main(int ac, char** av) +int main(int ac, char const* const* av) { + cmsys::Encoding::CommandLineArguments args = + cmsys::Encoding::CommandLineArguments::Main(ac, av); + ac = args.argc(); + av = args.argv(); + cmSystemTools::EnableMSVCDebugHook(); cmSystemTools::FindCMakeResources(av[0]); if(ac > 1) @@ -181,7 +187,7 @@ int main(int ac, char** av) return ret; } -int do_cmake(int ac, char** av) +int do_cmake(int ac, char const* const* av) { if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 ) { @@ -352,7 +358,7 @@ int do_cmake(int ac, char** av) } //---------------------------------------------------------------------------- -static int do_build(int ac, char** av) +static int do_build(int ac, char const* const* av) { #ifndef CMAKE_BUILD_WITH_CMAKE std::cerr << "This cmake does not support --build\n"; diff --git a/Source/ctest.cxx b/Source/ctest.cxx index de07458..3eb5551 100644 --- a/Source/ctest.cxx +++ b/Source/ctest.cxx @@ -18,6 +18,7 @@ #include "CTest/cmCTestScriptHandler.h" #include "CTest/cmCTestLaunch.h" +#include "cmsys/Encoding.hxx" //---------------------------------------------------------------------------- static const char * cmDocumentationName[][2] = @@ -111,8 +112,13 @@ static const char * cmDocumentationOptions[][2] = }; // this is a test driver program for cmCTest. -int main (int argc, char *argv[]) +int main (int argc, char const* const* argv) { + cmsys::Encoding::CommandLineArguments encoding_args = + cmsys::Encoding::CommandLineArguments::Main(argc, argv); + argc = encoding_args.argc(); + argv = encoding_args.argv(); + cmSystemTools::DoNotInheritStdPipes(); cmSystemTools::EnableMSVCDebugHook(); cmSystemTools::FindCMakeResources(argv[0]); diff --git a/Source/kwsys/Terminal.c b/Source/kwsys/Terminal.c index 25832c2..6d7ec41 100644 --- a/Source/kwsys/Terminal.c +++ b/Source/kwsys/Terminal.c @@ -155,6 +155,7 @@ static const char* kwsysTerminalVT100Names[] = "mach-color", "mlterm", "putty", + "putty-256color", "rxvt", "rxvt-256color", "rxvt-cygwin", diff --git a/Tests/AliasTarget/CMakeLists.txt b/Tests/AliasTarget/CMakeLists.txt index fdb1638..9467fae 100644 --- a/Tests/AliasTarget/CMakeLists.txt +++ b/Tests/AliasTarget/CMakeLists.txt @@ -48,3 +48,25 @@ endif() add_library(iface INTERFACE) add_library(Alias::Iface ALIAS iface) + +get_target_property(_notAlias1 foo ALIASED_TARGET) +if (NOT DEFINED _notAlias1) + message(SEND_ERROR "_notAlias1 is not defined") +endif() +if (_notAlias1) + message(SEND_ERROR "_notAlias1 is defined, but foo is not an ALIAS") +endif() +if (NOT _notAlias1 STREQUAL _notAlias1-NOTFOUND) + message(SEND_ERROR "_notAlias1 not defined to a -NOTFOUND variant") +endif() + +get_property(_notAlias2 TARGET foo PROPERTY ALIASED_TARGET) +if (NOT DEFINED _notAlias2) + message(SEND_ERROR "_notAlias2 is not defined") +endif() +if (_notAlias2) + message(SEND_ERROR "_notAlias2 is defined, but foo is not an ALIAS") +endif() +if (NOT _notAlias2 STREQUAL _notAlias2-NOTFOUND) + message(SEND_ERROR "_notAlias2 not defined to a -NOTFOUND variant") +endif() diff --git a/Tests/CMakeCommands/add_compile_options/CMakeLists.txt b/Tests/CMakeCommands/add_compile_options/CMakeLists.txt index 1652cf6..995b32c 100644 --- a/Tests/CMakeCommands/add_compile_options/CMakeLists.txt +++ b/Tests/CMakeCommands/add_compile_options/CMakeLists.txt @@ -12,3 +12,10 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") "DO_GNU_TESTS" ) endif() + +add_compile_options(-rtti) +add_library(imp UNKNOWN IMPORTED) +get_target_property(_res imp COMPILE_OPTIONS) +if (_res) + message(SEND_ERROR "add_compile_options populated the COMPILE_OPTIONS target property") +endif() diff --git a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt index 900dbd0..14d40aa 100644 --- a/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt +++ b/Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt @@ -25,3 +25,10 @@ target_compile_definitions(consumer target_compile_definitions(consumer PRIVATE ) + +add_definitions(-DSOME_DEF) +add_library(imp UNKNOWN IMPORTED) +get_target_property(_res imp COMPILE_DEFINITIONS) +if (_res) + message(SEND_ERROR "add_definitions populated the COMPILE_DEFINITIONS target property") +endif() diff --git a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt index 8a564c7..661bbaa 100644 --- a/Tests/CMakeCommands/target_include_directories/CMakeLists.txt +++ b/Tests/CMakeCommands/target_include_directories/CMakeLists.txt @@ -62,3 +62,10 @@ target_include_directories(consumer target_include_directories(consumer SYSTEM PRIVATE ) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) +add_library(imp UNKNOWN IMPORTED) +get_target_property(_res imp INCLUDE_DIRECTORIES) +if (_res) + message(SEND_ERROR "include_directories populated the INCLUDE_DIRECTORIES target property") +endif() diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 063bd2d..78dddd3 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -2168,6 +2168,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --output-log "${CMake_BINARY_DIR}/Tests/CTestConfig/ScriptWithArgs.log" ) + ADD_TEST_MACRO(CMakeCommands.add_compile_options add_compile_options) ADD_TEST_MACRO(CMakeCommands.target_link_libraries target_link_libraries) ADD_TEST_MACRO(CMakeCommands.target_include_directories target_include_directories) ADD_TEST_MACRO(CMakeCommands.target_compile_definitions target_compile_definitions) diff --git a/Tests/CTestTest/test.cmake.in b/Tests/CTestTest/test.cmake.in index 214bff8..ab39b88 100644 --- a/Tests/CTestTest/test.cmake.in +++ b/Tests/CTestTest/test.cmake.in @@ -6,7 +6,7 @@ # this is the cvs module name that should be checked out set (CTEST_MODULE_NAME SmallAndFast) -# these are the the name of the source and binary directory on disk. +# these are the name of the source and binary directory on disk. # They will be appended to DASHBOARD_ROOT set (CTEST_SOURCE_NAME SmallAndFast) set (CTEST_BINARY_NAME SmallAndFastBuild) diff --git a/Tests/CompatibleInterface/CMakeLists.txt b/Tests/CompatibleInterface/CMakeLists.txt index 5e64d2a..350b518 100644 --- a/Tests/CompatibleInterface/CMakeLists.txt +++ b/Tests/CompatibleInterface/CMakeLists.txt @@ -24,6 +24,8 @@ set_property(TARGET iface1 APPEND PROPERTY COMPATIBLE_INTERFACE_NUMBER_MIN NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 + NUMBER_MIN_PROP3 + NUMBER_MIN_PROP4 ) set_property(TARGET iface1 APPEND PROPERTY COMPATIBLE_INTERFACE_NUMBER_MAX @@ -34,7 +36,7 @@ set_property(TARGET iface1 APPEND PROPERTY set(CMAKE_DEBUG_TARGET_PROPERTIES BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 STRING_PROP1 STRING_PROP2 STRING_PROP3 - NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 + NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 NUMBER_MIN_PROP3 NUMBER_MIN_PROP4 NUMBER_MAX_PROP1 NUMBER_MAX_PROP2 ) @@ -44,6 +46,8 @@ set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1) set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2) set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP1 100) set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP2 200) +set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP3 0x10) +set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP4 0x10) set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP1 100) set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200) @@ -56,6 +60,8 @@ set_property(TARGET CompatibleInterface PROPERTY STRING_PROP2 prop2) set_property(TARGET CompatibleInterface PROPERTY STRING_PROP3 prop3) set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP1 50) set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP2 250) +set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP3 0xa) +set_property(TARGET CompatibleInterface PROPERTY NUMBER_MIN_PROP4 0x1A) set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP1 50) set_property(TARGET CompatibleInterface PROPERTY NUMBER_MAX_PROP2 250) @@ -69,6 +75,8 @@ target_compile_definitions(CompatibleInterface $<$<STREQUAL:$<TARGET_PROPERTY:STRING_PROP3>,prop3>:STRING_PROP3> $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP1>,50>:NUMBER_MIN_PROP1=50> $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP2>,200>:NUMBER_MIN_PROP2=200> + $<$<EQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP3>,0xA>:NUMBER_MIN_PROP3=0xA> + $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MIN_PROP4>,0x10>:NUMBER_MIN_PROP4=0x10> $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP1>,100>:NUMBER_MAX_PROP1=100> $<$<STREQUAL:$<TARGET_PROPERTY:NUMBER_MAX_PROP2>,250>:NUMBER_MAX_PROP2=250> ) diff --git a/Tests/CompatibleInterface/main.cpp b/Tests/CompatibleInterface/main.cpp index fa299e9..e23625a 100644 --- a/Tests/CompatibleInterface/main.cpp +++ b/Tests/CompatibleInterface/main.cpp @@ -33,7 +33,9 @@ enum { NumericMaxTest1 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP1 == 100>), NumericMaxTest2 = sizeof(CMakeStaticAssert<NUMBER_MAX_PROP2 == 250>), NumericMinTest1 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP1 == 50>), - NumericMinTest2 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP2 == 200>) + NumericMinTest2 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP2 == 200>), + NumericMinTest3 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP3 == 0xA>), + NumericMinTest4 = sizeof(CMakeStaticAssert<NUMBER_MIN_PROP4 == 0x10>) }; #include "iface2.h" diff --git a/Tests/ExportImport/Export/Interface/CMakeLists.txt b/Tests/ExportImport/Export/Interface/CMakeLists.txt index f400f13..9d4793d 100644 --- a/Tests/ExportImport/Export/Interface/CMakeLists.txt +++ b/Tests/ExportImport/Export/Interface/CMakeLists.txt @@ -23,7 +23,10 @@ set_property(TARGET sharedlib PROPERTY INTERFACE_COMPILE_DEFINITIONS "SHAREDLIB_ add_library(sharediface INTERFACE) target_link_libraries(sharediface INTERFACE sharedlib) -install(TARGETS headeronly sharediface sharedlib +install(TARGETS headeronly sharediface + EXPORT expInterface +) +install(TARGETS sharedlib EXPORT expInterface RUNTIME DESTINATION bin LIBRARY DESTINATION lib NAMELINK_SKIP diff --git a/Tests/GeneratorExpression/CMakeLists.txt b/Tests/GeneratorExpression/CMakeLists.txt index 892f80f..4fb7ecd 100644 --- a/Tests/GeneratorExpression/CMakeLists.txt +++ b/Tests/GeneratorExpression/CMakeLists.txt @@ -196,6 +196,27 @@ add_custom_target(check-part3 ALL -Dlower_case=$<LOWER_CASE:Mi,XeD> -Dupper_case=$<UPPER_CASE:MiX,eD> -Dmake_c_identifier=$<MAKE_C_IDENTIFIER:4f,oo:+bar-$> + -Dequal1=$<EQUAL:1,2> + -Dequal2=$<EQUAL:1,1> + -Dequal3=$<EQUAL:0x1,1> + -Dequal4=$<EQUAL:0x1,2> + -Dequal5=$<EQUAL:0xA,0xa> + -Dequal6=$<EQUAL:0xA,10> + -Dequal7=$<EQUAL:0xA,012> + -Dequal8=$<EQUAL:10,012> + -Dequal9=$<EQUAL:10,010> + -Dequal10=$<EQUAL:10,0b1010> + -Dequal11=$<EQUAL:-10,-0xa> + -Dequal12=$<EQUAL:10,+0xa> + -Dequal13=$<EQUAL:+10,+0xa> + -Dequal14=$<EQUAL:+10,0xa> + -Dequal15=$<EQUAL:-10,-0xa> + -Dequal16=$<EQUAL:-10,-0b1010> + -Dequal17=$<EQUAL:-10,+0b1010> + -Dequal18=$<EQUAL:10,+0b1010> + -Dequal19=$<EQUAL:10,+012> + -Dequal20=$<EQUAL:10,-012> + -Dequal21=$<EQUAL:-10,-012> -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)" VERBATIM diff --git a/Tests/GeneratorExpression/check-part3.cmake b/Tests/GeneratorExpression/check-part3.cmake index 3361eeb..2c6bf49 100644 --- a/Tests/GeneratorExpression/check-part3.cmake +++ b/Tests/GeneratorExpression/check-part3.cmake @@ -37,3 +37,24 @@ endforeach() check(lower_case "mi,xed") check(upper_case "MIX,ED") check(make_c_identifier "_4f_oo__bar__") +check(equal1 "0") +check(equal2 "1") +check(equal3 "1") +check(equal4 "0") +check(equal5 "1") +check(equal6 "1") +check(equal7 "1") +check(equal8 "1") +check(equal9 "0") +check(equal10 "1") +check(equal11 "1") +check(equal12 "1") +check(equal13 "1") +check(equal14 "1") +check(equal15 "1") +check(equal16 "1") +check(equal17 "0") +check(equal18 "1") +check(equal19 "1") +check(equal20 "0") +check(equal21 "1") diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt index 1f5c93b..abe9f74 100644 --- a/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/CMakeLists.txt @@ -25,6 +25,10 @@ add_library(imported_consumer imported_consumer.cpp) target_link_libraries(imported_consumer iface) target_compile_options(imported_consumer PRIVATE -Werror=unused-variable) +add_library(imported_consumer2 imported_consumer.cpp) +target_link_libraries(imported_consumer2 imported_consumer) +target_compile_options(imported_consumer2 PRIVATE -Werror=unused-variable) + macro(do_try_compile error_option) set(TC_ARGS IFACE_TRY_COMPILE_${error_option} diff --git a/Tests/InterfaceLibrary/CMakeLists.txt b/Tests/InterfaceLibrary/CMakeLists.txt index 8154ced..b396eb6 100644 --- a/Tests/InterfaceLibrary/CMakeLists.txt +++ b/Tests/InterfaceLibrary/CMakeLists.txt @@ -6,13 +6,15 @@ project(InterfaceLibrary) add_library(iface_nodepends INTERFACE) target_compile_definitions(iface_nodepends INTERFACE IFACE_DEFINE) +add_subdirectory(headerdir) + add_executable(InterfaceLibrary definetestexe.cpp) -target_link_libraries(InterfaceLibrary iface_nodepends) +target_link_libraries(InterfaceLibrary iface_nodepends headeriface) add_subdirectory(libsdir) add_executable(sharedlibtestexe sharedlibtestexe.cpp) -target_link_libraries(sharedlibtestexe shared_iface) +target_link_libraries(sharedlibtestexe shared_iface imported::iface) add_library(broken EXCLUDE_FROM_ALL broken.cpp) diff --git a/Tests/InterfaceLibrary/definetestexe.cpp b/Tests/InterfaceLibrary/definetestexe.cpp index decd37c..e7a10c1 100644 --- a/Tests/InterfaceLibrary/definetestexe.cpp +++ b/Tests/InterfaceLibrary/definetestexe.cpp @@ -3,6 +3,18 @@ #error Expected IFACE_DEFINE #endif +#include "iface_header.h" + +#ifndef IFACE_HEADER_SRCDIR +#error Expected IFACE_HEADER_SRCDIR +#endif + +#include "iface_header_builddir.h" + +#ifndef IFACE_HEADER_BUILDDIR +#error Expected IFACE_HEADER_BUILDDIR +#endif + int main(int,char**) { return 0; diff --git a/Tests/InterfaceLibrary/headerdir/CMakeLists.txt b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt new file mode 100644 index 0000000..98f521e --- /dev/null +++ b/Tests/InterfaceLibrary/headerdir/CMakeLists.txt @@ -0,0 +1,8 @@ + +set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON) + +add_library(headeriface INTERFACE) + +file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/iface_header_builddir.h" + "#define IFACE_HEADER_BUILDDIR\n" +) diff --git a/Tests/InterfaceLibrary/headerdir/iface_header.h b/Tests/InterfaceLibrary/headerdir/iface_header.h new file mode 100644 index 0000000..82dd157 --- /dev/null +++ b/Tests/InterfaceLibrary/headerdir/iface_header.h @@ -0,0 +1 @@ +#define IFACE_HEADER_SRCDIR diff --git a/Tests/InterfaceLibrary/libsdir/CMakeLists.txt b/Tests/InterfaceLibrary/libsdir/CMakeLists.txt index 6999646..4e529df 100644 --- a/Tests/InterfaceLibrary/libsdir/CMakeLists.txt +++ b/Tests/InterfaceLibrary/libsdir/CMakeLists.txt @@ -24,3 +24,5 @@ target_compile_definitions(shareddependlib add_library(shared_iface INTERFACE) target_link_libraries(shared_iface INTERFACE sharedlib) + +add_library(imported::iface INTERFACE IMPORTED GLOBAL) diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 9dd5289..7b99395 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -47,7 +47,6 @@ add_custom_target(generate_moc_input COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/myinterface.h.in" "${CMAKE_CURRENT_BINARY_DIR}" COMMAND ${CMAKE_COMMAND} -E rename "${CMAKE_CURRENT_BINARY_DIR}/myinterface.h.in" "${CMAKE_CURRENT_BINARY_DIR}/myinterface.h" ) -# set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/myinterface.h" PROPERTIES GENERATED TRUE) add_executable(QtAutogen main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp xyz.cpp yaf.cpp gadget.cpp $<TARGET_OBJECTS:privateSlot> diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt index 0044564..e3efe28 100644 --- a/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt +++ b/Tests/RunCMake/CompatibleInterface/DebugProperties-stderr.txt @@ -25,6 +25,28 @@ CMake Debug Log: \* Target "CompatibleInterface" property not set. + CMake Debug Log: + Boolean compatibility of property "BOOL_PROP5" for target + "CompatibleInterface" \(result: "FALSE"\): + + \* Target "CompatibleInterface" property not set. + \* Target "iface1" property value "FALSE" \(Interface set\) ++ +CMake Debug Log: + Boolean compatibility of property "BOOL_PROP6" for target + "CompatibleInterface" \(result: "FALSE"\): + + \* Target "CompatibleInterface" property not set. + \* Target "iface1" property value "FALSE" \(Interface set\) + \* Target "iface2" property value "FALSE" \(Agree\) ++ +CMake Debug Log: + Boolean compatibility of property "BOOL_PROP7" for target + "CompatibleInterface" \(result: "FALSE"\): + + \* Target "CompatibleInterface" property is implied by use. + \* Target "iface1" property value "FALSE" \(Agree\) ++ +CMake Debug Log: String compatibility of property "STRING_PROP1" for target "CompatibleInterface" \(result: "prop1"\): diff --git a/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake b/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake index 3214d8e..42a3af2 100644 --- a/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake +++ b/Tests/RunCMake/CompatibleInterface/DebugProperties.cmake @@ -13,6 +13,9 @@ set_property(TARGET iface1 APPEND PROPERTY BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 + BOOL_PROP5 + BOOL_PROP6 + BOOL_PROP7 ) set_property(TARGET iface1 APPEND PROPERTY COMPATIBLE_INTERFACE_STRING @@ -32,7 +35,7 @@ set_property(TARGET iface1 APPEND PROPERTY ) set(CMAKE_DEBUG_TARGET_PROPERTIES - BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 + BOOL_PROP1 BOOL_PROP2 BOOL_PROP3 BOOL_PROP4 BOOL_PROP5 BOOL_PROP6 BOOL_PROP7 STRING_PROP1 STRING_PROP2 STRING_PROP3 NUMBER_MIN_PROP1 NUMBER_MIN_PROP2 NUMBER_MAX_PROP1 NUMBER_MAX_PROP2 @@ -40,6 +43,9 @@ set(CMAKE_DEBUG_TARGET_PROPERTIES set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP1 ON) set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP2 ON) +set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP5 OFF) +set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP6 OFF) +set_property(TARGET iface1 PROPERTY INTERFACE_BOOL_PROP7 OFF) set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP1 prop1) set_property(TARGET iface1 PROPERTY INTERFACE_STRING_PROP2 prop2) set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP1 100) @@ -47,8 +53,15 @@ set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MIN_PROP2 200) set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP1 100) set_property(TARGET iface1 PROPERTY INTERFACE_NUMBER_MAX_PROP2 200) +add_library(iface2 INTERFACE) +set_property(TARGET iface2 PROPERTY INTERFACE_BOOL_PROP6 OFF) + +add_library(iface3 INTERFACE) + add_executable(CompatibleInterface empty.cpp) -target_link_libraries(CompatibleInterface iface1) +target_link_libraries(CompatibleInterface iface1 iface2 + $<$<BOOL:$<TARGET_PROPERTY:BOOL_PROP7>>:iface3> +) set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP2 ON) set_property(TARGET CompatibleInterface PROPERTY BOOL_PROP3 ON) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-stderr.txt new file mode 100644 index 0000000..723daec --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use-stderr.txt @@ -0,0 +1,4 @@ +CMake Error: Property SOMEPROP on target "user" is +implied to be empty because it was used to determine the link libraries +already. The INTERFACE_SOMEPROP property on +dependency "foo" is in conflict. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use.cmake new file mode 100644 index 0000000..a064d76 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceNumber-mismatched-use.cmake @@ -0,0 +1,9 @@ + +add_library(foo UNKNOWN IMPORTED) +add_library(bar UNKNOWN IMPORTED) + +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_NUMBER_MIN SOMEPROP) +set_property(TARGET foo PROPERTY INTERFACE_SOMEPROP 42) + +add_executable(user main.cpp) +target_link_libraries(user foo $<$<STREQUAL:$<TARGET_PROPERTY:SOMEPROP>,42>:bar>) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt index 5a8f99d..900e3f8 100644 --- a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict-stderr.txt @@ -2,4 +2,5 @@ CMake Error in CMakeLists.txt: Property "SOMETHING" appears in both the COMPATIBLE_INTERFACE_BOOL and the COMPATIBLE_INTERFACE_STRING property in the dependencies of target "user". This is not allowed. A property may only require compatibility in a - boolean interpretation or a string interpretation, but not both. + boolean interpretation, a numeric minimum, a numeric maximum or a string + interpretation, but not a mixture. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake index 711368a..4bae804 100644 --- a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Conflict.cmake @@ -1,9 +1,8 @@ add_library(foo UNKNOWN IMPORTED) -add_library(bar UNKNOWN IMPORTED) set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL SOMETHING) set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING SOMETHING) add_executable(user main.cpp) -target_link_libraries(user foo bar) +target_link_libraries(user foo) diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-result.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-stderr.txt b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-stderr.txt new file mode 100644 index 0000000..2cfbae4 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict-stderr.txt @@ -0,0 +1,7 @@ +CMake Error in CMakeLists.txt: + Property "OTHER" appears in both the COMPATIBLE_INTERFACE_BOOL, + COMPATIBLE_INTERFACE_NUMBER_MIN and the COMPATIBLE_INTERFACE_STRING + property in the dependencies of target "user". This is not allowed. A + property may only require compatibility in a boolean interpretation, a + numeric minimum, a numeric maximum or a string interpretation, but not a + mixture. diff --git a/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict.cmake b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict.cmake new file mode 100644 index 0000000..164ffd9 --- /dev/null +++ b/Tests/RunCMake/CompatibleInterface/InterfaceString-Bool-Min-Conflict.cmake @@ -0,0 +1,9 @@ + +add_library(foo UNKNOWN IMPORTED) + +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_BOOL OTHER) +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_STRING OTHER) +set_property(TARGET foo APPEND PROPERTY COMPATIBLE_INTERFACE_NUMBER_MIN OTHER) + +add_executable(user main.cpp) +target_link_libraries(user foo) diff --git a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake index b87adc8..0b9729b 100644 --- a/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake +++ b/Tests/RunCMake/CompatibleInterface/RunCMakeTest.cmake @@ -7,8 +7,10 @@ run_cmake(InterfaceBool-builtin-prop) run_cmake(InterfaceString-mismatch-depends) run_cmake(InterfaceString-mismatch-depend-self) run_cmake(InterfaceString-mismatched-use) +run_cmake(InterfaceNumber-mismatched-use) run_cmake(InterfaceString-builtin-prop) run_cmake(InterfaceString-Bool-Conflict) +run_cmake(InterfaceString-Bool-Min-Conflict) run_cmake(DebugProperties) if (QT_QMAKE_EXECUTABLE}) diff --git a/Tests/RunCMake/include/ExportExportInclude-result.txt b/Tests/RunCMake/include/ExportExportInclude-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/include/ExportExportInclude-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/include/ExportExportInclude-stderr.txt b/Tests/RunCMake/include/ExportExportInclude-stderr.txt new file mode 100644 index 0000000..70d013c --- /dev/null +++ b/Tests/RunCMake/include/ExportExportInclude-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at ExportExportInclude.cmake:6 \(include\): + include could not find load file: + + .*/Tests/RunCMake/include/ExportExportInclude-build/theTargets.cmake +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/include/ExportExportInclude.cmake b/Tests/RunCMake/include/ExportExportInclude.cmake new file mode 100644 index 0000000..14e5d91 --- /dev/null +++ b/Tests/RunCMake/include/ExportExportInclude.cmake @@ -0,0 +1,6 @@ + +add_library(iface INTERFACE) +install(TARGETS iface EXPORT ifaceExport) + +export(EXPORT ifaceExport FILE "${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake") +include("${CMAKE_CURRENT_BINARY_DIR}/theTargets.cmake") diff --git a/Tests/RunCMake/include/RunCMakeTest.cmake b/Tests/RunCMake/include/RunCMakeTest.cmake index 7fc9a12..bea7d5c 100644 --- a/Tests/RunCMake/include/RunCMakeTest.cmake +++ b/Tests/RunCMake/include/RunCMakeTest.cmake @@ -4,3 +4,4 @@ run_cmake(EmptyString) run_cmake(EmptyStringOptional) run_cmake(CMP0024-WARN) run_cmake(CMP0024-NEW) +run_cmake(ExportExportInclude) diff --git a/Tests/RunCMake/interface_library/RunCMakeTest.cmake b/Tests/RunCMake/interface_library/RunCMakeTest.cmake index 0d00b71..9ca9a77 100644 --- a/Tests/RunCMake/interface_library/RunCMakeTest.cmake +++ b/Tests/RunCMake/interface_library/RunCMakeTest.cmake @@ -4,4 +4,6 @@ run_cmake(invalid_name) run_cmake(target_commands) run_cmake(no_shared_libs) run_cmake(whitelist) +run_cmake(invalid_signature) run_cmake(genex_link) +run_cmake(add_dependencies) diff --git a/Tests/RunCMake/interface_library/add_dependencies-result.txt b/Tests/RunCMake/interface_library/add_dependencies-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/interface_library/add_dependencies-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/interface_library/add_dependencies-stderr.txt b/Tests/RunCMake/interface_library/add_dependencies-stderr.txt new file mode 100644 index 0000000..c550b68 --- /dev/null +++ b/Tests/RunCMake/interface_library/add_dependencies-stderr.txt @@ -0,0 +1,6 @@ +CMake Error at add_dependencies.cmake:4 \(add_dependencies\): + add_dependencies Cannot add target-level dependencies to INTERFACE library + target "iface". + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/interface_library/add_dependencies.cmake b/Tests/RunCMake/interface_library/add_dependencies.cmake new file mode 100644 index 0000000..12cdfb4 --- /dev/null +++ b/Tests/RunCMake/interface_library/add_dependencies.cmake @@ -0,0 +1,4 @@ + +add_library(foo empty.cpp) +add_library(iface INTERFACE) +add_dependencies(iface foo) diff --git a/Tests/RunCMake/interface_library/invalid_signature-result.txt b/Tests/RunCMake/interface_library/invalid_signature-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/interface_library/invalid_signature-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/interface_library/invalid_signature-stderr.txt b/Tests/RunCMake/interface_library/invalid_signature-stderr.txt new file mode 100644 index 0000000..701586a --- /dev/null +++ b/Tests/RunCMake/interface_library/invalid_signature-stderr.txt @@ -0,0 +1,89 @@ +CMake Error at invalid_signature.cmake:2 \(add_library\): + add_library INTERFACE library requires no source arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:3 \(add_library\): + add_library INTERFACE library specified with conflicting/multiple types. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:4 \(add_library\): + add_library INTERFACE library specified with conflicting/multiple types. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:5 \(add_library\): + add_library INTERFACE library specified with conflicting/multiple types. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:6 \(add_library\): + add_library INTERFACE library specified with conflicting/multiple types. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:7 \(add_library\): + add_library INTERFACE library specified with conflicting/multiple types. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:8 \(add_library\): + add_library INTERFACE library specified with conflicting/multiple types. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:9 \(add_library\): + add_library INTERFACE library specified with conflicting STATIC type. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:10 \(add_library\): + add_library INTERFACE library specified with conflicting SHARED type. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:11 \(add_library\): + add_library INTERFACE library specified with conflicting MODULE type. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:12 \(add_library\): + add_library INTERFACE library specified with conflicting OBJECT type. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:13 \(add_library\): + add_library INTERFACE library specified with conflicting UNKNOWN type. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:14 \(add_library\): + add_library INTERFACE library specified with conflicting ALIAS type. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:15 \(add_library\): + add_library INTERFACE library specified with conflicting ALIAS type. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:16 \(add_library\): + add_library INTERFACE library specified with conflicting/multiple types. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:17 \(add_library\): + add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:18 \(add_library\): + add_library INTERFACE library may not be used with EXCLUDE_FROM_ALL. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) ++ +CMake Error at invalid_signature.cmake:20 \(add_library\): + add_library INTERFACE library requires no source arguments. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/interface_library/invalid_signature.cmake b/Tests/RunCMake/interface_library/invalid_signature.cmake new file mode 100644 index 0000000..67e3267 --- /dev/null +++ b/Tests/RunCMake/interface_library/invalid_signature.cmake @@ -0,0 +1,20 @@ + +add_library(iface1 INTERFACE empty.cpp) +add_library(iface3 STATIC INTERFACE) +add_library(iface4 STATIC INTERFACE empty.cpp) +add_library(iface5 SHARED INTERFACE) +add_library(iface6 MODULE INTERFACE) +add_library(iface7 OBJECT INTERFACE) +add_library(iface8 UNKNOWN INTERFACE) +add_library(iface9 INTERFACE STATIC) +add_library(iface10 INTERFACE SHARED) +add_library(iface11 INTERFACE MODULE) +add_library(iface12 INTERFACE OBJECT) +add_library(iface13 INTERFACE UNKNOWN) +add_library(iface14 INTERFACE ALIAS) +add_library(iface15 ALIAS INTERFACE) +add_library(iface16 INTERFACE INTERFACE) +add_library(iface17 INTERFACE EXCLUDE_FROM_ALL) +add_library(iface18 EXCLUDE_FROM_ALL INTERFACE) +add_library(iface19 GLOBAL INTERFACE) +add_library(iface20 INTERFACE GLOBAL) diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt index 5e0ef87..aa9735e 100644 --- a/Utilities/Sphinx/CMakeLists.txt +++ b/Utilities/Sphinx/CMakeLists.txt @@ -11,8 +11,7 @@ #============================================================================= if(NOT CMake_SOURCE_DIR) set(CMakeHelp_STANDALONE 1) - cmake_minimum_required(VERSION 2.8.2 FATAL_ERROR) - set(CMAKE_LEGACY_CYGWIN_WIN32 0) # Remove when CMake >= 2.8.4 is required + cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR) get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH) get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH) include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake) diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index 1955e42..336c74a 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -12,6 +12,16 @@ import os import re +# Monkey patch for pygments reporting an error when generator expressions are +# used. +# https://bitbucket.org/birkenfeld/pygments-main/issue/942/cmake-generator-expressions-not-handled +from pygments.lexers import CMakeLexer +from pygments.token import Name, Operator +from pygments.lexer import bygroups +CMakeLexer.tokens["args"].append(('(\\$<)(.+?)(>)', + bygroups(Operator, Name.Variable, Operator))) + + from docutils.parsers.rst import Directive, directives from docutils.transforms import Transform try: diff --git a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 index 9d60515..f8fb039 100644 --- a/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 +++ b/Utilities/cmlibarchive/libarchive/archive_write_set_options.3 @@ -255,7 +255,7 @@ If the .Ar value is .Cm hd , -then the the boot image is assumed to be a bootable hard disk image. +then the boot image is assumed to be a bootable hard disk image. If the .Ar value is |