Bladeren bron

Merge topic 'objective-c-cxx'

dd0f304613 Objective C/C++: Add compiler standard detection
b515af782b Help: Add release note for Objective-C/C++ language support
9e66397c28 Languages: Add support for Objective-C++
80f120a85f Languages: Add support for Objective-C

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3811
Brad King 6 jaren geleden
bovenliggende
commit
9b03baee30
72 gewijzigde bestanden met toevoegingen van 2787 en 81 verwijderingen
  1. 2 3
      Help/command/enable_language.rst
  2. 2 1
      Help/command/project.rst
  3. 28 0
      Help/manual/cmake-generator-expressions.7.rst
  4. 6 0
      Help/manual/cmake-modules.7.rst
  5. 1 0
      Help/module/CheckOBJCCompilerFlag.rst
  6. 1 0
      Help/module/CheckOBJCSourceCompiles.rst
  7. 1 0
      Help/module/CheckOBJCSourceRuns.rst
  8. 1 0
      Help/module/CheckOBJCXXCompilerFlag.rst
  9. 1 0
      Help/module/CheckOBJCXXSourceCompiles.rst
  10. 1 0
      Help/module/CheckOBJCXXSourceRuns.rst
  11. 9 0
      Help/release/dev/objective-c-cxx.rst
  12. 10 1
      Modules/CMakeCXXCompiler.cmake.in
  13. 189 0
      Modules/CMakeDetermineOBJCCompiler.cmake
  14. 197 0
      Modules/CMakeDetermineOBJCXXCompiler.cmake
  15. 69 0
      Modules/CMakeOBJCCompiler.cmake.in
  16. 20 0
      Modules/CMakeOBJCCompilerABI.m
  17. 63 0
      Modules/CMakeOBJCCompilerId.m.in
  18. 188 0
      Modules/CMakeOBJCInformation.cmake
  19. 79 0
      Modules/CMakeOBJCXXCompiler.cmake.in
  20. 20 0
      Modules/CMakeOBJCXXCompilerABI.mm
  21. 68 0
      Modules/CMakeOBJCXXCompilerId.mm.in
  22. 273 0
      Modules/CMakeOBJCXXInformation.cmake
  23. 94 0
      Modules/CMakeTestOBJCCompiler.cmake
  24. 93 0
      Modules/CMakeTestOBJCXXCompiler.cmake
  25. 64 0
      Modules/CheckOBJCCompilerFlag.cmake
  26. 145 0
      Modules/CheckOBJCSourceCompiles.cmake
  27. 145 0
      Modules/CheckOBJCSourceRuns.cmake
  28. 64 0
      Modules/CheckOBJCXXCompilerFlag.cmake
  29. 146 0
      Modules/CheckOBJCXXSourceCompiles.cmake
  30. 145 0
      Modules/CheckOBJCXXSourceRuns.cmake
  31. 17 0
      Modules/Compiler/AppleClang-OBJC.cmake
  32. 37 0
      Modules/Compiler/AppleClang-OBJCXX.cmake
  33. 18 0
      Modules/Compiler/Clang-OBJC.cmake
  34. 70 0
      Modules/Compiler/Clang-OBJCXX.cmake
  35. 6 0
      Modules/Compiler/GNU-OBJC.cmake
  36. 10 0
      Modules/Compiler/GNU-OBJCXX.cmake
  37. 6 0
      Modules/Platform/Apple-AppleClang-OBJC.cmake
  38. 6 0
      Modules/Platform/Apple-AppleClang-OBJCXX.cmake
  39. 2 0
      Modules/Platform/Apple-Clang-OBJC.cmake
  40. 2 0
      Modules/Platform/Apple-Clang-OBJCXX.cmake
  41. 4 0
      Modules/Platform/Apple-GNU-OBJC.cmake
  42. 4 0
      Modules/Platform/Apple-GNU-OBJCXX.cmake
  43. 9 1
      Modules/Platform/Darwin.cmake
  44. 7 1
      Source/cmGeneratorExpressionNode.cxx
  45. 11 1
      Source/cmLocalGenerator.cxx
  46. 80 68
      Source/cmMakefile.cxx
  47. 10 4
      Source/cmMakefile.h
  48. 8 0
      Source/cmTarget.cxx
  49. 73 0
      Tests/CMakeLists.txt
  50. 11 0
      Tests/CMakeOnly/CMakeLists.txt
  51. 11 1
      Tests/CMakeOnly/CheckLanguage/CMakeLists.txt
  52. 17 0
      Tests/CMakeOnly/CheckOBJCCompilerFlag/CMakeLists.txt
  53. 17 0
      Tests/CMakeOnly/CheckOBJCXXCompilerFlag/CMakeLists.txt
  54. 14 0
      Tests/CMakeOnly/CompilerIdOBJC/CMakeLists.txt
  55. 14 0
      Tests/CMakeOnly/CompilerIdOBJCXX/CMakeLists.txt
  56. 5 0
      Tests/Objective-C++/cxx-file-extension-test/CMakeLists.txt
  57. 8 0
      Tests/Objective-C++/cxx-file-extension-test/main.mm
  58. 6 0
      Tests/Objective-C++/objcxx-file-extension-test/CMakeLists.txt
  59. 14 0
      Tests/Objective-C++/objcxx-file-extension-test/main.mm
  60. 11 0
      Tests/Objective-C++/simple-build-test/CMakeLists.txt
  61. 9 0
      Tests/Objective-C++/simple-build-test/foo.h
  62. 7 0
      Tests/Objective-C++/simple-build-test/foo.mm
  63. 14 0
      Tests/Objective-C++/simple-build-test/main.mm
  64. 5 0
      Tests/Objective-C/c-file-extension-test/CMakeLists.txt
  65. 8 0
      Tests/Objective-C/c-file-extension-test/main.m
  66. 6 0
      Tests/Objective-C/objc-file-extension-test/CMakeLists.txt
  67. 12 0
      Tests/Objective-C/objc-file-extension-test/main.m
  68. 11 0
      Tests/Objective-C/simple-build-test/CMakeLists.txt
  69. 9 0
      Tests/Objective-C/simple-build-test/foo.h
  70. 7 0
      Tests/Objective-C/simple-build-test/foo.m
  71. 12 0
      Tests/Objective-C/simple-build-test/main.m
  72. 54 0
      Tests/TryCompile/CMakeLists.txt

+ 2 - 3
Help/command/enable_language.rst

@@ -1,7 +1,6 @@
 enable_language
 ---------------
-
-Enable a language (CXX/C/Fortran/etc)
+Enable a language (CXX/C/OBJC/OBJCXX/Fortran/etc)
 
 .. code-block:: cmake
 
@@ -10,7 +9,7 @@ Enable a language (CXX/C/Fortran/etc)
 Enables support for the named language in CMake.  This is
 the same as the :command:`project` command but does not create any of the extra
 variables that are created by the project command.  Example languages
-are ``CXX``, ``C``, ``CUDA``, ``Fortran``, and ``ASM``.
+are ``CXX``, ``C``, ``CUDA``, ``OBJC``, ``OBJCXX``, ``Fortran``, and ``ASM``.
 
 If enabling ``ASM``, enable it last so that CMake can check whether
 compilers for other languages like ``C`` work for assembly too.

+ 2 - 1
Help/command/project.rst

@@ -87,7 +87,8 @@ The options are:
   Can also be specified without ``LANGUAGES`` keyword per the first, short signature.
 
   Selects which programming languages are needed to build the project.
-  Supported languages include ``C``, ``CXX`` (i.e.  C++), ``CUDA``, ``Fortran``, and ``ASM``.
+  Supported languages include ``C``, ``CXX`` (i.e.  C++), ``CUDA``,
+  ``OBJC`` (i.e. Objective-C), ``OBJCXX``, ``Fortran``, and ``ASM``.
   By default ``C`` and ``CXX`` are enabled if no language options are given.
   Specify language ``NONE``, or use the ``LANGUAGES`` keyword and list no languages,
   to skip enabling any languages.

+ 28 - 0
Help/manual/cmake-generator-expressions.7.rst

@@ -130,6 +130,16 @@ Variable Queries
   ``1`` if the CMake's compiler id of the CUDA compiler matches any one
   of the entries in ``compiler_ids``, otherwise ``0``.
   See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+``$<OBJC_COMPILER_ID:compiler_ids>``
+  where ``compiler_ids`` is a comma-separated list.
+  ``1`` if the CMake's compiler id of the Objective-C compiler matches any one
+  of the entries in ``compiler_ids``, otherwise ``0``.
+  See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+``$<OBJCXX_COMPILER_ID:compiler_ids>``
+  where ``compiler_ids`` is a comma-separated list.
+  ``1`` if the CMake's compiler id of the Objective-C++ compiler matches any one
+  of the entries in ``compiler_ids``, otherwise ``0``.
+  See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
 ``$<Fortran_COMPILER_ID:compiler_ids>``
   where ``compiler_ids`` is a comma-separated list.
   ``1`` if the CMake's compiler id of the Fortran compiler matches any one
@@ -144,6 +154,12 @@ Variable Queries
 ``$<CUDA_COMPILER_VERSION:version>``
   ``1`` if the version of the CXX compiler matches ``version``, otherwise ``0``.
   See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+``$<OBJC_COMPILER_VERSION:version>``
+  ``1`` if the version of the OBJC compiler matches ``version``, otherwise ``0``.
+  See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+``$<OBJCXX_COMPILER_VERSION:version>``
+  ``1`` if the version of the OBJCXX compiler matches ``version``, otherwise ``0``.
+  See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
 ``$<Fortran_COMPILER_VERSION:version>``
   ``1`` if the version of the Fortran compiler matches ``version``, otherwise ``0``.
   See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
@@ -401,6 +417,12 @@ Variable Queries
 ``$<CUDA_COMPILER_ID>``
   The CMake's compiler id of the CUDA compiler used.
   See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+``$<OBJC_COMPILER_ID>``
+  The CMake's compiler id of the OBJC compiler used.
+  See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
+``$<OBJCXX_COMPILER_ID>``
+  The CMake's compiler id of the OBJCXX compiler used.
+  See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
 ``$<Fortran_COMPILER_ID>``
   The CMake's compiler id of the Fortran compiler used.
   See also the :variable:`CMAKE_<LANG>_COMPILER_ID` variable.
@@ -413,6 +435,12 @@ Variable Queries
 ``$<CUDA_COMPILER_VERSION>``
   The version of the CUDA compiler used.
   See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+``$<OBJC_COMPILER_VERSION>``
+  The version of the OBJC compiler used.
+  See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
+``$<OBJCXX_COMPILER_VERSION>``
+  The version of the OBJCXX compiler used.
+  See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.
 ``$<Fortran_COMPILER_VERSION>``
   The version of the Fortran compiler used.
   See also the :variable:`CMAKE_<LANG>_COMPILER_VERSION` variable.

+ 6 - 0
Help/manual/cmake-modules.7.rst

@@ -36,6 +36,12 @@ These modules are loaded using the :command:`include` command.
    /module/CheckIncludeFiles
    /module/CheckLanguage
    /module/CheckLibraryExists
+   /module/CheckOBJCCompilerFlag
+   /module/CheckOBJCSourceCompiles
+   /module/CheckOBJCSourceRuns
+   /module/CheckOBJCXXCompilerFlag
+   /module/CheckOBJCXXSourceCompiles
+   /module/CheckOBJCXXSourceRuns
    /module/CheckPIESupported
    /module/CheckPrototypeDefinition
    /module/CheckStructHasMember

+ 1 - 0
Help/module/CheckOBJCCompilerFlag.rst

@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckOBJCCompilerFlag.cmake

+ 1 - 0
Help/module/CheckOBJCSourceCompiles.rst

@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckOBJCSourceCompiles.cmake

+ 1 - 0
Help/module/CheckOBJCSourceRuns.rst

@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckOBJCSourceRuns.cmake

+ 1 - 0
Help/module/CheckOBJCXXCompilerFlag.rst

@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckOBJCXXCompilerFlag.cmake

+ 1 - 0
Help/module/CheckOBJCXXSourceCompiles.rst

@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckOBJCXXSourceCompiles.cmake

+ 1 - 0
Help/module/CheckOBJCXXSourceRuns.rst

@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/CheckOBJCXXSourceRuns.cmake

+ 9 - 0
Help/release/dev/objective-c-cxx.rst

@@ -0,0 +1,9 @@
+Objective C/C++
+---------------
+
+* CMake learned to support the Objective C (``OBJC``) and Objective C++
+  (``OBJCXX``) languages.  They may be enabled via the :command:`project`
+  and :command:`enable_language` commands.  When ``OBJC`` or ``OBJCXX``
+  is enabled, source files with the ``.m`` or ``.mm``, respectively,
+  will be compiled as Objective C or C++.  Otherwise they will be treated
+  as plain C++ sources as they were before.

+ 10 - 1
Modules/CMakeCXXCompiler.cmake.in

@@ -42,8 +42,17 @@ if(CMAKE_COMPILER_IS_MINGW)
   set(MINGW 1)
 endif()
 set(CMAKE_CXX_COMPILER_ID_RUN 1)
+set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP)
 set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
-set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;mm;CPP)
+
+foreach (lang OBJC OBJCXX)
+  if (CMAKE_${lang}_COMPILER_ID_RUN)
+    foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
+      list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
+    endforeach()
+  endif()
+endforeach()
+
 set(CMAKE_CXX_LINKER_PREFERENCE 30)
 set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
 

+ 189 - 0
Modules/CMakeDetermineOBJCCompiler.cmake

@@ -0,0 +1,189 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# determine the compiler to use for Objective-C programs
+# NOTE, a generator may set CMAKE_OBJC_COMPILER before
+# loading this file to force a compiler.
+# use environment variable OBJC first if defined by user, next use
+# the cmake variable CMAKE_GENERATOR_OBJC which can be defined by a generator
+# as a default compiler
+#
+# Sets the following variables:
+#   CMAKE_OBJC_COMPILER
+#   CMAKE_AR
+#   CMAKE_RANLIB
+#   CMAKE_COMPILER_IS_GNUOBJC
+#   CMAKE_COMPILER_IS_CLANGOBJC
+#
+# If not already set before, it also sets
+#   _CMAKE_TOOLCHAIN_PREFIX
+
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
+
+# Load system-specific compiler preferences for this language.
+include(Platform/${CMAKE_SYSTEM_NAME}-Determine-OBJC OPTIONAL)
+include(Platform/${CMAKE_SYSTEM_NAME}-OBJC OPTIONAL)
+if(NOT CMAKE_OBJC_COMPILER_NAMES)
+  set(CMAKE_OBJC_COMPILER_NAMES clang)
+endif()
+
+if("${CMAKE_GENERATOR}" MATCHES "Xcode")
+  set(CMAKE_OBJC_COMPILER_XCODE_TYPE sourcecode.c.objc)
+else()
+  if(NOT CMAKE_OBJC_COMPILER)
+    set(CMAKE_OBJC_COMPILER_INIT NOTFOUND)
+
+    # prefer the environment variable OBJC
+    if($ENV{OBJC} MATCHES ".+")
+      get_filename_component(CMAKE_OBJC_COMPILER_INIT $ENV{OBJC} PROGRAM PROGRAM_ARGS CMAKE_OBJC_FLAGS_ENV_INIT)
+      if(CMAKE_OBJC_FLAGS_ENV_INIT)
+        set(CMAKE_OBJC_COMPILER_ARG1 "${CMAKE_OBJC_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C compiler")
+      endif()
+      if(NOT EXISTS ${CMAKE_OBJC_COMPILER_INIT})
+        message(FATAL_ERROR "Could not find compiler set in environment variable OBJC:\n$ENV{OBJC}.")
+      endif()
+    endif()
+
+    # next try prefer the compiler specified by the generator
+    if(CMAKE_GENERATOR_OBJC)
+      if(NOT CMAKE_OBJC_COMPILER_INIT)
+        set(CMAKE_OBJC_COMPILER_INIT ${CMAKE_GENERATOR_OBJC})
+      endif()
+    endif()
+
+    # finally list compilers to try
+    if(NOT CMAKE_OBJC_COMPILER_INIT)
+      set(CMAKE_OBJC_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}cc ${_CMAKE_TOOLCHAIN_PREFIX}gcc clang)
+    endif()
+
+    _cmake_find_compiler(OBJC)
+
+  else()
+    # we only get here if CMAKE_OBJC_COMPILER was specified using -D or a pre-made CMakeCache.txt
+    # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
+    # if CMAKE_OBJC_COMPILER is a list of length 2, use the first item as
+    # CMAKE_OBJC_COMPILER and the 2nd one as CMAKE_OBJC_COMPILER_ARG1
+
+    list(LENGTH CMAKE_OBJC_COMPILER _CMAKE_OBJC_COMPILER_LIST_LENGTH)
+    if("${_CMAKE_OBJC_COMPILER_LIST_LENGTH}" EQUAL 2)
+      list(GET CMAKE_OBJC_COMPILER 1 CMAKE_OBJC_COMPILER_ARG1)
+      list(GET CMAKE_OBJC_COMPILER 0 CMAKE_OBJC_COMPILER)
+    endif()
+
+    # if a compiler was specified by the user but without path,
+    # now try to find it with the full path
+    # if it is found, force it into the cache,
+    # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
+    # if the C compiler already had a path, reuse it for searching the CXX compiler
+    get_filename_component(_CMAKE_USER_OBJC_COMPILER_PATH "${CMAKE_OBJC_COMPILER}" PATH)
+    if(NOT _CMAKE_USER_OBJC_COMPILER_PATH)
+      find_program(CMAKE_OBJC_COMPILER_WITH_PATH NAMES ${CMAKE_OBJC_COMPILER})
+      if(CMAKE_OBJC_COMPILER_WITH_PATH)
+        set(CMAKE_OBJC_COMPILER ${CMAKE_OBJC_COMPILER_WITH_PATH} CACHE STRING "Objective-C compiler" FORCE)
+      endif()
+      unset(CMAKE_OBJC_COMPILER_WITH_PATH CACHE)
+    endif()
+  endif()
+  mark_as_advanced(CMAKE_OBJC_COMPILER)
+
+  # Each entry in this list is a set of extra flags to try
+  # adding to the compile line to see if it helps produce
+  # a valid identification file.
+  set(CMAKE_OBJC_COMPILER_ID_TEST_FLAGS_FIRST)
+  set(CMAKE_OBJC_COMPILER_ID_TEST_FLAGS
+    # Try compiling to an object file only.
+    "-c"
+
+    )
+endif()
+
+# Build a small source file to identify the compiler.
+if(NOT CMAKE_OBJC_COMPILER_ID_RUN)
+  set(CMAKE_OBJC_COMPILER_ID_RUN 1)
+
+  # Try to identify the compiler.
+  set(CMAKE_OBJC_COMPILER_ID)
+  file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
+    CMAKE_OBJC_COMPILER_ID_PLATFORM_CONTENT)
+
+  # Match the link line from xcodebuild output of the form
+  #  Ld ...
+  #      ...
+  #      /path/to/cc ...CompilerIdOBJC/...
+  # to extract the compiler front-end for the language.
+  set(CMAKE_OBJC_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdOBJC/(\\./)?(CompilerIdOBJC.(framework|xctest)/)?CompilerIdOBJC[ \t\n\\\"]")
+  set(CMAKE_OBJC_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+  CMAKE_DETERMINE_COMPILER_ID(OBJC OBJCCFLAGS CMakeOBJCCompilerId.m)
+
+  # Set old compiler and platform id variables.
+  if(CMAKE_OBJC_COMPILER_ID STREQUAL "GNU")
+    set(CMAKE_COMPILER_IS_GNUOBJC 1)
+  endif()
+  if(CMAKE_OBJC_COMPILER_ID STREQUAL "Clang")
+    set(CMAKE_COMPILER_IS_CLANGOBJC 1)
+  endif()
+endif()
+
+if (NOT _CMAKE_TOOLCHAIN_LOCATION)
+  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_OBJC_COMPILER}" PATH)
+endif ()
+
+# If we have a gcc cross compiler, they have usually some prefix, like
+# e.g. powerpc-linux-gcc, arm-elf-gcc or i586-mingw32msvc-gcc, optionally
+# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).
+# The other tools of the toolchain usually have the same prefix
+# NAME_WE cannot be used since then this test will fail for names like
+# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
+# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
+if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)
+
+  if(CMAKE_OBJC_COMPILER_ID MATCHES "GNU|Clang|QCC")
+    get_filename_component(COMPILER_BASENAME "${CMAKE_OBJC_COMPILER}" NAME)
+    if (COMPILER_BASENAME MATCHES "^(.+-)(clang|g?cc)(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+      set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5})
+    elseif(CMAKE_OBJC_COMPILER_ID MATCHES "Clang")
+      if(CMAKE_OBJC_COMPILER_TARGET)
+        set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_OBJC_COMPILER_TARGET}-)
+      endif()
+    elseif(COMPILER_BASENAME MATCHES "qcc(\\.exe)?$")
+      if(CMAKE_OBJC_COMPILER_TARGET MATCHES "gcc_nto([a-z0-9]+_[0-9]+|[^_le]+)(le)?")
+        set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-)
+      endif()
+    endif ()
+
+    # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
+    # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
+    if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    endif ()
+  endif()
+
+endif ()
+
+set(_CMAKE_PROCESSING_LANGUAGE "OBJC")
+include(CMakeFindBinUtils)
+include(Compiler/${CMAKE_OBJC_COMPILER_ID}-FindBinUtils OPTIONAL)
+unset(_CMAKE_PROCESSING_LANGUAGE)
+
+if(CMAKE_OBJC_COMPILER_ARCHITECTURE_ID)
+  set(_SET_CMAKE_OBJC_COMPILER_ARCHITECTURE_ID
+    "set(CMAKE_OBJC_COMPILER_ARCHITECTURE_ID ${CMAKE_OBJC_COMPILER_ARCHITECTURE_ID})")
+else()
+  set(_SET_CMAKE_OBJC_COMPILER_ARCHITECTURE_ID "")
+endif()
+
+if(CMAKE_OBJC_XCODE_ARCHS)
+  set(SET_CMAKE_XCODE_ARCHS
+    "set(CMAKE_XCODE_ARCHS \"${CMAKE_OBJC_XCODE_ARCHS}\")")
+endif()
+
+# configure variables set in this file for fast reload later on
+configure_file(${CMAKE_ROOT}/Modules/CMakeOBJCCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake
+  @ONLY
+  )
+set(CMAKE_OBJC_COMPILER_ENV_VAR "OBJC")

+ 197 - 0
Modules/CMakeDetermineOBJCXXCompiler.cmake

@@ -0,0 +1,197 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# determine the compiler to use for Objective-C++ programs
+# NOTE, a generator may set CMAKE_OBJCXX_COMPILER before
+# loading this file to force a compiler.
+# use environment variable OBJCXX first if defined by user, next use
+# the cmake variable CMAKE_GENERATOR_OBJCXX which can be defined by a generator
+# as a default compiler
+# If the internal cmake variable _CMAKE_TOOLCHAIN_PREFIX is set, this is used
+# as prefix for the tools (e.g. arm-elf-g++, arm-elf-ar etc.)
+#
+# Sets the following variables:
+#   CMAKE_OBJCXX_COMPILER
+#   CMAKE_COMPILER_IS_GNUOBJCXX
+#   CMAKE_COMPILER_IS_CLANGOBJCXX
+#   CMAKE_AR
+#   CMAKE_RANLIB
+#
+# If not already set before, it also sets
+#   _CMAKE_TOOLCHAIN_PREFIX
+
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
+
+# Load system-specific compiler preferences for this language.
+include(Platform/${CMAKE_SYSTEM_NAME}-Determine-OBJCXX OPTIONAL)
+include(Platform/${CMAKE_SYSTEM_NAME}-OBJCXX OPTIONAL)
+if(NOT CMAKE_OBJCXX_COMPILER_NAMES)
+  set(CMAKE_OBJCXX_COMPILER_NAMES clang++)
+endif()
+
+if("${CMAKE_GENERATOR}" MATCHES "Xcode")
+  set(CMAKE_OBJCXX_COMPILER_XCODE_TYPE sourcecode.cpp.objcpp)
+else()
+  if(NOT CMAKE_OBJCXX_COMPILER)
+    set(CMAKE_OBJCXX_COMPILER_INIT NOTFOUND)
+
+    # prefer the environment variable OBJCXX
+    if($ENV{OBJCXX} MATCHES ".+")
+      get_filename_component(CMAKE_OBJCXX_COMPILER_INIT $ENV{OBJCXX} PROGRAM PROGRAM_ARGS CMAKE_OBJCXX_FLAGS_ENV_INIT)
+      if(CMAKE_OBJCXX_FLAGS_ENV_INIT)
+        set(CMAKE_OBJCXX_COMPILER_ARG1 "${CMAKE_OBJCXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to Objective-C++ compiler")
+      endif()
+      if(NOT EXISTS ${CMAKE_OBJCXX_COMPILER_INIT})
+        message(FATAL_ERROR "Could not find compiler set in environment variable OBJCXX:\n$ENV{OBJCXX}.\n${CMAKE_OBJCXX_COMPILER_INIT}")
+      endif()
+    endif()
+
+    # next prefer the generator specified compiler
+    if(CMAKE_GENERATOR_OBJCXX)
+      if(NOT CMAKE_OBJCXX_COMPILER_INIT)
+        set(CMAKE_OBJCXX_COMPILER_INIT ${CMAKE_GENERATOR_OBJCXX})
+      endif()
+    endif()
+
+    # finally list compilers to try
+    if(NOT CMAKE_OBJCXX_COMPILER_INIT)
+      set(CMAKE_OBJCXX_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ clang++)
+    endif()
+
+    _cmake_find_compiler(OBJCXX)
+
+  else()
+    # we only get here if CMAKE_OBJCXX_COMPILER was specified using -D or a pre-made CMakeCache.txt
+    # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
+    # if CMAKE_OBJCXX_COMPILER is a list of length 2, use the first item as
+    # CMAKE_OBJCXX_COMPILER and the 2nd one as CMAKE_OBJCXX_COMPILER_ARG1
+
+    list(LENGTH CMAKE_OBJCXX_COMPILER _CMAKE_OBJCXX_COMPILER_LIST_LENGTH)
+    if("${_CMAKE_OBJCXX_COMPILER_LIST_LENGTH}" EQUAL 2)
+      list(GET CMAKE_OBJCXX_COMPILER 1 CMAKE_OBJCXX_COMPILER_ARG1)
+      list(GET CMAKE_OBJCXX_COMPILER 0 CMAKE_OBJCXX_COMPILER)
+    endif()
+
+    # if a compiler was specified by the user but without path,
+    # now try to find it with the full path
+    # if it is found, force it into the cache,
+    # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
+    # if the C compiler already had a path, reuse it for searching the CXX compiler
+    get_filename_component(_CMAKE_USER_OBJCXX_COMPILER_PATH "${CMAKE_OBJCXX_COMPILER}" PATH)
+    if(NOT _CMAKE_USER_OBJCXX_COMPILER_PATH)
+      find_program(CMAKE_OBJCXX_COMPILER_WITH_PATH NAMES ${CMAKE_OBJCXX_COMPILER})
+      if(CMAKE_OBJCXX_COMPILER_WITH_PATH)
+        set(CMAKE_OBJCXX_COMPILER ${CMAKE_OBJCXX_COMPILER_WITH_PATH} CACHE STRING "Objective-C++ compiler" FORCE)
+      endif()
+      unset(CMAKE_OBJCXX_COMPILER_WITH_PATH CACHE)
+    endif()
+
+  endif()
+  mark_as_advanced(CMAKE_OBJCXX_COMPILER)
+
+  # Each entry in this list is a set of extra flags to try
+  # adding to the compile line to see if it helps produce
+  # a valid identification file.
+  set(CMAKE_OBJCXX_COMPILER_ID_TEST_FLAGS_FIRST)
+  set(CMAKE_OBJCXX_COMPILER_ID_TEST_FLAGS
+    # Try compiling to an object file only.
+    "-c"
+
+    # ARMClang need target options
+    "--target=arm-arm-none-eabi -mcpu=cortex-m3"
+    )
+endif()
+
+# Build a small source file to identify the compiler.
+if(NOT CMAKE_OBJCXX_COMPILER_ID_RUN)
+  set(CMAKE_OBJCXX_COMPILER_ID_RUN 1)
+
+  # Try to identify the compiler.
+  set(CMAKE_OBJCXX_COMPILER_ID)
+  file(READ ${CMAKE_ROOT}/Modules/CMakePlatformId.h.in
+    CMAKE_OBJCXX_COMPILER_ID_PLATFORM_CONTENT)
+
+  # Match the link line from xcodebuild output of the form
+  #  Ld ...
+  #      ...
+  #      /path/to/cc ...CompilerIdOBJCXX/...
+  # to extract the compiler front-end for the language.
+  set(CMAKE_OBJCXX_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdOBJCXX/(\\./)?(CompilerIdOBJCXX.(framework|xctest)/)?CompilerIdOBJCXX[ \t\n\\\"]")
+  set(CMAKE_OBJCXX_COMPILER_ID_TOOL_MATCH_INDEX 2)
+
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+  CMAKE_DETERMINE_COMPILER_ID(OBJCXX OBJCXXFLAGS CMakeOBJCXXCompilerId.mm)
+
+  # Set old compiler and platform id variables.
+  if(CMAKE_OBJCXX_COMPILER_ID MATCHES "GNU")
+    set(CMAKE_COMPILER_IS_GNUOBJCXX 1)
+  endif()
+  if(CMAKE_OBJCXX_COMPILER_ID MATCHES "Clang")
+    set(CMAKE_COMPILER_IS_CLANGOBJCXX 1)
+  endif()
+endif()
+
+if (NOT _CMAKE_TOOLCHAIN_LOCATION)
+  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_OBJCXX_COMPILER}" PATH)
+endif ()
+
+# if we have a g++ cross compiler, they have usually some prefix, like
+# e.g. powerpc-linux-g++, arm-elf-g++ or i586-mingw32msvc-g++ , optionally
+# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).
+# The other tools of the toolchain usually have the same prefix
+# NAME_WE cannot be used since then this test will fail for names like
+# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
+# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
+
+
+if (CMAKE_CROSSCOMPILING  AND NOT  _CMAKE_TOOLCHAIN_PREFIX)
+
+  if("${CMAKE_OBJCXX_COMPILER_ID}" MATCHES "GNU|Clang|QCC")
+    get_filename_component(COMPILER_BASENAME "${CMAKE_OBJCXX_COMPILER}" NAME)
+    if (COMPILER_BASENAME MATCHES "^(.+-)(clan)?[gc]\\+\\+(-[0-9]+(\\.[0-9]+)*)?(-[^.]+)?(\\.exe)?$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+      set(_CMAKE_COMPILER_SUFFIX ${CMAKE_MATCH_5})
+    elseif("${CMAKE_OBJCXX_COMPILER_ID}" MATCHES "Clang")
+      if(CMAKE_OBJCXX_COMPILER_TARGET)
+        set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_OBJCXX_COMPILER_TARGET}-)
+      endif()
+    elseif(COMPILER_BASENAME MATCHES "QCC(\\.exe)?$")
+      if(CMAKE_OBJCXX_COMPILER_TARGET MATCHES "gcc_nto([a-z0-9]+_[0-9]+|[^_le]+)(le)")
+        set(_CMAKE_TOOLCHAIN_PREFIX nto${CMAKE_MATCH_1}-)
+      endif()
+    endif ()
+
+    # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
+    # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
+    if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
+      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
+    endif ()
+  endif()
+
+endif ()
+
+set(_CMAKE_PROCESSING_LANGUAGE "OBJCXX")
+include(CMakeFindBinUtils)
+include(Compiler/${CMAKE_OBJCXX_COMPILER_ID}-FindBinUtils OPTIONAL)
+unset(_CMAKE_PROCESSING_LANGUAGE)
+
+if(CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID)
+  set(_SET_CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID
+    "set(CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID ${CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID})")
+else()
+  set(_SET_CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID "")
+endif()
+
+if(CMAKE_OBJCXX_XCODE_ARCHS)
+  set(SET_CMAKE_XCODE_ARCHS
+    "set(CMAKE_XCODE_ARCHS \"${CMAKE_OBJCXX_XCODE_ARCHS}\")")
+endif()
+
+# configure all variables set in this file
+configure_file(${CMAKE_ROOT}/Modules/CMakeOBJCXXCompiler.cmake.in
+  ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCXXCompiler.cmake
+  @ONLY
+  )
+
+set(CMAKE_OBJCXX_COMPILER_ENV_VAR "OBJCXX")

+ 69 - 0
Modules/CMakeOBJCCompiler.cmake.in

@@ -0,0 +1,69 @@
+set(CMAKE_OBJC_COMPILER "@CMAKE_OBJC_COMPILER@")
+set(CMAKE_OBJC_COMPILER_ARG1 "@CMAKE_OBJC_COMPILER_ARG1@")
+set(CMAKE_OBJC_COMPILER_ID "@CMAKE_OBJC_COMPILER_ID@")
+set(CMAKE_OBJC_COMPILER_VERSION "@CMAKE_OBJC_COMPILER_VERSION@")
+set(CMAKE_OBJC_COMPILER_VERSION_INTERNAL "@CMAKE_OBJC_COMPILER_VERSION_INTERNAL@")
+set(CMAKE_OBJC_COMPILER_WRAPPER "@CMAKE_OBJC_COMPILER_WRAPPER@")
+set(CMAKE_OBJC_STANDARD_COMPUTED_DEFAULT "@CMAKE_OBJC_STANDARD_COMPUTED_DEFAULT@")
+set(CMAKE_OBJC_COMPILE_FEATURES "@CMAKE_OBJC_COMPILE_FEATURES@")
+set(CMAKE_OBJC90_COMPILE_FEATURES "@CMAKE_OBJC90_COMPILE_FEATURES@")
+set(CMAKE_OBJC99_COMPILE_FEATURES "@CMAKE_OBJC99_COMPILE_FEATURES@")
+set(CMAKE_OBJC11_COMPILE_FEATURES "@CMAKE_OBJC11_COMPILE_FEATURES@")
+
+set(CMAKE_OBJC_PLATFORM_ID "@CMAKE_OBJC_PLATFORM_ID@")
+set(CMAKE_OBJC_SIMULATE_ID "@CMAKE_OBJC_SIMULATE_ID@")
+set(CMAKE_OBJC_COMPILER_FRONTEND_VARIANT "@CMAKE_OBJC_COMPILER_FRONTEND_VARIANT@")
+set(CMAKE_OBJC_SIMULATE_VERSION "@CMAKE_OBJC_SIMULATE_VERSION@")
+@_SET_CMAKE_OBJC_COMPILER_ARCHITECTURE_ID@
+@SET_CMAKE_XCODE_ARCHS@
+set(CMAKE_AR "@CMAKE_AR@")
+set(CMAKE_OBJC_COMPILER_AR "@CMAKE_OBJC_COMPILER_AR@")
+set(CMAKE_RANLIB "@CMAKE_RANLIB@")
+set(CMAKE_OBJC_COMPILER_RANLIB "@CMAKE_OBJC_COMPILER_RANLIB@")
+set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_MT "@CMAKE_MT@")
+set(CMAKE_COMPILER_IS_GNUOBJC @CMAKE_COMPILER_IS_GNUOBJC@)
+set(CMAKE_OBJC_COMPILER_LOADED 1)
+set(CMAKE_OBJC_COMPILER_WORKS @CMAKE_OBJC_COMPILER_WORKS@)
+set(CMAKE_OBJC_ABI_COMPILED @CMAKE_OBJC_ABI_COMPILED@)
+
+set(CMAKE_OBJC_COMPILER_ENV_VAR "OBJC")
+
+set(CMAKE_OBJC_COMPILER_ID_RUN 1)
+set(CMAKE_OBJC_SOURCE_FILE_EXTENSIONS m)
+set(CMAKE_OBJC_IGNORE_EXTENSIONS h;H;o;O)
+set(CMAKE_OBJC_LINKER_PREFERENCE 5)
+
+foreach (lang C CXX OBJCXX)
+  foreach(extension IN LISTS CMAKE_OBJC_SOURCE_FILE_EXTENSIONS)
+    if (CMAKE_${lang}_COMPILER_ID_RUN)
+      list(REMOVE_ITEM CMAKE_${lang}_SOURCE_FILE_EXTENSIONS ${extension})
+    endif()
+  endforeach()
+endforeach()
+
+# Save compiler ABI information.
+set(CMAKE_OBJC_SIZEOF_DATA_PTR "@CMAKE_OBJC_SIZEOF_DATA_PTR@")
+set(CMAKE_OBJC_COMPILER_ABI "@CMAKE_OBJC_COMPILER_ABI@")
+set(CMAKE_OBJC_LIBRARY_ARCHITECTURE "@CMAKE_OBJC_LIBRARY_ARCHITECTURE@")
+
+if(CMAKE_OBJC_SIZEOF_DATA_PTR)
+  set(CMAKE_SIZEOF_VOID_P "${CMAKE_OBJC_SIZEOF_DATA_PTR}")
+endif()
+
+if(CMAKE_OBJC_COMPILER_ABI)
+  set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_OBJC_COMPILER_ABI}")
+endif()
+
+if(CMAKE_OBJC_LIBRARY_ARCHITECTURE)
+  set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_OBJC_LIBRARY_ARCHITECTURE@")
+endif()
+
+@CMAKE_OBJC_COMPILER_CUSTOM_CODE@
+@CMAKE_OBJC_SYSROOT_FLAG_CODE@
+@CMAKE_OBJC_OSX_DEPLOYMENT_TARGET_FLAG_CODE@
+
+set(CMAKE_OBJC_IMPLICIT_INCLUDE_DIRECTORIES "@CMAKE_OBJC_IMPLICIT_INCLUDE_DIRECTORIES@")
+set(CMAKE_OBJC_IMPLICIT_LINK_LIBRARIES "@CMAKE_OBJC_IMPLICIT_LINK_LIBRARIES@")
+set(CMAKE_OBJC_IMPLICIT_LINK_DIRECTORIES "@CMAKE_OBJC_IMPLICIT_LINK_DIRECTORIES@")
+set(CMAKE_OBJC_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_OBJC_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")

+ 20 - 0
Modules/CMakeOBJCCompilerABI.m

@@ -0,0 +1,20 @@
+#ifdef __cplusplus
+# error "A C++ compiler has been selected for Objective-C."
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+#include "CMakeCompilerABI.h"
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+  int require = 0;
+  require += info_sizeof_dptr[argc];
+#if defined(ABI_ID)
+  require += info_abi[argc];
+#endif
+  (void)argv;
+  return require;
+}

+ 63 - 0
Modules/CMakeOBJCCompilerId.m.in

@@ -0,0 +1,63 @@
+#ifdef __cplusplus
+# error "An Objective-C++ compiler has been selected for Objective-C."
+#endif
+
+@CMAKE_OBJC_COMPILER_ID_CONTENT@
+
+/* Construct the string literal in pieces to prevent the source from
+   getting matched.  Store it in a pointer rather than an array
+   because some compilers will just produce instructions to fill the
+   array rather than assigning a pointer to a static array.  */
+char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+#ifdef SIMULATE_ID
+char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
+#endif
+
+#ifdef __QNXNTO__
+char const* qnxnto = "INFO" ":" "qnxnto[]";
+#endif
+
+@CMAKE_OBJC_COMPILER_ID_PLATFORM_CONTENT@
+@CMAKE_OBJC_COMPILER_ID_ERROR_FOR_TEST@
+
+#if !defined(__STDC__)
+# if (defined(_MSC_VER) && !defined(__clang__)) \
+  || (defined(__ibmxl__) || defined(__IBMC__))
+#  define C_DIALECT "90"
+# else
+#  define C_DIALECT
+# endif
+#elif __STDC_VERSION__ >= 201000L
+# define C_DIALECT "11"
+#elif __STDC_VERSION__ >= 199901L
+# define C_DIALECT "99"
+#else
+# define C_DIALECT "90"
+#endif
+const char* info_language_dialect_default =
+  "INFO" ":" "dialect_default[" C_DIALECT "]";
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+  int require = 0;
+  require += info_compiler[argc];
+  require += info_platform[argc];
+  require += info_arch[argc];
+#ifdef COMPILER_VERSION_MAJOR
+  require += info_version[argc];
+#endif
+#ifdef COMPILER_VERSION_INTERNAL
+  require += info_version_internal[argc];
+#endif
+#ifdef SIMULATE_ID
+  require += info_simulate[argc];
+#endif
+#ifdef SIMULATE_VERSION_MAJOR
+  require += info_simulate_version[argc];
+#endif
+  require += info_language_dialect_default[argc];
+  (void)argv;
+  return require;
+}

+ 188 - 0
Modules/CMakeOBJCInformation.cmake

@@ -0,0 +1,188 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# This file sets the basic flags for the Objective-C language in CMake.
+# It also loads the available platform file for the system-compiler
+# if it exists.
+# It also loads a system - compiler - processor (or target hardware)
+# specific file, which is mainly useful for crosscompiling and embedded systems.
+
+include(CMakeLanguageInformation)
+
+# some compilers use different extensions (e.g. sdcc uses .rel)
+# so set the extension here first so it can be overridden by the compiler specific file
+set(CMAKE_OBJC_OUTPUT_EXTENSION .o)
+
+if(NOT CMAKE_INCLUDE_FLAG_OBJC)
+  set(CMAKE_INCLUDE_FLAG_OBJC ${CMAKE_INCLUDE_FLAG_C})
+endif()
+
+set(_INCLUDED_FILE 0)
+
+# Load compiler-specific information.
+if(CMAKE_OBJC_COMPILER_ID)
+  include(Compiler/${CMAKE_OBJC_COMPILER_ID}-OBJC OPTIONAL)
+endif()
+
+set(CMAKE_BASE_NAME)
+get_filename_component(CMAKE_BASE_NAME "${CMAKE_OBJC_COMPILER}" NAME_WE)
+if(CMAKE_COMPILER_IS_GNUOBJC)
+  set(CMAKE_BASE_NAME gcc)
+endif()
+
+
+# load a hardware specific file, mostly useful for embedded compilers
+if(CMAKE_SYSTEM_PROCESSOR)
+  if(CMAKE_OBJC_COMPILER_ID)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_OBJC_COMPILER_ID}-OBJC-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+  endif()
+  if (NOT _INCLUDED_FILE)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+  endif ()
+endif()
+
+
+# load the system- and compiler specific files
+if(CMAKE_OBJC_COMPILER_ID)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_OBJC_COMPILER_ID}-OBJC
+    OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+endif()
+if (NOT _INCLUDED_FILE)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}
+    OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+endif ()
+
+# load any compiler-wrapper specific information
+if (CMAKE_OBJC_COMPILER_WRAPPER)
+  __cmake_include_compiler_wrapper(OBJC)
+endif ()
+
+# We specify the compiler information in the system file for some
+# platforms, but this language may not have been enabled when the file
+# was first included.  Include it again to get the language info.
+# Remove this when all compiler info is removed from system files.
+if (NOT _INCLUDED_FILE)
+  include(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
+endif ()
+
+if(CMAKE_OBJC_SIZEOF_DATA_PTR)
+  foreach(f ${CMAKE_OBJC_ABI_FILES})
+    include(${f})
+  endforeach()
+  unset(CMAKE_OBJC_ABI_FILES)
+endif()
+
+# This should be included before the _INIT variables are
+# used to initialize the cache.  Since the rule variables
+# have if blocks on them, users can still define them here.
+# But, it should still be after the platform file so changes can
+# be made to those values.
+
+if(CMAKE_USER_MAKE_RULES_OVERRIDE)
+  # Save the full path of the file so try_compile can use it.
+  include(${CMAKE_USER_MAKE_RULES_OVERRIDE} RESULT_VARIABLE _override)
+  set(CMAKE_USER_MAKE_RULES_OVERRIDE "${_override}")
+endif()
+
+if(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC)
+  # Save the full path of the file so try_compile can use it.
+  include(${CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC} RESULT_VARIABLE _override)
+  set(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJC "${_override}")
+endif()
+
+
+# for most systems a module is the same as a shared library
+# so unless the variable CMAKE_MODULE_EXISTS is set just
+# copy the values from the LIBRARY variables
+if(NOT CMAKE_MODULE_EXISTS)
+  set(CMAKE_SHARED_MODULE_OBJC_FLAGS ${CMAKE_SHARED_LIBRARY_OBJC_FLAGS})
+  set(CMAKE_SHARED_MODULE_CREATE_OBJC_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_OBJC_FLAGS})
+endif()
+
+set(CMAKE_OBJC_FLAGS_INIT "$ENV{OBJCFLAGS} ${CMAKE_OBJC_FLAGS_INIT}")
+
+cmake_initialize_per_config_variable(CMAKE_OBJC_FLAGS "Flags used by the Objective-C compiler")
+
+if(CMAKE_OBJC_STANDARD_LIBRARIES_INIT)
+  set(CMAKE_OBJC_STANDARD_LIBRARIES "${CMAKE_OBJC_STANDARD_LIBRARIES_INIT}"
+    CACHE STRING "Libraries linked by default with all Objective-C applications.")
+  mark_as_advanced(CMAKE_OBJC_STANDARD_LIBRARIES)
+endif()
+
+include(CMakeCommonLanguageInclude)
+
+# now define the following rule variables
+
+# CMAKE_OBJC_CREATE_SHARED_LIBRARY
+# CMAKE_OBJC_CREATE_SHARED_MODULE
+# CMAKE_OBJC_COMPILE_OBJECT
+# CMAKE_OBJC_LINK_EXECUTABLE
+
+# variables supplied by the generator at use time
+# <TARGET>
+# <TARGET_BASE> the target without the suffix
+# <OBJECTS>
+# <OBJECT>
+# <LINK_LIBRARIES>
+# <FLAGS>
+# <LINK_FLAGS>
+
+# Objective-C compiler information
+# <CMAKE_OBJC_COMPILER>
+# <CMAKE_SHARED_LIBRARY_CREATE_OBJC_FLAGS>
+# <CMAKE_SHARED_MODULE_CREATE_OBJC_FLAGS>
+# <CMAKE_OBJC_LINK_FLAGS>
+
+# Static library tools
+# <CMAKE_AR>
+# <CMAKE_RANLIB>
+
+
+# create an Objective-C shared library
+if(NOT CMAKE_OBJC_CREATE_SHARED_LIBRARY)
+  set(CMAKE_OBJC_CREATE_SHARED_LIBRARY
+      "<CMAKE_OBJC_COMPILER> <CMAKE_SHARED_LIBRARY_OBJC_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_OBJC_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+endif()
+
+# create an Objective-C shared module just copy the shared library rule
+if(NOT CMAKE_OBJC_CREATE_SHARED_MODULE)
+  set(CMAKE_OBJC_CREATE_SHARED_MODULE ${CMAKE_OBJC_CREATE_SHARED_LIBRARY})
+endif()
+
+# Create an static archive incrementally for large object file counts.
+# If CMAKE_OBJC_CREATE_STATIC_LIBRARY is set it will override these.
+if(NOT DEFINED CMAKE_OBJC_ARCHIVE_CREATE)
+  set(CMAKE_OBJC_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
+endif()
+if(NOT DEFINED CMAKE_OBJC_ARCHIVE_APPEND)
+  set(CMAKE_OBJC_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+endif()
+if(NOT DEFINED CMAKE_OBJC_ARCHIVE_FINISH)
+  set(CMAKE_OBJC_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
+endif()
+
+# compile an Objective-C file into an object file
+if(NOT CMAKE_OBJC_COMPILE_OBJECT)
+  set(CMAKE_OBJC_COMPILE_OBJECT
+    "<CMAKE_OBJC_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT>   -c <SOURCE>")
+endif()
+
+if(NOT CMAKE_OBJC_LINK_EXECUTABLE)
+  set(CMAKE_OBJC_LINK_EXECUTABLE
+    "<CMAKE_OBJC_COMPILER> <FLAGS> <CMAKE_OBJC_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+endif()
+
+if(NOT CMAKE_EXECUTABLE_RUNTIME_OBJC_FLAG)
+  set(CMAKE_EXECUTABLE_RUNTIME_OBJC_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_OBJC_FLAG})
+endif()
+
+if(NOT CMAKE_EXECUTABLE_RUNTIME_OBJC_FLAG_SEP)
+  set(CMAKE_EXECUTABLE_RUNTIME_OBJC_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_OBJC_FLAG_SEP})
+endif()
+
+if(NOT CMAKE_EXECUTABLE_RPATH_LINK_OBJC_FLAG)
+  set(CMAKE_EXECUTABLE_RPATH_LINK_OBJC_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_OBJC_FLAG})
+endif()
+
+set(CMAKE_OBJC_INFORMATION_LOADED 1)

+ 79 - 0
Modules/CMakeOBJCXXCompiler.cmake.in

@@ -0,0 +1,79 @@
+set(CMAKE_OBJCXX_COMPILER "@CMAKE_OBJCXX_COMPILER@")
+set(CMAKE_OBJCXX_COMPILER_ARG1 "@CMAKE_OBJCXX_COMPILER_ARG1@")
+set(CMAKE_OBJCXX_COMPILER_ID "@CMAKE_OBJCXX_COMPILER_ID@")
+set(CMAKE_OBJCXX_COMPILER_VERSION "@CMAKE_OBJCXX_COMPILER_VERSION@")
+set(CMAKE_OBJCXX_COMPILER_VERSION_INTERNAL "@CMAKE_OBJCXX_COMPILER_VERSION_INTERNAL@")
+set(CMAKE_OBJCXX_COMPILER_WRAPPER "@CMAKE_OBJCXX_COMPILER_WRAPPER@")
+set(CMAKE_OBJCXX_STANDARD_COMPUTED_DEFAULT "@CMAKE_OBJCXX_STANDARD_COMPUTED_DEFAULT@")
+set(CMAKE_OBJCXX_COMPILE_FEATURES "@CMAKE_OBJCXX_COMPILE_FEATURES@")
+set(CMAKE_OBJCXX98_COMPILE_FEATURES "@CMAKE_OBJCXX98_COMPILE_FEATURES@")
+set(CMAKE_OBJCXX11_COMPILE_FEATURES "@CMAKE_OBJCXX11_COMPILE_FEATURES@")
+set(CMAKE_OBJCXX14_COMPILE_FEATURES "@CMAKE_OBJCXX14_COMPILE_FEATURES@")
+set(CMAKE_OBJCXX17_COMPILE_FEATURES "@CMAKE_OBJCXX17_COMPILE_FEATURES@")
+set(CMAKE_OBJCXX20_COMPILE_FEATURES "@CMAKE_OBJCXX20_COMPILE_FEATURES@")
+
+set(CMAKE_OBJCXX_PLATFORM_ID "@CMAKE_OBJCXX_PLATFORM_ID@")
+set(CMAKE_OBJCXX_SIMULATE_ID "@CMAKE_OBJCXX_SIMULATE_ID@")
+set(CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT "@CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT@")
+set(CMAKE_OBJCXX_SIMULATE_VERSION "@CMAKE_OBJCXX_SIMULATE_VERSION@")
+@_SET_CMAKE_OBJCXX_COMPILER_ARCHITECTURE_ID@
+@SET_CMAKE_XCODE_ARCHS@
+set(CMAKE_AR "@CMAKE_AR@")
+set(CMAKE_OBJCXX_COMPILER_AR "@CMAKE_OBJCXX_COMPILER_AR@")
+set(CMAKE_RANLIB "@CMAKE_RANLIB@")
+set(CMAKE_OBJCXX_COMPILER_RANLIB "@CMAKE_OBJCXX_COMPILER_RANLIB@")
+set(CMAKE_LINKER "@CMAKE_LINKER@")
+set(CMAKE_MT "@CMAKE_MT@")
+set(CMAKE_COMPILER_IS_GNUOBJCXX @CMAKE_COMPILER_IS_GNUOBJCXX@)
+set(CMAKE_OBJCXX_COMPILER_LOADED 1)
+set(CMAKE_OBJCXX_COMPILER_WORKS @CMAKE_OBJCXX_COMPILER_WORKS@)
+set(CMAKE_OBJCXX_ABI_COMPILED @CMAKE_OBJCXX_ABI_COMPILED@)
+
+set(CMAKE_OBJCXX_COMPILER_ENV_VAR "OBJCXX")
+
+set(CMAKE_OBJCXX_COMPILER_ID_RUN 1)
+set(CMAKE_OBJCXX_SOURCE_FILE_EXTENSIONS M;m;mm)
+set(CMAKE_OBJCXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O)
+
+if (CMAKE_OBJC_COMPILER_ID_RUN)
+  foreach(extension IN LISTS CMAKE_OBJC_SOURCE_FILE_EXTENSIONS)
+    list(REMOVE_ITEM CMAKE_OBJCXX_SOURCE_FILE_EXTENSIONS ${extension})
+  endforeach()
+endif()
+
+foreach (lang C CXX OBJC)
+  foreach(extension IN LISTS CMAKE_OBJCXX_SOURCE_FILE_EXTENSIONS)
+    if (CMAKE_${lang}_COMPILER_ID_RUN)
+      list(REMOVE_ITEM CMAKE_${lang}_SOURCE_FILE_EXTENSIONS ${extension})
+    endif()
+  endforeach()
+endforeach()
+
+set(CMAKE_OBJCXX_LINKER_PREFERENCE 25)
+set(CMAKE_OBJCXX_LINKER_PREFERENCE_PROPAGATES 1)
+
+# Save compiler ABI information.
+set(CMAKE_OBJCXX_SIZEOF_DATA_PTR "@CMAKE_OBJCXX_SIZEOF_DATA_PTR@")
+set(CMAKE_OBJCXX_COMPILER_ABI "@CMAKE_OBJCXX_COMPILER_ABI@")
+set(CMAKE_OBJCXX_LIBRARY_ARCHITECTURE "@CMAKE_OBJCXX_LIBRARY_ARCHITECTURE@")
+
+if(CMAKE_OBJCXX_SIZEOF_DATA_PTR)
+  set(CMAKE_SIZEOF_VOID_P "${CMAKE_OBJCXX_SIZEOF_DATA_PTR}")
+endif()
+
+if(CMAKE_OBJCXX_COMPILER_ABI)
+  set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_OBJCXX_COMPILER_ABI}")
+endif()
+
+if(CMAKE_OBJCXX_LIBRARY_ARCHITECTURE)
+  set(CMAKE_LIBRARY_ARCHITECTURE "@CMAKE_OBJCXX_LIBRARY_ARCHITECTURE@")
+endif()
+
+@CMAKE_OBJCXX_COMPILER_CUSTOM_CODE@
+@CMAKE_OBJCXX_SYSROOT_FLAG_CODE@
+@CMAKE_OBJCXX_OSX_DEPLOYMENT_TARGET_FLAG_CODE@
+
+set(CMAKE_OBJCXX_IMPLICIT_INCLUDE_DIRECTORIES "@CMAKE_OBJCXX_IMPLICIT_INCLUDE_DIRECTORIES@")
+set(CMAKE_OBJCXX_IMPLICIT_LINK_LIBRARIES "@CMAKE_OBJCXX_IMPLICIT_LINK_LIBRARIES@")
+set(CMAKE_OBJCXX_IMPLICIT_LINK_DIRECTORIES "@CMAKE_OBJCXX_IMPLICIT_LINK_DIRECTORIES@")
+set(CMAKE_OBJCXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "@CMAKE_OBJCXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES@")

+ 20 - 0
Modules/CMakeOBJCXXCompilerABI.mm

@@ -0,0 +1,20 @@
+#ifndef __cplusplus
+# error "A C compiler has been selected for Objective-C++."
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+#include "CMakeCompilerABI.h"
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char *argv[])
+{
+  int require = 0;
+  require += info_sizeof_dptr[argc];
+#if defined(ABI_ID)
+  require += info_abi[argc];
+#endif
+  (void)argv;
+  return require;
+}

+ 68 - 0
Modules/CMakeOBJCXXCompilerId.mm.in

@@ -0,0 +1,68 @@
+/* This source file must have a .cpp extension so that all C++ compilers
+   recognize the extension without flags.  Borland does not know .cxx for
+   example.  */
+#ifndef __cplusplus
+# error "An Objective-C compiler has been selected for Objective-C++."
+#endif
+
+@CMAKE_OBJCXX_COMPILER_ID_CONTENT@
+
+/* Construct the string literal in pieces to prevent the source from
+   getting matched.  Store it in a pointer rather than an array
+   because some compilers will just produce instructions to fill the
+   array rather than assigning a pointer to a static array.  */
+char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
+#ifdef SIMULATE_ID
+char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
+#endif
+
+#ifdef __QNXNTO__
+char const* qnxnto = "INFO" ":" "qnxnto[]";
+#endif
+
+@CMAKE_OBJCXX_COMPILER_ID_PLATFORM_CONTENT@
+@CMAKE_OBJCXX_COMPILER_ID_ERROR_FOR_TEST@
+
+#if defined(_MSC_VER) && defined(_MSVC_LANG)
+#define CXX_STD _MSVC_LANG
+#else
+#define CXX_STD __cplusplus
+#endif
+
+const char* info_language_dialect_default = "INFO" ":" "dialect_default["
+#if CXX_STD > 201703L
+  "20"
+#elif CXX_STD >= 201703L
+  "17"
+#elif CXX_STD >= 201402L
+  "14"
+#elif CXX_STD >= 201103L
+  "11"
+#else
+  "98"
+#endif
+"]";
+
+/*--------------------------------------------------------------------------*/
+
+int main(int argc, char* argv[])
+{
+  int require = 0;
+  require += info_compiler[argc];
+  require += info_platform[argc];
+#ifdef COMPILER_VERSION_MAJOR
+  require += info_version[argc];
+#endif
+#ifdef COMPILER_VERSION_INTERNAL
+  require += info_version_internal[argc];
+#endif
+#ifdef SIMULATE_ID
+  require += info_simulate[argc];
+#endif
+#ifdef SIMULATE_VERSION_MAJOR
+  require += info_simulate_version[argc];
+#endif
+  require += info_language_dialect_default[argc];
+  (void)argv;
+  return require;
+}

+ 273 - 0
Modules/CMakeOBJCXXInformation.cmake

@@ -0,0 +1,273 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+# This file sets the basic flags for the Objective-C++ language in CMake.
+# It also loads the available platform file for the system-compiler
+# if it exists.
+# It also loads a system - compiler - processor (or target hardware)
+# specific file, which is mainly useful for crosscompiling and embedded systems.
+
+include(CMakeLanguageInformation)
+
+# some compilers use different extensions (e.g. sdcc uses .rel)
+# so set the extension here first so it can be overridden by the compiler specific file
+set(CMAKE_OBJCXX_OUTPUT_EXTENSION .o)
+
+set(_INCLUDED_FILE 0)
+
+# Load compiler-specific information.
+if(CMAKE_OBJCXX_COMPILER_ID)
+  include(Compiler/${CMAKE_OBJCXX_COMPILER_ID}-OBJCXX OPTIONAL)
+endif()
+
+set(CMAKE_BASE_NAME)
+get_filename_component(CMAKE_BASE_NAME "${CMAKE_OBJCXX_COMPILER}" NAME_WE)
+# since the gnu compiler has several names force g++
+if(CMAKE_COMPILER_IS_GNUOBJCXX)
+  set(CMAKE_BASE_NAME g++)
+endif()
+
+
+# load a hardware specific file, mostly useful for embedded compilers
+if(CMAKE_SYSTEM_PROCESSOR)
+  if(CMAKE_OBJCXX_COMPILER_ID)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_OBJCXX_COMPILER_ID}-OBJCXX-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+  endif()
+  if (NOT _INCLUDED_FILE)
+    include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME}-${CMAKE_SYSTEM_PROCESSOR} OPTIONAL)
+  endif ()
+endif()
+
+# load the system- and compiler specific files
+if(CMAKE_OBJCXX_COMPILER_ID)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_OBJCXX_COMPILER_ID}-OBJCXX OPTIONAL RESULT_VARIABLE _INCLUDED_FILE)
+endif()
+if (NOT _INCLUDED_FILE)
+  include(Platform/${CMAKE_EFFECTIVE_SYSTEM_NAME}-${CMAKE_BASE_NAME} OPTIONAL
+          RESULT_VARIABLE _INCLUDED_FILE)
+endif ()
+
+# load any compiler-wrapper specific information
+if (CMAKE_OBJCXX_COMPILER_WRAPPER)
+  __cmake_include_compiler_wrapper(OBJCXX)
+endif ()
+
+# We specify the compiler information in the system file for some
+# platforms, but this language may not have been enabled when the file
+# was first included.  Include it again to get the language info.
+# Remove this when all compiler info is removed from system files.
+if (NOT _INCLUDED_FILE)
+  include(Platform/${CMAKE_SYSTEM_NAME} OPTIONAL)
+endif ()
+
+if(CMAKE_OBJCXX_SIZEOF_DATA_PTR)
+  foreach(f ${CMAKE_OBJCXX_ABI_FILES})
+    include(${f})
+  endforeach()
+  unset(CMAKE_OBJCXX_ABI_FILES)
+endif()
+
+# This should be included before the _INIT variables are
+# used to initialize the cache.  Since the rule variables
+# have if blocks on them, users can still define them here.
+# But, it should still be after the platform file so changes can
+# be made to those values.
+
+if(CMAKE_USER_MAKE_RULES_OVERRIDE)
+  # Save the full path of the file so try_compile can use it.
+  include(${CMAKE_USER_MAKE_RULES_OVERRIDE} RESULT_VARIABLE _override)
+  set(CMAKE_USER_MAKE_RULES_OVERRIDE "${_override}")
+endif()
+
+if(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJCXX)
+  # Save the full path of the file so try_compile can use it.
+  include(${CMAKE_USER_MAKE_RULES_OVERRIDE_OBJCXX} RESULT_VARIABLE _override)
+  set(CMAKE_USER_MAKE_RULES_OVERRIDE_OBJCXX "${_override}")
+endif()
+
+
+# Create a set of shared library variable specific to Objective-C++
+# For 90% of the systems, these are the same flags as the Objective-C versions
+# so if these are not set just copy the flags from the Objective-C version
+if(NOT CMAKE_SHARED_LIBRARY_CREATE_OBJCXX_FLAGS)
+  set(CMAKE_SHARED_LIBRARY_CREATE_OBJCXX_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_OBJC_FLAGS})
+endif()
+
+if(NOT CMAKE_OBJCXX_COMPILE_OPTIONS_PIC)
+  set(CMAKE_OBJCXX_COMPILE_OPTIONS_PIC ${CMAKE_OBJC_COMPILE_OPTIONS_PIC})
+endif()
+
+if(NOT CMAKE_OBJCXX_COMPILE_OPTIONS_PIE)
+  set(CMAKE_OBJCXX_COMPILE_OPTIONS_PIE ${CMAKE_OBJC_COMPILE_OPTIONS_PIE})
+endif()
+if(NOT CMAKE_OBJCXX_LINK_OPTIONS_PIE)
+  set(CMAKE_OBJCXX_LINK_OPTIONS_PIE ${CMAKE_OBJC_LINK_OPTIONS_PIE})
+endif()
+if(NOT CMAKE_OBJCXX_LINK_OPTIONS_NO_PIE)
+  set(CMAKE_OBJCXX_LINK_OPTIONS_NO_PIE ${CMAKE_OBJC_LINK_OPTIONS_NO_PIE})
+endif()
+
+if(NOT CMAKE_OBJCXX_COMPILE_OPTIONS_DLL)
+  set(CMAKE_OBJCXX_COMPILE_OPTIONS_DLL ${CMAKE_OBJC_COMPILE_OPTIONS_DLL})
+endif()
+
+if(NOT CMAKE_SHARED_LIBRARY_OBJCXX_FLAGS)
+  set(CMAKE_SHARED_LIBRARY_OBJCXX_FLAGS ${CMAKE_SHARED_LIBRARY_OBJC_FLAGS})
+endif()
+
+if(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_OBJCXX_FLAGS)
+  set(CMAKE_SHARED_LIBRARY_LINK_OBJCXX_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_OBJC_FLAGS})
+endif()
+
+if(NOT CMAKE_SHARED_LIBRARY_RUNTIME_OBJCXX_FLAG)
+  set(CMAKE_SHARED_LIBRARY_RUNTIME_OBJCXX_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_OBJC_FLAG})
+endif()
+
+if(NOT CMAKE_SHARED_LIBRARY_RUNTIME_OBJCXX_FLAG_SEP)
+  set(CMAKE_SHARED_LIBRARY_RUNTIME_OBJCXX_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_OBJC_FLAG_SEP})
+endif()
+
+if(NOT CMAKE_SHARED_LIBRARY_RPATH_LINK_OBJCXX_FLAG)
+  set(CMAKE_SHARED_LIBRARY_RPATH_LINK_OBJCXX_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_OBJC_FLAG})
+endif()
+
+if(NOT DEFINED CMAKE_EXE_EXPORTS_OBJCXX_FLAG)
+  set(CMAKE_EXE_EXPORTS_OBJCXX_FLAG ${CMAKE_EXE_EXPORTS_OBJC_FLAG})
+endif()
+
+if(NOT DEFINED CMAKE_SHARED_LIBRARY_SONAME_OBJCXX_FLAG)
+  set(CMAKE_SHARED_LIBRARY_SONAME_OBJCXX_FLAG ${CMAKE_SHARED_LIBRARY_SONAME_OBJC_FLAG})
+endif()
+
+if(NOT CMAKE_EXECUTABLE_RUNTIME_OBJCXX_FLAG)
+  set(CMAKE_EXECUTABLE_RUNTIME_OBJCXX_FLAG ${CMAKE_SHARED_LIBRARY_RUNTIME_OBJCXX_FLAG})
+endif()
+
+if(NOT CMAKE_EXECUTABLE_RUNTIME_OBJCXX_FLAG_SEP)
+  set(CMAKE_EXECUTABLE_RUNTIME_OBJCXX_FLAG_SEP ${CMAKE_SHARED_LIBRARY_RUNTIME_OBJCXX_FLAG_SEP})
+endif()
+
+if(NOT CMAKE_EXECUTABLE_RPATH_LINK_OBJCXX_FLAG)
+  set(CMAKE_EXECUTABLE_RPATH_LINK_OBJCXX_FLAG ${CMAKE_SHARED_LIBRARY_RPATH_LINK_OBJCXX_FLAG})
+endif()
+
+if(NOT DEFINED CMAKE_SHARED_LIBRARY_LINK_OBJCXX_WITH_RUNTIME_PATH)
+  set(CMAKE_SHARED_LIBRARY_LINK_OBJCXX_WITH_RUNTIME_PATH ${CMAKE_SHARED_LIBRARY_LINK_OBJC_WITH_RUNTIME_PATH})
+endif()
+
+if(NOT CMAKE_INCLUDE_FLAG_OBJCXX)
+  set(CMAKE_INCLUDE_FLAG_OBJCXX ${CMAKE_INCLUDE_FLAG_C})
+endif()
+
+# for most systems a module is the same as a shared library
+# so unless the variable CMAKE_MODULE_EXISTS is set just
+# copy the values from the LIBRARY variables
+if(NOT CMAKE_MODULE_EXISTS)
+  set(CMAKE_SHARED_MODULE_OBJCXX_FLAGS ${CMAKE_SHARED_LIBRARY_OBJCXX_FLAGS})
+  set(CMAKE_SHARED_MODULE_CREATE_OBJCXX_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_OBJCXX_FLAGS})
+endif()
+
+# repeat for modules
+if(NOT CMAKE_SHARED_MODULE_CREATE_OBJCXX_FLAGS)
+  set(CMAKE_SHARED_MODULE_CREATE_OBJCXX_FLAGS ${CMAKE_SHARED_MODULE_CREATE_OBJC_FLAGS})
+endif()
+
+if(NOT CMAKE_SHARED_MODULE_OBJCXX_FLAGS)
+  set(CMAKE_SHARED_MODULE_OBJCXX_FLAGS ${CMAKE_SHARED_MODULE_OBJC_FLAGS})
+endif()
+
+# Initialize OBJCXX link type selection flags from OBJC versions.
+foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
+  if(NOT CMAKE_${type}_LINK_STATIC_OBJCXX_FLAGS)
+    set(CMAKE_${type}_LINK_STATIC_OBJCXX_FLAGS
+      ${CMAKE_${type}_LINK_STATIC_OBJC_FLAGS})
+  endif()
+  if(NOT CMAKE_${type}_LINK_DYNAMIC_OBJCXX_FLAGS)
+    set(CMAKE_${type}_LINK_DYNAMIC_OBJCXX_FLAGS
+      ${CMAKE_${type}_LINK_DYNAMIC_OBJC_FLAGS})
+  endif()
+endforeach()
+
+# add the flags to the cache based
+# on the initial values computed in the platform/*.cmake files
+# use _INIT variables so that this only happens the first time
+# and you can set these flags in the cmake cache
+set(CMAKE_OBJCXX_FLAGS_INIT "$ENV{OBJCXXFLAGS} ${CMAKE_OBJCXX_FLAGS_INIT}")
+
+cmake_initialize_per_config_variable(CMAKE_OBJCXX_FLAGS "Flags used by the Objective-C++ compiler")
+
+if(CMAKE_OBJCXX_STANDARD_LIBRARIES_INIT)
+  set(CMAKE_OBJCXX_STANDARD_LIBRARIES "${CMAKE_OBJCXX_STANDARD_LIBRARIES_INIT}"
+    CACHE STRING "Libraries linked by default with all Objective-C++ applications.")
+  mark_as_advanced(CMAKE_OBJCXX_STANDARD_LIBRARIES)
+endif()
+
+include(CMakeCommonLanguageInclude)
+
+# now define the following rules:
+# CMAKE_OBJCXX_CREATE_SHARED_LIBRARY
+# CMAKE_OBJCXX_CREATE_SHARED_MODULE
+# CMAKE_OBJCXX_COMPILE_OBJECT
+# CMAKE_OBJCXX_LINK_EXECUTABLE
+
+# variables supplied by the generator at use time
+# <TARGET>
+# <TARGET_BASE> the target without the suffix
+# <OBJECTS>
+# <OBJECT>
+# <LINK_LIBRARIES>
+# <FLAGS>
+# <LINK_FLAGS>
+
+# Objective-C++ compiler information
+# <CMAKE_OBJCXX_COMPILER>
+# <CMAKE_SHARED_LIBRARY_CREATE_OBJCXX_FLAGS>
+# <CMAKE_OBJCXX_SHARED_MODULE_CREATE_FLAGS>
+# <CMAKE_OBJCXX_LINK_FLAGS>
+
+# Static library tools
+# <CMAKE_AR>
+# <CMAKE_RANLIB>
+
+
+# create a shared Objective-C++ library
+if(NOT CMAKE_OBJCXX_CREATE_SHARED_LIBRARY)
+  set(CMAKE_OBJCXX_CREATE_SHARED_LIBRARY
+      "<CMAKE_OBJCXX_COMPILER> <CMAKE_SHARED_LIBRARY_OBJCXX_FLAGS> <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_OBJCXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")
+endif()
+
+# create an Objective-C++ shared module copy the shared library rule by default
+if(NOT CMAKE_OBJCXX_CREATE_SHARED_MODULE)
+  set(CMAKE_OBJCXX_CREATE_SHARED_MODULE ${CMAKE_OBJCXX_CREATE_SHARED_LIBRARY})
+endif()
+
+
+# Create a static archive incrementally for large object file counts.
+# If CMAKE_OBJCXX_CREATE_STATIC_LIBRARY is set it will override these.
+if(NOT DEFINED CMAKE_OBJCXX_ARCHIVE_CREATE)
+  set(CMAKE_OBJCXX_ARCHIVE_CREATE "<CMAKE_AR> qc <TARGET> <LINK_FLAGS> <OBJECTS>")
+endif()
+if(NOT DEFINED CMAKE_OBJCXX_ARCHIVE_APPEND)
+  set(CMAKE_OBJCXX_ARCHIVE_APPEND "<CMAKE_AR> q  <TARGET> <LINK_FLAGS> <OBJECTS>")
+endif()
+if(NOT DEFINED CMAKE_OBJCXX_ARCHIVE_FINISH)
+  set(CMAKE_OBJCXX_ARCHIVE_FINISH "<CMAKE_RANLIB> <TARGET>")
+endif()
+
+# compile an Objective-C++ file into an object file
+if(NOT CMAKE_OBJCXX_COMPILE_OBJECT)
+  set(CMAKE_OBJCXX_COMPILE_OBJECT
+    "<CMAKE_OBJCXX_COMPILER>  <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE>")
+endif()
+
+if(NOT CMAKE_OBJCXX_LINK_EXECUTABLE)
+  set(CMAKE_OBJCXX_LINK_EXECUTABLE
+    "<CMAKE_OBJCXX_COMPILER>  <FLAGS> <CMAKE_OBJCXX_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")
+endif()
+
+mark_as_advanced(
+CMAKE_VERBOSE_MAKEFILE
+)
+
+set(CMAKE_OBJCXX_INFORMATION_LOADED 1)

+ 94 - 0
Modules/CMakeTestOBJCCompiler.cmake

@@ -0,0 +1,94 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+if(CMAKE_OBJC_COMPILER_FORCED)
+  # The compiler configuration was forced by the user.
+  # Assume the user has configured all compiler information.
+  set(CMAKE_OBJC_COMPILER_WORKS TRUE)
+  return()
+endif()
+
+include(CMakeTestCompilerCommon)
+
+# work around enforced code signing and / or missing exectuable target type
+set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
+if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
+  set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
+endif()
+
+# Remove any cached result from an older CMake version.
+# We now store this in CMakeCCompiler.cmake.
+unset(CMAKE_OBJC_COMPILER_WORKS CACHE)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that that selected Objective-C compiler can actually compile
+# and link the most basic of programs.   If not, a fatal error
+# is set and cmake stops processing commands and will not generate
+# any makefiles or projects.
+if(NOT CMAKE_OBJC_COMPILER_WORKS)
+  PrintTestCompilerStatus("OBJC" "")
+  __TestCompiler_setTryCompileTargetType()
+  file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCCompiler.m
+    "#ifdef __cplusplus\n"
+    "# error \"The CMAKE_OBJC_COMPILER is set to a C++ compiler\"\n"
+    "#endif\n"
+    "#ifndef __OBJC__\n"
+    "# error \"The CMAKE_OBJC_COMPILER is not an Objective-C compiler\"\n"
+    "#endif\n"
+    "int main(int argc, char* argv[])\n"
+    "{ (void)argv; return argc-1;}\n")
+  try_compile(CMAKE_OBJC_COMPILER_WORKS ${CMAKE_BINARY_DIR}
+    ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCCompiler.m
+    OUTPUT_VARIABLE __CMAKE_OBJC_COMPILER_OUTPUT)
+  # Move result from cache to normal variable.
+  set(CMAKE_OBJC_COMPILER_WORKS ${CMAKE_OBJC_COMPILER_WORKS})
+  unset(CMAKE_OBJC_COMPILER_WORKS CACHE)
+  set(OBJC_TEST_WAS_RUN 1)
+  __TestCompiler_restoreTryCompileTargetType()
+endif()
+
+if(NOT CMAKE_OBJC_COMPILER_WORKS)
+  PrintTestCompilerStatus("OBJC" " -- broken")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Determining if the Objective-C compiler works failed with "
+    "the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
+  string(REPLACE "\n" "\n  " _output "${__CMAKE_OBJC_COMPILER_OUTPUT}")
+  message(FATAL_ERROR "The Objective-C compiler\n  \"${CMAKE_OBJC_COMPILER}\"\n"
+    "is not able to compile a simple test program.\nIt fails "
+    "with the following output:\n  ${_output}\n\n"
+    "CMake will not be able to correctly generate this project.")
+else()
+  if(OBJC_TEST_WAS_RUN)
+    PrintTestCompilerStatus("OBJC" " -- works")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "Determining if the Objective-C compiler works passed with "
+      "the following output:\n${__CMAKE_OBJC_COMPILER_OUTPUT}\n\n")
+  endif()
+
+  # Try to identify the ABI and configure it into CMakeOBJCCompiler.cmake
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+  CMAKE_DETERMINE_COMPILER_ABI(OBJC ${CMAKE_ROOT}/Modules/CMakeOBJCCompilerABI.m)
+  # Try to identify the compiler features
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+  CMAKE_DETERMINE_COMPILE_FEATURES(OBJC)
+
+  # Re-configure to save learned information.
+  configure_file(
+    ${CMAKE_ROOT}/Modules/CMakeOBJCCompiler.cmake.in
+    ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake
+    @ONLY
+    )
+  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCCompiler.cmake)
+
+  if(CMAKE_OBJC_SIZEOF_DATA_PTR)
+    foreach(f ${CMAKE_OBJC_ABI_FILES})
+      include(${f})
+    endforeach()
+    unset(CMAKE_OBJC_ABI_FILES)
+  endif()
+endif()
+
+set(CMAKE_TRY_COMPILE_TARGET_TYPE ${__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE})
+unset(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE)
+unset(__CMAKE_OBJC_COMPILER_OUTPUT)

+ 93 - 0
Modules/CMakeTestOBJCXXCompiler.cmake

@@ -0,0 +1,93 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+
+if(CMAKE_OBJCXX_COMPILER_FORCED)
+  # The compiler configuration was forced by the user.
+  # Assume the user has configured all compiler information.
+  set(CMAKE_OBJCXX_COMPILER_WORKS TRUE)
+  return()
+endif()
+
+include(CMakeTestCompilerCommon)
+
+# work around enforced code signing and / or missing exectuable target type
+set(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE ${CMAKE_TRY_COMPILE_TARGET_TYPE})
+if(_CMAKE_FEATURE_DETECTION_TARGET_TYPE)
+  set(CMAKE_TRY_COMPILE_TARGET_TYPE ${_CMAKE_FEATURE_DETECTION_TARGET_TYPE})
+endif()
+
+# Remove any cached result from an older CMake version.
+# We now store this in CMakeOBJCXXCompiler.cmake.
+unset(CMAKE_OBJCXX_COMPILER_WORKS CACHE)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that the selected Objective-C++ compiler can actually compile
+# and link the most basic of programs.   If not, a fatal error
+# is set and cmake stops processing commands and will not generate
+# any makefiles or projects.
+if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
+  PrintTestCompilerStatus("OBJCXX" "")
+  __TestCompiler_setTryCompileTargetType()
+  file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCXXCompiler.mm
+    "#ifndef __cplusplus\n"
+    "# error \"The CMAKE_OBJCXX_COMPILER is set to a C compiler\"\n"
+    "#endif\n"
+    "#ifndef __OBJC__\n"
+    "# error \"The CMAKE_OBJCXX_COMPILER is not an Objective-C++ compiler\"\n"
+    "#endif\n"
+    "int main(){return 0;}\n")
+  try_compile(CMAKE_OBJCXX_COMPILER_WORKS ${CMAKE_BINARY_DIR}
+    ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/testOBJCXXCompiler.mm
+    OUTPUT_VARIABLE __CMAKE_OBJCXX_COMPILER_OUTPUT)
+  # Move result from cache to normal variable.
+  set(CMAKE_OBJCXX_COMPILER_WORKS ${CMAKE_OBJCXX_COMPILER_WORKS})
+  unset(CMAKE_OBJCXX_COMPILER_WORKS CACHE)
+  set(OBJCXX_TEST_WAS_RUN 1)
+  __TestCompiler_restoreTryCompileTargetType()
+endif()
+
+if(NOT CMAKE_OBJCXX_COMPILER_WORKS)
+  PrintTestCompilerStatus("OBJCXX" " -- broken")
+  file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+    "Determining if the Objective-C++ compiler works failed with "
+    "the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
+  string(REPLACE "\n" "\n  " _output "${__CMAKE_OBJCXX_COMPILER_OUTPUT}")
+  message(FATAL_ERROR "The Objective-C++ compiler\n  \"${CMAKE_OBJCXX_COMPILER}\"\n"
+    "is not able to compile a simple test program.\nIt fails "
+    "with the following output:\n  ${_output}\n\n"
+    "CMake will not be able to correctly generate this project.")
+else()
+  if(OBJCXX_TEST_WAS_RUN)
+    PrintTestCompilerStatus("OBJCXX" " -- works")
+    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+      "Determining if the Objective-C++ compiler works passed with "
+      "the following output:\n${__CMAKE_OBJCXX_COMPILER_OUTPUT}\n\n")
+  endif()
+
+  # Try to identify the ABI and configure it into CMakeOBJCXXCompiler.cmake
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerABI.cmake)
+  CMAKE_DETERMINE_COMPILER_ABI(OBJCXX ${CMAKE_ROOT}/Modules/CMakeOBJCXXCompilerABI.mm)
+  # Try to identify the compiler features
+  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompileFeatures.cmake)
+  CMAKE_DETERMINE_COMPILE_FEATURES(OBJCXX)
+
+  # Re-configure to save learned information.
+  configure_file(
+    ${CMAKE_ROOT}/Modules/CMakeOBJCXXCompiler.cmake.in
+    ${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCXXCompiler.cmake
+    @ONLY
+    )
+  include(${CMAKE_PLATFORM_INFO_DIR}/CMakeOBJCXXCompiler.cmake)
+
+  if(CMAKE_OBJCXX_SIZEOF_DATA_PTR)
+    foreach(f ${CMAKE_OBJCXX_ABI_FILES})
+      include(${f})
+    endforeach()
+    unset(CMAKE_OBJCXX_ABI_FILES)
+  endif()
+endif()
+
+set(CMAKE_TRY_COMPILE_TARGET_TYPE ${__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE})
+unset(__CMAKE_SAVED_TRY_COMPILE_TARGET_TYPE)
+unset(__CMAKE_OBJCXX_COMPILER_OUTPUT)

+ 64 - 0
Modules/CheckOBJCCompilerFlag.cmake

@@ -0,0 +1,64 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckOBJCCompilerFlag
+---------------------
+
+Check whether the Objective-C compiler supports a given flag.
+
+.. command:: check_objc_compiler_flag
+
+  .. code-block:: cmake
+
+    check_objc_compiler_flag(<flag> <var>)
+
+  Check that the ``<flag>`` is accepted by the compiler without
+  a diagnostic.  Stores the result in an internal cache entry
+  named ``<var>``.
+
+This command temporarily sets the ``CMAKE_REQUIRED_DEFINITIONS`` variable
+and calls the ``check_objc_source_compiles`` macro from the
+:module:`CheckOBJCSourceCompiles` module.  See documentation of that
+module for a listing of variables that can otherwise modify the build.
+
+A positive result from this check indicates only that the compiler did not
+issue a diagnostic message when given the flag.  Whether the flag has any
+effect or even a specific one is beyond the scope of this module.
+
+.. note::
+  Since the :command:`try_compile` command forwards flags from variables
+  like :variable:`CMAKE_OBJC_FLAGS <CMAKE_<LANG>_FLAGS>`, unknown flags
+  in such variables may cause a false negative for this check.
+#]=======================================================================]
+
+include_guard(GLOBAL)
+include(CheckOBJCSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
+
+macro (CHECK_OBJC_COMPILER_FLAG _FLAG _RESULT)
+  set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
+  set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+
+   # Normalize locale during test compilation.
+  set(_CheckOBJCCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG)
+  foreach(v ${_CheckOBJCCompilerFlag_LOCALE_VARS})
+    set(_CheckOBJCCompilerFlag_SAVED_${v} "$ENV{${v}}")
+    set(ENV{${v}} OBJC)
+  endforeach()
+  CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckOBJCCompilerFlag_COMMON_PATTERNS)
+  CHECK_OBJC_SOURCE_COMPILES("#ifndef __OBJC__\n#  error \"Not an Objective-C compiler\"\n#endif\nint main(void) { return 0; }" ${_RESULT}
+    # Some compilers do not fail with a bad flag
+    FAIL_REGEX "command line option .* is valid for .* but not for Objective-C" # GNU
+    FAIL_REGEX "argument unused during compilation: .*" # Clang
+    ${_CheckOBJCCompilerFlag_COMMON_PATTERNS}
+    )
+  foreach(v ${_CheckOBJCCompilerFlag_LOCALE_VARS})
+    set(ENV{${v}} ${_CheckOBJCCompilerFlag_SAVED_${v}})
+    unset(_CheckOBJCCompilerFlag_SAVED_${v})
+  endforeach()
+  unset(_CheckOBJCCompilerFlag_LOCALE_VARS)
+  unset(_CheckOBJCCompilerFlag_COMMON_PATTERNS)
+
+  set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
+endmacro ()

+ 145 - 0
Modules/CheckOBJCSourceCompiles.cmake

@@ -0,0 +1,145 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckOBJCSourceCompiles
+-----------------------
+
+Check if given Objective-C source compiles and links into an executable.
+
+.. command:: check_objc_source_compiles
+
+  .. code-block:: cmake
+
+    check_objc_source_compiles(<code> <resultVar>
+                               [FAIL_REGEX <regex1> [<regex2>...]])
+
+  Check that the source supplied in ``<code>`` can be compiled as a Objectie-C source
+  file and linked as an executable (so it must contain at least a ``main()``
+  function). The result will be stored in the internal cache variable specified
+  by ``<resultVar>``, with a boolean true value for success and boolean false
+  for failure. If ``FAIL_REGEX`` is provided, then failure is determined by
+  checking if anything in the output matches any of the specified regular
+  expressions.
+
+  The underlying check is performed by the :command:`try_compile` command. The
+  compile and link commands can be influenced by setting any of the following
+  variables prior to calling ``check_objc_source_compiles()``:
+
+  ``CMAKE_REQUIRED_FLAGS``
+    Additional flags to pass to the compiler. Note that the contents of
+    :variable:`CMAKE_OBJC_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated
+    configuration-specific variable are automatically added to the compiler
+    command before the contents of ``CMAKE_REQUIRED_FLAGS``.
+
+  ``CMAKE_REQUIRED_DEFINITIONS``
+    A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form
+    ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by
+    ``<resultVar>`` will also be added automatically.
+
+  ``CMAKE_REQUIRED_INCLUDES``
+    A :ref:`;-list <CMake Language Lists>` of header search paths to pass to
+    the compiler. These will be the only header search paths used by
+    ``try_compile()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES`
+    directory property will be ignored.
+
+  ``CMAKE_REQUIRED_LINK_OPTIONS``
+    A :ref:`;-list <CMake Language Lists>` of options to add to the link
+    command (see :command:`try_compile` for further details).
+
+  ``CMAKE_REQUIRED_LIBRARIES``
+    A :ref:`;-list <CMake Language Lists>` of libraries to add to the link
+    command. These can be the name of system libraries or they can be
+    :ref:`Imported Targets <Imported Targets>` (see :command:`try_compile` for
+    further details).
+
+  ``CMAKE_REQUIRED_QUIET``
+    If this variable evaluates to a boolean true value, all status messages
+    associated with the check will be suppressed.
+
+  The check is only performed once, with the result cached in the variable
+  named by ``<resultVar>``. Every subsequent CMake run will re-use this cached
+  value rather than performing the check again, even if the ``<code>`` changes.
+  In order to force the check to be re-evaluated, the variable named by
+  ``<resultVar>`` must be manually removed from the cache.
+
+#]=======================================================================]
+
+include_guard(GLOBAL)
+
+macro(CHECK_OBJC_SOURCE_COMPILES SOURCE VAR)
+  if(NOT DEFINED "${VAR}")
+    set(_FAIL_REGEX)
+    set(_key)
+    foreach(arg ${ARGN})
+      if("${arg}" MATCHES "^(FAIL_REGEX)$")
+        set(_key "${arg}")
+      elseif(_key)
+        list(APPEND _${_key} "${arg}")
+      else()
+        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
+      endif()
+    endforeach()
+    set(MACRO_CHECK_FUNCTION_DEFINITIONS
+      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+    if(CMAKE_REQUIRED_LINK_OPTIONS)
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS
+        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
+    else()
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS)
+    endif()
+    if(CMAKE_REQUIRED_LIBRARIES)
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+    else()
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES
+        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+    else()
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.m"
+      "${SOURCE}\n")
+
+    if(NOT CMAKE_REQUIRED_QUIET)
+      message(STATUS "Performing Test ${VAR}")
+    endif()
+    try_compile(${VAR}
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.m
+      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS}
+      ${CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+      "${CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES}"
+      OUTPUT_VARIABLE OUTPUT)
+
+    foreach(_regex ${_FAIL_REGEX})
+      if("${OUTPUT}" MATCHES "${_regex}")
+        set(${VAR} 0)
+      endif()
+    endforeach()
+
+    if(${VAR})
+      set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Success")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing Objective-C SOURCE FILE Test ${VAR} succeeded with the following output:\n"
+        "${OUTPUT}\n"
+        "Source file was:\n${SOURCE}\n")
+    else()
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Failed")
+      endif()
+      set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Performing Objective-C SOURCE FILE Test ${VAR} failed with the following output:\n"
+        "${OUTPUT}\n"
+        "Source file was:\n${SOURCE}\n")
+    endif()
+  endif()
+endmacro()

+ 145 - 0
Modules/CheckOBJCSourceRuns.cmake

@@ -0,0 +1,145 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckOBJCSourceRuns
+-------------------
+
+Check if given Objective-C source compiles and links into an executable and can
+subsequently be run.
+
+.. command:: check_objc_source_runs
+
+  .. code-block:: cmake
+
+    check_objc_source_runs(<code> <resultVar>)
+
+  Check that the source supplied in ``<code>`` can be compiled as a Objective-C source
+  file, linked as an executable and then run. The ``<code>`` must contain at
+  least a ``main()`` function. If the ``<code>`` could be built and run
+  successfully, the internal cache variable specified by ``<resultVar>`` will
+  be set to 1, otherwise it will be set to an value that evaluates to boolean
+  false (e.g. an empty string or an error message).
+
+  The underlying check is performed by the :command:`try_run` command. The
+  compile and link commands can be influenced by setting any of the following
+  variables prior to calling ``check_objc_source_runs()``:
+
+  ``CMAKE_REQUIRED_FLAGS``
+    Additional flags to pass to the compiler. Note that the contents of
+    :variable:`CMAKE_OBJC_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated
+    configuration-specific variable are automatically added to the compiler
+    command before the contents of ``CMAKE_REQUIRED_FLAGS``.
+
+  ``CMAKE_REQUIRED_DEFINITIONS``
+    A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form
+    ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by
+    ``<resultVar>`` will also be added automatically.
+
+  ``CMAKE_REQUIRED_INCLUDES``
+    A :ref:`;-list <CMake Language Lists>` of header search paths to pass to
+    the compiler. These will be the only header search paths used by
+    ``try_run()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES`
+    directory property will be ignored.
+
+  ``CMAKE_REQUIRED_LINK_OPTIONS``
+    A :ref:`;-list <CMake Language Lists>` of options to add to the link
+    command (see :command:`try_run` for further details).
+
+  ``CMAKE_REQUIRED_LIBRARIES``
+    A :ref:`;-list <CMake Language Lists>` of libraries to add to the link
+    command. These can be the name of system libraries or they can be
+    :ref:`Imported Targets <Imported Targets>` (see :command:`try_run` for
+    further details).
+
+  ``CMAKE_REQUIRED_QUIET``
+    If this variable evaluates to a boolean true value, all status messages
+    associated with the check will be suppressed.
+
+  The check is only performed once, with the result cached in the variable
+  named by ``<resultVar>``. Every subsequent CMake run will re-use this cached
+  value rather than performing the check again, even if the ``<code>`` changes.
+  In order to force the check to be re-evaluated, the variable named by
+  ``<resultVar>`` must be manually removed from the cache.
+
+#]=======================================================================]
+
+include_guard(GLOBAL)
+
+macro(CHECK_OBJC_SOURCE_RUNS SOURCE VAR)
+  if(NOT DEFINED "${VAR}")
+    set(MACRO_CHECK_FUNCTION_DEFINITIONS
+      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+    if(CMAKE_REQUIRED_LINK_OPTIONS)
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS
+        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
+    else()
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS)
+    endif()
+    if(CMAKE_REQUIRED_LIBRARIES)
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+    else()
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES
+        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+    else()
+      set(CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.m"
+      "${SOURCE}\n")
+
+    if(NOT CMAKE_REQUIRED_QUIET)
+      message(STATUS "Performing Test ${VAR}")
+    endif()
+    try_run(${VAR}_EXITCODE ${VAR}_COMPILED
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.m
+      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_OBJC_SOURCE_COMPILES_ADD_LINK_OPTIONS}
+      ${CHECK_OBJC_SOURCE_COMPILES_ADD_LIBRARIES}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+      -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
+      "${CHECK_OBJC_SOURCE_COMPILES_ADD_INCLUDES}"
+      COMPILE_OUTPUT_VARIABLE OUTPUT
+      RUN_OUTPUT_VARIABLE RUN_OUTPUT)
+    # if it did not compile make the return value fail code of 1
+    if(NOT ${VAR}_COMPILED)
+      set(${VAR}_EXITCODE 1)
+    endif()
+    # if the return value was 0 then it worked
+    if("${${VAR}_EXITCODE}" EQUAL 0)
+      set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Success")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing Objective-C SOURCE FILE Test ${VAR} succeeded with the following compile output:\n"
+        "${OUTPUT}\n"
+        "...and run output:\n"
+        "${RUN_OUTPUT}\n"
+        "Return value: ${${VAR}}\n"
+        "Source file was:\n${SOURCE}\n")
+    else()
+      if(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES  "FAILED_TO_RUN")
+        set(${VAR} "${${VAR}_EXITCODE}")
+      else()
+        set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+      endif()
+
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Failed")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Performing Objective-C SOURCE FILE Test ${VAR} failed with the following compile output:\n"
+        "${OUTPUT}\n"
+        "...and run output:\n"
+        "${RUN_OUTPUT}\n"
+        "Return value: ${${VAR}_EXITCODE}\n"
+        "Source file was:\n${SOURCE}\n")
+
+    endif()
+  endif()
+endmacro()

+ 64 - 0
Modules/CheckOBJCXXCompilerFlag.cmake

@@ -0,0 +1,64 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckOBJCXXCompilerFlag
+-----------------------
+
+Check whether the Objective-C++ compiler supports a given flag.
+
+.. command:: check_objcxx_compiler_flag
+
+  .. code-block:: cmake
+
+    check_objcxx_compiler_flag(<flag> <var>)
+
+  Check that the ``<flag>`` is accepted by the compiler without
+  a diagnostic.  Stores the result in an internal cache entry
+  named ``<var>``.
+
+This command temporarily sets the ``CMAKE_REQUIRED_DEFINITIONS`` variable
+and calls the ``check_objcxx_source_compiles`` macro from the
+:module:`CheckOBJCXXSourceCompiles` module.  See documentation of that
+module for a listing of variables that can otherwise modify the build.
+
+A positive result from this check indicates only that the compiler did not
+issue a diagnostic message when given the flag.  Whether the flag has any
+effect or even a specific one is beyond the scope of this module.
+
+.. note::
+  Since the :command:`try_compile` command forwards flags from variables
+  like :variable:`CMAKE_OBJCXX_FLAGS <CMAKE_<LANG>_FLAGS>`, unknown flags
+  in such variables may cause a false negative for this check.
+#]=======================================================================]
+
+include_guard(GLOBAL)
+include(CheckOBJCXXSourceCompiles)
+include(CMakeCheckCompilerFlagCommonPatterns)
+
+macro (CHECK_OBJCXX_COMPILER_FLAG _FLAG _RESULT)
+  set(SAFE_CMAKE_REQUIRED_DEFINITIONS "${CMAKE_REQUIRED_DEFINITIONS}")
+  set(CMAKE_REQUIRED_DEFINITIONS "${_FLAG}")
+
+  # Normalize locale during test compilation.
+  set(_CheckOBJCXXCompilerFlag_LOCALE_VARS LC_ALL LC_MESSAGES LANG)
+  foreach(v ${_CheckOBJCXXCompilerFlag_LOCALE_VARS})
+    set(_CheckOBJCXXCompilerFlag_SAVED_${v} "$ENV{${v}}")
+    set(ENV{${v}} OBJCXX)
+  endforeach()
+  CHECK_COMPILER_FLAG_COMMON_PATTERNS(_CheckOBJCXXCompilerFlag_COMMON_PATTERNS)
+  CHECK_OBJCXX_SOURCE_COMPILES("#ifndef __OBJC__\n#  error \"Not an Objective-C++ compiler\"\n#endif\nint main(void) { return 0; }" ${_RESULT}
+    # Some compilers do not fail with a bad flag
+    FAIL_REGEX "command line option .* is valid for .* but not for Objective-C\\\\+\\\\+" # GNU
+    FAIL_REGEX "argument unused during compilation: .*" # Clang
+    ${_CheckOBJCXXCompilerFlag_COMMON_PATTERNS}
+    )
+  foreach(v ${_CheckOBJCXXCompilerFlag_LOCALE_VARS})
+    set(ENV{${v}} ${_CheckOBJCXXCompilerFlag_SAVED_${v}})
+    unset(_CheckOBJCXXCompilerFlag_SAVED_${v})
+  endforeach()
+  unset(_CheckOBJCXXCompilerFlag_LOCALE_VARS)
+  unset(_CheckOBJCXXCompilerFlag_COMMON_PATTERNS)
+
+  set (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
+endmacro ()

+ 146 - 0
Modules/CheckOBJCXXSourceCompiles.cmake

@@ -0,0 +1,146 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckOBJCXXSourceCompiles
+-------------------------
+
+Check if given Objective-C++ source compiles and links into an executable.
+
+.. command:: check_objcxx_source_compiles
+
+  .. code-block:: cmake
+
+    check_objcxx_source_compiles(<code> <resultVar>
+                                 [FAIL_REGEX <regex1> [<regex2>...]])
+
+  Check that the source supplied in ``<code>`` can be compiled as a Objective-C++ source
+  file and linked as an executable (so it must contain at least a ``main()``
+  function). The result will be stored in the internal cache variable specified
+  by ``<resultVar>``, with a boolean true value for success and boolean false
+  for failure. If ``FAIL_REGEX`` is provided, then failure is determined by
+  checking if anything in the output matches any of the specified regular
+  expressions.
+
+  The underlying check is performed by the :command:`try_compile` command. The
+  compile and link commands can be influenced by setting any of the following
+  variables prior to calling ``check_objcxx_source_compiles()``:
+
+  ``CMAKE_REQUIRED_FLAGS``
+    Additional flags to pass to the compiler. Note that the contents of
+    :variable:`CMAKE_OBJCXX_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated
+    configuration-specific variable are automatically added to the compiler
+    command before the contents of ``CMAKE_REQUIRED_FLAGS``.
+
+  ``CMAKE_REQUIRED_DEFINITIONS``
+    A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form
+    ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by
+    ``<resultVar>`` will also be added automatically.
+
+  ``CMAKE_REQUIRED_INCLUDES``
+    A :ref:`;-list <CMake Language Lists>` of header search paths to pass to
+    the compiler. These will be the only header search paths used by
+    ``try_compile()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES`
+    directory property will be ignored.
+
+  ``CMAKE_REQUIRED_LINK_OPTIONS``
+    A :ref:`;-list <CMake Language Lists>` of options to add to the link
+    command (see :command:`try_compile` for further details).
+
+  ``CMAKE_REQUIRED_LIBRARIES``
+    A :ref:`;-list <CMake Language Lists>` of libraries to add to the link
+    command. These can be the name of system libraries or they can be
+    :ref:`Imported Targets <Imported Targets>` (see :command:`try_compile` for
+    further details).
+
+  ``CMAKE_REQUIRED_QUIET``
+    If this variable evaluates to a boolean true value, all status messages
+    associated with the check will be suppressed.
+
+  The check is only performed once, with the result cached in the variable
+  named by ``<resultVar>``. Every subsequent CMake run will re-use this cached
+  value rather than performing the check again, even if the ``<code>`` changes.
+  In order to force the check to be re-evaluated, the variable named by
+  ``<resultVar>`` must be manually removed from the cache.
+
+#]=======================================================================]
+
+include_guard(GLOBAL)
+
+macro(CHECK_OBJCXX_SOURCE_COMPILES SOURCE VAR)
+  if(NOT DEFINED "${VAR}")
+    set(_FAIL_REGEX)
+    set(_key)
+    foreach(arg ${ARGN})
+      if("${arg}" MATCHES "^(FAIL_REGEX)$")
+        set(_key "${arg}")
+      elseif(_key)
+        list(APPEND _${_key} "${arg}")
+      else()
+        message(FATAL_ERROR "Unknown argument:\n  ${arg}\n")
+      endif()
+    endforeach()
+
+    set(MACRO_CHECK_FUNCTION_DEFINITIONS
+      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+    if(CMAKE_REQUIRED_LINK_OPTIONS)
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS
+        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
+    else()
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS)
+    endif()
+    if(CMAKE_REQUIRED_LIBRARIES)
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+    else()
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES
+        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+    else()
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm"
+      "${SOURCE}\n")
+
+    if(NOT CMAKE_REQUIRED_QUIET)
+      message(STATUS "Performing Test ${VAR}")
+    endif()
+    try_compile(${VAR}
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm
+      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS}
+      ${CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+      "${CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES}"
+      OUTPUT_VARIABLE OUTPUT)
+
+    foreach(_regex ${_FAIL_REGEX})
+      if("${OUTPUT}" MATCHES "${_regex}")
+        set(${VAR} 0)
+      endif()
+    endforeach()
+
+    if(${VAR})
+      set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Success")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing Objective-C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
+        "${OUTPUT}\n"
+        "Source file was:\n${SOURCE}\n")
+    else()
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Failed")
+      endif()
+      set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Performing Objective-C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
+        "${OUTPUT}\n"
+        "Source file was:\n${SOURCE}\n")
+    endif()
+  endif()
+endmacro()

+ 145 - 0
Modules/CheckOBJCXXSourceRuns.cmake

@@ -0,0 +1,145 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+CheckOBJCXXSourceRuns
+---------------------
+
+Check if given Objective-C++ source compiles and links into an executable and can
+subsequently be run.
+
+.. command:: check_objcxx_source_runs
+
+  .. code-block:: cmake
+
+    check_objcxx_source_runs(<code> <resultVar>)
+
+  Check that the source supplied in ``<code>`` can be compiled as a Objective-C++ source
+  file, linked as an executable and then run. The ``<code>`` must contain at
+  least a ``main()`` function. If the ``<code>`` could be built and run
+  successfully, the internal cache variable specified by ``<resultVar>`` will
+  be set to 1, otherwise it will be set to an value that evaluates to boolean
+  false (e.g. an empty string or an error message).
+
+  The underlying check is performed by the :command:`try_run` command. The
+  compile and link commands can be influenced by setting any of the following
+  variables prior to calling ``check_objcxx_source_runs()``:
+
+  ``CMAKE_REQUIRED_FLAGS``
+    Additional flags to pass to the compiler. Note that the contents of
+    :variable:`CMAKE_OBJCXX_FLAGS <CMAKE_<LANG>_FLAGS>` and its associated
+    configuration-specific variable are automatically added to the compiler
+    command before the contents of ``CMAKE_REQUIRED_FLAGS``.
+
+  ``CMAKE_REQUIRED_DEFINITIONS``
+    A :ref:`;-list <CMake Language Lists>` of compiler definitions of the form
+    ``-DFOO`` or ``-DFOO=bar``. A definition for the name specified by
+    ``<resultVar>`` will also be added automatically.
+
+  ``CMAKE_REQUIRED_INCLUDES``
+    A :ref:`;-list <CMake Language Lists>` of header search paths to pass to
+    the compiler. These will be the only header search paths used by
+    ``try_run()``, i.e. the contents of the :prop_dir:`INCLUDE_DIRECTORIES`
+    directory property will be ignored.
+
+  ``CMAKE_REQUIRED_LINK_OPTIONS``
+    A :ref:`;-list <CMake Language Lists>` of options to add to the link
+    command (see :command:`try_run` for further details).
+
+  ``CMAKE_REQUIRED_LIBRARIES``
+    A :ref:`;-list <CMake Language Lists>` of libraries to add to the link
+    command. These can be the name of system libraries or they can be
+    :ref:`Imported Targets <Imported Targets>` (see :command:`try_run` for
+    further details).
+
+  ``CMAKE_REQUIRED_QUIET``
+    If this variable evaluates to a boolean true value, all status messages
+    associated with the check will be suppressed.
+
+  The check is only performed once, with the result cached in the variable
+  named by ``<resultVar>``. Every subsequent CMake run will re-use this cached
+  value rather than performing the check again, even if the ``<code>`` changes.
+  In order to force the check to be re-evaluated, the variable named by
+  ``<resultVar>`` must be manually removed from the cache.
+
+#]=======================================================================]
+
+include_guard(GLOBAL)
+
+macro(CHECK_OBJCXX_SOURCE_RUNS SOURCE VAR)
+  if(NOT DEFINED "${VAR}")
+    set(MACRO_CHECK_FUNCTION_DEFINITIONS
+      "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
+    if(CMAKE_REQUIRED_LINK_OPTIONS)
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS
+        LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
+    else()
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS)
+    endif()
+    if(CMAKE_REQUIRED_LIBRARIES)
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES
+        LINK_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
+    else()
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES)
+    endif()
+    if(CMAKE_REQUIRED_INCLUDES)
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES
+        "-DINCLUDE_DIRECTORIES:STRING=${CMAKE_REQUIRED_INCLUDES}")
+    else()
+      set(CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES)
+    endif()
+    file(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm"
+      "${SOURCE}\n")
+
+    if(NOT CMAKE_REQUIRED_QUIET)
+      message(STATUS "Performing Test ${VAR}")
+    endif()
+    try_run(${VAR}_EXITCODE ${VAR}_COMPILED
+      ${CMAKE_BINARY_DIR}
+      ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.mm
+      COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+      ${CHECK_OBJCXX_SOURCE_COMPILES_ADD_LINK_OPTIONS}
+      ${CHECK_OBJCXX_SOURCE_COMPILES_ADD_LIBRARIES}
+      CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+      -DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
+      "${CHECK_OBJCXX_SOURCE_COMPILES_ADD_INCLUDES}"
+      COMPILE_OUTPUT_VARIABLE OUTPUT
+      RUN_OUTPUT_VARIABLE RUN_OUTPUT)
+
+    # if it did not compile make the return value fail code of 1
+    if(NOT ${VAR}_COMPILED)
+      set(${VAR}_EXITCODE 1)
+    endif()
+    # if the return value was 0 then it worked
+    if("${${VAR}_EXITCODE}" EQUAL 0)
+      set(${VAR} 1 CACHE INTERNAL "Test ${VAR}")
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Success")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Performing Objective-C++ SOURCE FILE Test ${VAR} succeeded with the following output:\n"
+        "${OUTPUT}\n"
+        "...and run output:\n"
+        "${RUN_OUTPUT}\n"
+        "Return value: ${${VAR}}\n"
+        "Source file was:\n${SOURCE}\n")
+    else()
+      if(CMAKE_CROSSCOMPILING AND "${${VAR}_EXITCODE}" MATCHES  "FAILED_TO_RUN")
+        set(${VAR} "${${VAR}_EXITCODE}")
+      else()
+        set(${VAR} "" CACHE INTERNAL "Test ${VAR}")
+      endif()
+
+      if(NOT CMAKE_REQUIRED_QUIET)
+        message(STATUS "Performing Test ${VAR} - Failed")
+      endif()
+      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Performing Objective-C++ SOURCE FILE Test ${VAR} failed with the following output:\n"
+        "${OUTPUT}\n"
+        "...and run output:\n"
+        "${RUN_OUTPUT}\n"
+        "Return value: ${${VAR}_EXITCODE}\n"
+        "Source file was:\n${SOURCE}\n")
+    endif()
+  endif()
+endmacro()

+ 17 - 0
Modules/Compiler/AppleClang-OBJC.cmake

@@ -0,0 +1,17 @@
+include(Compiler/Clang-OBJC)
+
+if(NOT CMAKE_OBJC_COMPILER_VERSION VERSION_LESS 4.0)
+  set(CMAKE_OBJC90_STANDARD_COMPILE_OPTION "-std=c90")
+  set(CMAKE_OBJC90_EXTENSION_COMPILE_OPTION "-std=gnu90")
+  set(CMAKE_OBJC90_STANDARD__HAS_FULL_SUPPORT ON)
+
+  set(CMAKE_OBJC99_STANDARD_COMPILE_OPTION "-std=c99")
+  set(CMAKE_OBJC99_EXTENSION_COMPILE_OPTION "-std=gnu99")
+  set(CMAKE_OBJC99_STANDARD__HAS_FULL_SUPPORT ON)
+
+  set(CMAKE_OBJC11_STANDARD_COMPILE_OPTION "-std=c11")
+  set(CMAKE_OBJC11_EXTENSION_COMPILE_OPTION "-std=gnu11")
+  set(CMAKE_OBJC11_STANDARD__HAS_FULL_SUPPORT ON)
+endif()
+
+__compiler_check_default_language_standard(OBJC 4.0 99)

+ 37 - 0
Modules/Compiler/AppleClang-OBJCXX.cmake

@@ -0,0 +1,37 @@
+include(Compiler/Clang-OBJCXX)
+
+if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.0)
+  set(CMAKE_OBJCXX98_STANDARD_COMPILE_OPTION "-std=c++98")
+  set(CMAKE_OBJCXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+  set(CMAKE_OBJCXX98_STANDARD__HAS_FULL_SUPPORT ON)
+
+  set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "-std=c++11")
+  set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+endif()
+
+if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 6.1)
+  set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std=c++14")
+  set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+  set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
+elseif(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 5.1)
+  # AppleClang 5.0 knows this flag, but does not set a __cplusplus macro greater than 201103L
+  set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
+  set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
+  set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
+endif()
+
+if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 6.1)
+  set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
+  set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
+endif()
+
+if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 8.0)
+    set(CMAKE_OBJCXX11_STANDARD__HAS_FULL_SUPPORT ON)
+endif()
+
+if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 10.0)
+  set(CMAKE_OBJCXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
+  set(CMAKE_OBJCXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
+endif()
+
+__compiler_check_default_language_standard(OBJCXX 4.0 98)

+ 18 - 0
Modules/Compiler/Clang-OBJC.cmake

@@ -0,0 +1,18 @@
+include(Compiler/Clang)
+__compiler_clang(OBJC)
+
+if(NOT CMAKE_OBJC_COMPILER_VERSION VERSION_LESS 3.4)
+  set(CMAKE_OBJC90_STANDARD_COMPILE_OPTION "-std=c90")
+  set(CMAKE_OBJC90_EXTENSION_COMPILE_OPTION "-std=gnu90")
+  set(CMAKE_OBJC90_STANDARD__HAS_FULL_SUPPORT ON)
+
+  set(CMAKE_OBJC99_STANDARD_COMPILE_OPTION "-std=c99")
+  set(CMAKE_OBJC99_EXTENSION_COMPILE_OPTION "-std=gnu99")
+  set(CMAKE_OBJC99_STANDARD__HAS_FULL_SUPPORT ON)
+
+  set(CMAKE_OBJC11_STANDARD_COMPILE_OPTION "-std=c11")
+  set(CMAKE_OBJC11_EXTENSION_COMPILE_OPTION "-std=gnu11")
+  set(CMAKE_OBJC11_STANDARD__HAS_FULL_SUPPORT ON)
+endif()
+
+__compiler_check_default_language_standard(OBJC 3.4 99 3.6 11)

+ 70 - 0
Modules/Compiler/Clang-OBJCXX.cmake

@@ -0,0 +1,70 @@
+include(Compiler/Clang)
+__compiler_clang(OBJCXX)
+
+if("x${CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
+  if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 2.1)
+    set(CMAKE_OBJCXX98_STANDARD_COMPILE_OPTION "-std=c++98")
+    set(CMAKE_OBJCXX98_EXTENSION_COMPILE_OPTION "-std=gnu++98")
+  endif()
+
+  if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.1)
+    set(CMAKE_OBJCXX98_STANDARD__HAS_FULL_SUPPORT ON)
+    set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "-std=c++11")
+    set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "-std=gnu++11")
+    set(CMAKE_OBJCXX11_STANDARD__HAS_FULL_SUPPORT ON)
+  elseif(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 2.1)
+    set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "-std=c++0x")
+    set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "-std=gnu++0x")
+  endif()
+
+  if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.5)
+    set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std=c++14")
+    set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+    set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
+  elseif(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.4)
+    set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std=c++1y")
+    set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std=gnu++1y")
+    set(CMAKE_OBJCXX14_STANDARD__HAS_FULL_SUPPORT ON)
+  endif()
+
+  set(_clang_version_std17 5.0)
+
+  if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
+    set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++17")
+    set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++17")
+  elseif (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 3.5)
+    set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std=c++1z")
+    set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std=gnu++1z")
+  endif()
+
+  if (NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS "${_clang_version_std17}")
+    set(CMAKE_OBJCXX20_STANDARD_COMPILE_OPTION "-std=c++2a")
+    set(CMAKE_OBJCXX20_EXTENSION_COMPILE_OPTION "-std=gnu++2a")
+  endif()
+
+  unset(_clang_version_std17)
+
+  __compiler_check_default_language_standard(OBJCXX 2.1 98)
+elseif(CMAKE_OBJCXX_COMPILER_VERSION VERSION_GREATER_EQUAL 3.9
+    AND CMAKE_OBJCXX_SIMULATE_VERSION VERSION_GREATER_EQUAL 19.0)
+  # This version of clang-cl and the MSVC version it simulates have
+  # support for -std: flags.
+  set(CMAKE_OBJCXX98_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_OBJCXX98_EXTENSION_COMPILE_OPTION "")
+  set(CMAKE_OBJCXX98_STANDARD__HAS_FULL_SUPPORT ON)
+  set(CMAKE_OBJCXX11_STANDARD_COMPILE_OPTION "")
+  set(CMAKE_OBJCXX11_EXTENSION_COMPILE_OPTION "")
+  set(CMAKE_OBJCXX14_STANDARD_COMPILE_OPTION "-std:c++14")
+  set(CMAKE_OBJCXX14_EXTENSION_COMPILE_OPTION "-std:c++14")
+  if (CMAKE_OBJCXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6.0)
+    set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std:c++17")
+    set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std:c++17")
+    set(CMAKE_OBJCXX20_STANDARD_COMPILE_OPTION "-std:c++latest")
+    set(CMAKE_OBJCXX20_EXTENSION_COMPILE_OPTION "-std:c++latest")
+  else()
+    set(CMAKE_OBJCXX17_STANDARD_COMPILE_OPTION "-std:c++latest")
+    set(CMAKE_OBJCXX17_EXTENSION_COMPILE_OPTION "-std:c++latest")
+  endif()
+
+  __compiler_check_default_language_standard(OBJCXX 3.9 14)
+endif()

+ 6 - 0
Modules/Compiler/GNU-OBJC.cmake

@@ -0,0 +1,6 @@
+include(Compiler/GNU)
+__compiler_gnu(OBJC)
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
+  set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+endif()

+ 10 - 0
Modules/Compiler/GNU-OBJCXX.cmake

@@ -0,0 +1,10 @@
+include(Compiler/GNU)
+__compiler_gnu(OBJC)
+
+if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.2)
+  set(CMAKE_CXX_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN "-fvisibility-inlines-hidden")
+endif()
+
+if(NOT CMAKE_OBJCXX_LINK_FLAGS)
+  set(CMAKE_OBCXX_LINK_FLAGS "-lstdc++")
+endif()

+ 6 - 0
Modules/Platform/Apple-AppleClang-OBJC.cmake

@@ -0,0 +1,6 @@
+include(Platform/Apple-Clang-OBJC)
+if(NOT CMAKE_OBJC_COMPILER_VERSION VERSION_LESS 4.2)
+  set(CMAKE_OBJC_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
+else()
+  unset(CMAKE_OBJC_SYSTEM_FRAMEWORK_SEARCH_FLAG)
+endif()

+ 6 - 0
Modules/Platform/Apple-AppleClang-OBJCXX.cmake

@@ -0,0 +1,6 @@
+include(Platform/Apple-Clang-OBJCXX)
+if(NOT CMAKE_OBJCXX_COMPILER_VERSION VERSION_LESS 4.2)
+  set(CMAKE_OBJCXX_SYSTEM_FRAMEWORK_SEARCH_FLAG "-iframework ")
+else()
+  unset(CMAKE_OBJCXX_SYSTEM_FRAMEWORK_SEARCH_FLAG)
+endif()

+ 2 - 0
Modules/Platform/Apple-Clang-OBJC.cmake

@@ -0,0 +1,2 @@
+include(Platform/Apple-Clang)
+__apple_compiler_clang(OBJC)

+ 2 - 0
Modules/Platform/Apple-Clang-OBJCXX.cmake

@@ -0,0 +1,2 @@
+include(Platform/Apple-Clang)
+__apple_compiler_clang(OBJCXX)

+ 4 - 0
Modules/Platform/Apple-GNU-OBJC.cmake

@@ -0,0 +1,4 @@
+include(Platform/Apple-GNU)
+__apple_compiler_gnu(OBJC)
+cmake_gnu_set_sysroot_flag(OBJC)
+cmake_gnu_set_osx_deployment_target_flag(OBJC)

+ 4 - 0
Modules/Platform/Apple-GNU-OBJCXX.cmake

@@ -0,0 +1,4 @@
+include(Platform/Apple-GNU)
+__apple_compiler_gnu(OBJCXX)
+cmake_gnu_set_sysroot_flag(OBJCXX)
+cmake_gnu_set_osx_deployment_target_flag(OBJCXX)

+ 9 - 1
Modules/Platform/Darwin.cmake

@@ -119,10 +119,18 @@ set(CMAKE_C_CREATE_MACOSX_FRAMEWORK
 set(CMAKE_CXX_CREATE_MACOSX_FRAMEWORK
       "<CMAKE_CXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
 
+set(CMAKE_OBJC_CREATE_MACOSX_FRAMEWORK
+      "<CMAKE_OBJC_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_OBJC_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
+
+set(CMAKE_OBJCXX_CREATE_MACOSX_FRAMEWORK
+      "<CMAKE_OBJCXX_COMPILER> <LANGUAGE_COMPILE_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_OBJCXX_FLAGS> <LINK_FLAGS> -o <TARGET> <SONAME_FLAG> <TARGET_INSTALLNAME_DIR><TARGET_SONAME> <OBJECTS> <LINK_LIBRARIES>")
+
 # Set default framework search path flag for languages known to use a
 # preprocessor that may find headers in frameworks.
 set(CMAKE_C_FRAMEWORK_SEARCH_FLAG -F)
 set(CMAKE_CXX_FRAMEWORK_SEARCH_FLAG -F)
+set(CMAKE_OBJC_FRAMEWORK_SEARCH_FLAG -F)
+set(CMAKE_OBJCXX_FRAMEWORK_SEARCH_FLAG -F)
 set(CMAKE_Fortran_FRAMEWORK_SEARCH_FLAG -F)
 
 # default to searching for frameworks first
@@ -222,7 +230,7 @@ unset(_apps_paths)
 include(Platform/UnixPaths)
 if(_CMAKE_OSX_SYSROOT_PATH AND EXISTS ${_CMAKE_OSX_SYSROOT_PATH}/usr/include)
   list(APPEND CMAKE_SYSTEM_PREFIX_PATH ${_CMAKE_OSX_SYSROOT_PATH}/usr)
-  foreach(lang C CXX)
+  foreach(lang C CXX OBJC OBJCXX)
     list(APPEND _CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT ${_CMAKE_OSX_SYSROOT_PATH}/usr/include)
   endforeach()
 endif()

+ 7 - 1
Source/cmGeneratorExpressionNode.cxx

@@ -707,7 +707,8 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
 };
 
 static const CompilerIdNode cCompilerIdNode("C"), cxxCompilerIdNode("CXX"),
-  cudaCompilerIdNode("CUDA"), fortranCompilerIdNode("Fortran");
+  cudaCompilerIdNode("CUDA"), objcCompilerIdNode("OBJC"),
+  objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran");
 
 struct CompilerVersionNode : public cmGeneratorExpressionNode
 {
@@ -771,6 +772,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
 
 static const CompilerVersionNode cCompilerVersionNode("C"),
   cxxCompilerVersionNode("CXX"), cudaCompilerVersionNode("CUDA"),
+  objcCompilerVersionNode("OBJC"), objcxxCompilerVersionNode("OBJCXX"),
   fortranCompilerVersionNode("Fortran");
 
 struct PlatformIdNode : public cmGeneratorExpressionNode
@@ -2243,6 +2245,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
     { "NOT", &notNode },
     { "C_COMPILER_ID", &cCompilerIdNode },
     { "CXX_COMPILER_ID", &cxxCompilerIdNode },
+    { "OBJC_COMPILER_ID", &objcCompilerIdNode },
+    { "OBJCXX_COMPILER_ID", &objcxxCompilerIdNode },
     { "CUDA_COMPILER_ID", &cudaCompilerIdNode },
     { "Fortran_COMPILER_ID", &fortranCompilerIdNode },
     { "VERSION_GREATER", &versionGreaterNode },
@@ -2253,6 +2257,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
     { "C_COMPILER_VERSION", &cCompilerVersionNode },
     { "CXX_COMPILER_VERSION", &cxxCompilerVersionNode },
     { "CUDA_COMPILER_VERSION", &cudaCompilerVersionNode },
+    { "OBJC_COMPILER_VERSION", &objcCompilerVersionNode },
+    { "OBJCXX_COMPILER_VERSION", &objcxxCompilerVersionNode },
     { "Fortran_COMPILER_VERSION", &fortranCompilerVersionNode },
     { "PLATFORM_ID", &platformIdNode },
     { "COMPILE_FEATURES", &compileFeaturesNode },

+ 11 - 1
Source/cmLocalGenerator.cxx

@@ -1655,7 +1655,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
     const char* deploymentTargetFlag =
       this->Makefile->GetDefinition(deploymentTargetFlagVar);
     if (!archs.empty() && !lang.empty() &&
-        (lang[0] == 'C' || lang[0] == 'F')) {
+        (lang[0] == 'C' || lang[0] == 'F' || lang[0] == 'O')) {
       for (std::string const& arch : archs) {
         flags += " -arch ";
         flags += arch;
@@ -1942,10 +1942,20 @@ void cmLocalGenerator::AddCompilerRequirementFlag(
     langStdMap["CXX"].emplace_back("11");
     langStdMap["CXX"].emplace_back("98");
 
+    langStdMap["OBJCXX"].emplace_back("20");
+    langStdMap["OBJCXX"].emplace_back("17");
+    langStdMap["OBJCXX"].emplace_back("14");
+    langStdMap["OBJCXX"].emplace_back("11");
+    langStdMap["OBJCXX"].emplace_back("98");
+
     langStdMap["C"].emplace_back("11");
     langStdMap["C"].emplace_back("99");
     langStdMap["C"].emplace_back("90");
 
+    langStdMap["OBJC"].emplace_back("11");
+    langStdMap["OBJC"].emplace_back("99");
+    langStdMap["OBJC"].emplace_back("90");
+
     langStdMap["CUDA"].emplace_back("14");
     langStdMap["CUDA"].emplace_back("11");
     langStdMap["CUDA"].emplace_back("98");

+ 80 - 68
Source/cmMakefile.cxx

@@ -38,6 +38,7 @@
 #include "cmState.h"
 #include "cmStateDirectory.h"
 #include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 #include "cmTargetLinkLibraryType.h"
@@ -4629,9 +4630,9 @@ bool cmMakefile::AddRequiredTargetFeature(cmTarget* target,
 
   target->AppendProperty("COMPILE_FEATURES", feature.c_str());
 
-  return lang == "C"
-    ? this->AddRequiredTargetCFeature(target, feature, error)
-    : this->AddRequiredTargetCxxFeature(target, feature, error);
+  return lang == "C" || lang == "OBJC"
+    ? this->AddRequiredTargetCFeature(target, feature, lang, error)
+    : this->AddRequiredTargetCxxFeature(target, feature, lang, error);
 }
 
 bool cmMakefile::CompileFeatureKnown(cmTarget const* target,
@@ -4723,30 +4724,33 @@ bool cmMakefile::HaveStandardAvailable(cmTarget const* target,
                                        std::string const& lang,
                                        const std::string& feature) const
 {
-  return lang == "C" ? this->HaveCStandardAvailable(target, feature)
-                     : this->HaveCxxStandardAvailable(target, feature);
+  return lang == "C" || lang == "OBJC"
+    ? this->HaveCStandardAvailable(target, feature, lang)
+    : this->HaveCxxStandardAvailable(target, feature, lang);
 }
 
 bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
-                                        const std::string& feature) const
+                                        const std::string& feature,
+                                        std::string const& lang) const
 {
   const char* defaultCStandard =
-    this->GetDefinition("CMAKE_C_STANDARD_DEFAULT");
+    this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
   if (!defaultCStandard) {
     this->IssueMessage(
       MessageType::INTERNAL_ERROR,
-      "CMAKE_C_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
-      "not fully configured for this compiler.");
+      cmStrCat("CMAKE_", lang,
+               "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
+               "not fully configured for this compiler."));
     // Return true so the caller does not try to lookup the default standard.
     return true;
   }
   if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
                    cmStrCmp(defaultCStandard)) == cm::cend(C_STANDARDS)) {
-    std::ostringstream e;
-    e << "The CMAKE_C_STANDARD_DEFAULT variable contains an "
-         "invalid value: \""
-      << defaultCStandard << "\".";
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+    const std::string e = cmStrCat("The CMAKE_", lang,
+                                   "_STANDARD_DEFAULT variable contains an "
+                                   "invalid value: \"",
+                                   defaultCStandard, "\".");
+    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
     return false;
   }
 
@@ -4754,19 +4758,20 @@ bool cmMakefile::HaveCStandardAvailable(cmTarget const* target,
   bool needC99 = false;
   bool needC11 = false;
 
-  this->CheckNeededCLanguage(feature, needC90, needC99, needC11);
+  this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
 
-  const char* existingCStandard = target->GetProperty("C_STANDARD");
+  const char* existingCStandard =
+    target->GetProperty(cmStrCat(lang, "_STANDARD"));
   if (!existingCStandard) {
     existingCStandard = defaultCStandard;
   }
 
   if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
                    cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
-    std::ostringstream e;
-    e << "The C_STANDARD property on target \"" << target->GetName()
-      << "\" contained an invalid value: \"" << existingCStandard << "\".";
-    this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    const std::string e = cmStrCat(
+      "The ", lang, "_STANDARD property on target \"", target->GetName(),
+      "\" contained an invalid value: \"", existingCStandard, "\".");
+    this->IssueMessage(MessageType::FATAL_ERROR, e);
     return false;
   }
 
@@ -4797,7 +4802,7 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
                                  std::string const& lhs,
                                  std::string const& rhs)
 {
-  if (lang == "C") {
+  if (lang == "C" || lang == "OBJC") {
     const char* const* rhsIt = std::find_if(
       cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS), cmStrCmp(rhs));
 
@@ -4812,25 +4817,26 @@ bool cmMakefile::IsLaterStandard(std::string const& lang,
 }
 
 bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
-                                          const std::string& feature) const
+                                          const std::string& feature,
+                                          std::string const& lang) const
 {
   const char* defaultCxxStandard =
-    this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
+    this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
   if (!defaultCxxStandard) {
     this->IssueMessage(
       MessageType::INTERNAL_ERROR,
-      "CMAKE_CXX_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
-      "not fully configured for this compiler.");
+      cmStrCat("CMAKE_", lang,
+               "_STANDARD_DEFAULT is not set.  COMPILE_FEATURES support "
+               "not fully configured for this compiler."));
     // Return true so the caller does not try to lookup the default standard.
     return true;
   }
   if (std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
                    cmStrCmp(defaultCxxStandard)) == cm::cend(CXX_STANDARDS)) {
-    std::ostringstream e;
-    e << "The CMAKE_CXX_STANDARD_DEFAULT variable contains an "
-         "invalid value: \""
-      << defaultCxxStandard << "\".";
-    this->IssueMessage(MessageType::INTERNAL_ERROR, e.str());
+    const std::string e =
+      cmStrCat("The CMAKE_", lang, "_STANDARD_DEFAULT variable contains an ",
+               "invalid value: \"", defaultCxxStandard, "\".");
+    this->IssueMessage(MessageType::INTERNAL_ERROR, e);
     return false;
   }
 
@@ -4839,10 +4845,11 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
   bool needCxx14 = false;
   bool needCxx17 = false;
   bool needCxx20 = false;
-  this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
+  this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
                                needCxx17, needCxx20);
 
-  const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
+  const char* existingCxxStandard =
+    target->GetProperty(cmStrCat(lang, "_STANDARD"));
   if (!existingCxxStandard) {
     existingCxxStandard = defaultCxxStandard;
   }
@@ -4851,10 +4858,10 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
     std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
                  cmStrCmp(existingCxxStandard));
   if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
-    std::ostringstream e;
-    e << "The CXX_STANDARD property on target \"" << target->GetName()
-      << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
-    this->IssueMessage(MessageType::FATAL_ERROR, e.str());
+    const std::string e = cmStrCat(
+      "The ", lang, "_STANDARD property on target \"", target->GetName(),
+      "\" contained an invalid value: \"", existingCxxStandard, "\".");
+    this->IssueMessage(MessageType::FATAL_ERROR, e);
     return false;
   }
 
@@ -4872,32 +4879,33 @@ bool cmMakefile::HaveCxxStandardAvailable(cmTarget const* target,
 }
 
 void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
+                                        std::string const& lang,
                                         bool& needCxx98, bool& needCxx11,
                                         bool& needCxx14, bool& needCxx17,
                                         bool& needCxx20) const
 {
   if (const char* propCxx98 =
-        this->GetDefinition("CMAKE_CXX98_COMPILE_FEATURES")) {
+        this->GetDefinition(cmStrCat("CMAKE_", lang, "98_COMPILE_FEATURES"))) {
     std::vector<std::string> props = cmExpandedList(propCxx98);
     needCxx98 = cmContains(props, feature);
   }
   if (const char* propCxx11 =
-        this->GetDefinition("CMAKE_CXX11_COMPILE_FEATURES")) {
+        this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
     std::vector<std::string> props = cmExpandedList(propCxx11);
     needCxx11 = cmContains(props, feature);
   }
   if (const char* propCxx14 =
-        this->GetDefinition("CMAKE_CXX14_COMPILE_FEATURES")) {
+        this->GetDefinition(cmStrCat("CMAKE_", lang, "14_COMPILE_FEATURES"))) {
     std::vector<std::string> props = cmExpandedList(propCxx14);
     needCxx14 = cmContains(props, feature);
   }
   if (const char* propCxx17 =
-        this->GetDefinition("CMAKE_CXX17_COMPILE_FEATURES")) {
+        this->GetDefinition(cmStrCat("CMAKE_", lang, "17_COMPILE_FEATURES"))) {
     std::vector<std::string> props = cmExpandedList(propCxx17);
     needCxx17 = cmContains(props, feature);
   }
   if (const char* propCxx20 =
-        this->GetDefinition("CMAKE_CXX20_COMPILE_FEATURES")) {
+        this->GetDefinition(cmStrCat("CMAKE_", lang, "20_COMPILE_FEATURES"))) {
     std::vector<std::string> props = cmExpandedList(propCxx20);
     needCxx20 = cmContains(props, feature);
   }
@@ -4905,6 +4913,7 @@ void cmMakefile::CheckNeededCxxLanguage(const std::string& feature,
 
 bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
                                              const std::string& feature,
+                                             std::string const& lang,
                                              std::string* error) const
 {
   bool needCxx98 = false;
@@ -4913,13 +4922,14 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
   bool needCxx17 = false;
   bool needCxx20 = false;
 
-  this->CheckNeededCxxLanguage(feature, needCxx98, needCxx11, needCxx14,
+  this->CheckNeededCxxLanguage(feature, lang, needCxx98, needCxx11, needCxx14,
                                needCxx17, needCxx20);
 
-  const char* existingCxxStandard = target->GetProperty("CXX_STANDARD");
+  const char* existingCxxStandard =
+    target->GetProperty(cmStrCat(lang, "_STANDARD"));
   if (existingCxxStandard == nullptr) {
     const char* defaultCxxStandard =
-      this->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
+      this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
     if (defaultCxxStandard && *defaultCxxStandard) {
       existingCxxStandard = defaultCxxStandard;
     }
@@ -4930,14 +4940,14 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
       std::find_if(cm::cbegin(CXX_STANDARDS), cm::cend(CXX_STANDARDS),
                    cmStrCmp(existingCxxStandard));
     if (existingCxxLevel == cm::cend(CXX_STANDARDS)) {
-      std::ostringstream e;
-      e << "The CXX_STANDARD property on target \"" << target->GetName()
-        << "\" contained an invalid value: \"" << existingCxxStandard << "\".";
+      const std::string e = cmStrCat(
+        "The ", lang, "_STANDARD property on target \"", target->GetName(),
+        "\" contained an invalid value: \"", existingCxxStandard, "\".");
       if (error) {
-        *error = e.str();
+        *error = e;
       } else {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
-                                               e.str(), this->Backtrace);
+        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+                                               this->Backtrace);
       }
       return false;
     }
@@ -4978,7 +4988,7 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
     // Ensure the C++ language level is high enough to support
     // the needed C++ features.
     if (!existingCxxLevel || existingCxxLevel < needCxxLevel) {
-      target->SetProperty("CXX_STANDARD", *needCxxLevel);
+      target->SetProperty(cmStrCat(lang, "_STANDARD"), *needCxxLevel);
     }
 
     // Ensure the CUDA language level is high enough to support
@@ -4992,21 +5002,21 @@ bool cmMakefile::AddRequiredTargetCxxFeature(cmTarget* target,
 }
 
 void cmMakefile::CheckNeededCLanguage(const std::string& feature,
-                                      bool& needC90, bool& needC99,
-                                      bool& needC11) const
+                                      std::string const& lang, bool& needC90,
+                                      bool& needC99, bool& needC11) const
 {
   if (const char* propC90 =
-        this->GetDefinition("CMAKE_C90_COMPILE_FEATURES")) {
+        this->GetDefinition(cmStrCat("CMAKE_", lang, "90_COMPILE_FEATURES"))) {
     std::vector<std::string> props = cmExpandedList(propC90);
     needC90 = cmContains(props, feature);
   }
   if (const char* propC99 =
-        this->GetDefinition("CMAKE_C99_COMPILE_FEATURES")) {
+        this->GetDefinition(cmStrCat("CMAKE_", lang, "99_COMPILE_FEATURES"))) {
     std::vector<std::string> props = cmExpandedList(propC99);
     needC99 = cmContains(props, feature);
   }
   if (const char* propC11 =
-        this->GetDefinition("CMAKE_C11_COMPILE_FEATURES")) {
+        this->GetDefinition(cmStrCat("CMAKE_", lang, "11_COMPILE_FEATURES"))) {
     std::vector<std::string> props = cmExpandedList(propC11);
     needC11 = cmContains(props, feature);
   }
@@ -5014,18 +5024,20 @@ void cmMakefile::CheckNeededCLanguage(const std::string& feature,
 
 bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
                                            const std::string& feature,
+                                           std::string const& lang,
                                            std::string* error) const
 {
   bool needC90 = false;
   bool needC99 = false;
   bool needC11 = false;
 
-  this->CheckNeededCLanguage(feature, needC90, needC99, needC11);
+  this->CheckNeededCLanguage(feature, lang, needC90, needC99, needC11);
 
-  const char* existingCStandard = target->GetProperty("C_STANDARD");
+  const char* existingCStandard =
+    target->GetProperty(cmStrCat(lang, "_STANDARD"));
   if (existingCStandard == nullptr) {
     const char* defaultCStandard =
-      this->GetDefinition("CMAKE_C_STANDARD_DEFAULT");
+      this->GetDefinition(cmStrCat("CMAKE_", lang, "_STANDARD_DEFAULT"));
     if (defaultCStandard && *defaultCStandard) {
       existingCStandard = defaultCStandard;
     }
@@ -5033,14 +5045,14 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
   if (existingCStandard) {
     if (std::find_if(cm::cbegin(C_STANDARDS), cm::cend(C_STANDARDS),
                      cmStrCmp(existingCStandard)) == cm::cend(C_STANDARDS)) {
-      std::ostringstream e;
-      e << "The C_STANDARD property on target \"" << target->GetName()
-        << "\" contained an invalid value: \"" << existingCStandard << "\".";
+      const std::string e = cmStrCat(
+        "The ", lang, "_STANDARD property on target \"", target->GetName(),
+        "\" contained an invalid value: \"", existingCStandard, "\".");
       if (error) {
-        *error = e.str();
+        *error = e;
       } else {
-        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
-                                               e.str(), this->Backtrace);
+        this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e,
+                                               this->Backtrace);
       }
       return false;
     }
@@ -5071,11 +5083,11 @@ bool cmMakefile::AddRequiredTargetCFeature(cmTarget* target,
   }
 
   if (setC11) {
-    target->SetProperty("C_STANDARD", "11");
+    target->SetProperty(cmStrCat(lang, "_STANDARD"), "11");
   } else if (setC99) {
-    target->SetProperty("C_STANDARD", "99");
+    target->SetProperty(cmStrCat(lang, "_STANDARD"), "99");
   } else if (setC90) {
-    target->SetProperty("C_STANDARD", "90");
+    target->SetProperty(cmStrCat(lang, "_STANDARD"), "90");
   }
   return true;
 }

+ 10 - 4
Source/cmMakefile.h

@@ -1146,22 +1146,28 @@ private:
   bool MightHaveCustomCommand(const std::string& name) const;
 
   bool AddRequiredTargetCFeature(cmTarget* target, const std::string& feature,
+                                 std::string const& lang,
                                  std::string* error = nullptr) const;
 
   bool AddRequiredTargetCxxFeature(cmTarget* target,
                                    const std::string& feature,
+                                   std::string const& lang,
                                    std::string* error = nullptr) const;
 
-  void CheckNeededCLanguage(const std::string& feature, bool& needC90,
+  void CheckNeededCLanguage(const std::string& feature,
+                            std::string const& lang, bool& needC90,
                             bool& needC99, bool& needC11) const;
-  void CheckNeededCxxLanguage(const std::string& feature, bool& needCxx98,
+  void CheckNeededCxxLanguage(const std::string& feature,
+                              std::string const& lang, bool& needCxx98,
                               bool& needCxx11, bool& needCxx14,
                               bool& needCxx17, bool& needCxx20) const;
 
   bool HaveCStandardAvailable(cmTarget const* target,
-                              const std::string& feature) const;
+                              const std::string& feature,
+                              std::string const& lang) const;
   bool HaveCxxStandardAvailable(cmTarget const* target,
-                                const std::string& feature) const;
+                                const std::string& feature,
+                                std::string const& lang) const;
 
   void CheckForUnusedVariables() const;
 

+ 8 - 0
Source/cmTarget.cxx

@@ -332,6 +332,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     initProp("C_STANDARD");
     initProp("C_STANDARD_REQUIRED");
     initProp("C_EXTENSIONS");
+    initProp("OBJC_STANDARD");
+    initProp("OBJC_STANDARD_REQUIRED");
+    initProp("OBJC_EXTENSIONS");
     initProp("CXX_CLANG_TIDY");
     initProp("CXX_COMPILER_LAUNCHER");
     initProp("CXX_CPPLINT");
@@ -340,6 +343,9 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     initProp("CXX_STANDARD");
     initProp("CXX_STANDARD_REQUIRED");
     initProp("CXX_EXTENSIONS");
+    initProp("OBJCXX_STANDARD");
+    initProp("OBJCXX_STANDARD_REQUIRED");
+    initProp("OBJCXX_EXTENSIONS");
     initProp("CUDA_STANDARD");
     initProp("CUDA_STANDARD_REQUIRED");
     initProp("CUDA_EXTENSIONS");
@@ -452,6 +458,8 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
       this->GetType() != cmStateEnums::UTILITY) {
     initProp("C_VISIBILITY_PRESET");
     initProp("CXX_VISIBILITY_PRESET");
+    initProp("OBJC_VISIBILITY_PRESET");
+    initProp("OBJCXX_VISIBILITY_PRESET");
     initProp("CUDA_VISIBILITY_PRESET");
     initProp("VISIBILITY_INLINES_HIDDEN");
   }

+ 73 - 0
Tests/CMakeLists.txt

@@ -2328,6 +2328,79 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CFBundleTest")
 
       ADD_TEST_MACRO(ObjC++ ObjC++)
+
+      add_test(Objective-C.simple-build-test ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Objective-C/simple-build-test"
+        "${CMake_BINARY_DIR}/Tests/Objective-C/simple-build-test"
+        --build-two-config
+        ${build_generator_args}
+        --build-project simple-build-test
+        --build-options ${build_options}
+        --test-command simple-build-test
+      )
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Objective-C/simple-build-test")
+
+      add_test(Objective-C.c-file-extension-test ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Objective-C/c-file-extension-test"
+        "${CMake_BINARY_DIR}/Tests/Objective-C/c-file-extension-test"
+        --build-two-config
+        ${build_generator_args}
+        --build-project c-file-extension-test
+        --build-options ${build_options}
+        --test-command c-file-extension-test
+      )
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Objective-C/c-file-extension-test")
+
+      add_test(Objective-C.objc-file-extension-test ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Objective-C/objc-file-extension-test"
+        "${CMake_BINARY_DIR}/Tests/Objective-C/objc-file-extension-test"
+        --build-two-config
+        ${build_generator_args}
+        --build-project objc-file-extension-test
+        --build-options ${build_options}
+        --test-command objc-file-extension-test
+      )
+      list(APPEND TEST_BUILD_DIRS "${CMAKE_BINARY_DIR}/Tests/Objective-C/objc-file-extension-test")
+
+      add_test(Objective-CXX.simple-build-test ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Objective-C++/simple-build-test"
+        "${CMake_BINARY_DIR}/Tests/Objective-C++/simple-build-test"
+        --build-two-config
+        ${build_generator_args}
+        --build-project simple-build-test
+        --build-options ${build_options}
+        --test-command simple-build-test
+      )
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Objective-C++/simple-build-test")
+
+      add_test(Objective-CXX.cxx-file-extension-test ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Objective-C++/cxx-file-extension-test"
+        "${CMake_BINARY_DIR}/Tests/Objective-C++/cxx-file-extension-test"
+        --build-two-config
+        ${build_generator_args}
+        --build-project cxx-file-extension-test
+        --build-options ${build_options}
+        --test-command cxx-file-extension-test
+      )
+      list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Objective-C++/cxx-file-extension-test")
+
+      add_test(Objective-CXX.objcxx-file-extension-test ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/Objective-C++/objcxx-file-extension-test"
+        "${CMake_BINARY_DIR}/Tests/Objective-C++/objcxx-file-extension-test"
+        --build-two-config
+        ${build_generator_args}
+        --build-project objcxx-file-extension-test
+        --build-options ${build_options}
+        --test-command objcxx-file-extension-test
+      )
+      list(APPEND TEST_BUILD_DIRS "${CMAKE_BINARY_DIR}/Tests/Objective-C++/objcxx-file-extension-test")
+
     endif ()
   endif ()
 

+ 11 - 0
Tests/CMakeOnly/CMakeLists.txt

@@ -30,6 +30,17 @@ add_CMakeOnly_test(CheckStructHasMember)
 
 add_CMakeOnly_test(CompilerIdC)
 add_CMakeOnly_test(CompilerIdCXX)
+
+if(CMAKE_OBJC_COMPILER)
+  add_CMakeOnly_test(CompilerIdOBJC)
+  add_CMakeOnly_test(CheckOBJCCompilerFlag)
+endif()
+
+if(CMAKE_OBJCXX_COMPILER)
+  add_CMakeOnly_test(CompilerIdOBJCXX)
+  add_CMakeOnly_test(CheckOBJCXXCompilerFlag)
+endif()
+
 if(CMAKE_Fortran_COMPILER)
   add_CMakeOnly_test(CompilerIdFortran)
 endif()

+ 11 - 1
Tests/CMakeOnly/CheckLanguage/CMakeLists.txt

@@ -5,10 +5,20 @@ include(CheckLanguage)
 set(langs )
 set(expect_C 1)
 set(expect_CXX 1)
+
+if(APPLE)
+  set(expect_OBJC 1)
+  set(expect_OBJCXX 1)
+endif()
 unset(expect_Fortran)
 set(expect_NoSuchLanguage 0)
 
-foreach(lang C CXX Fortran CUDA NoSuchLanguage)
+set(LANGUAGES C CXX Fortran CUDA NoSuchLanguage)
+if(APPLE)
+  list(APPEND LANGUAGES OBJC OBJCXX)
+endif()
+
+foreach(lang ${LANGUAGES})
   check_language(${lang})
   if(NOT DEFINED CMAKE_${lang}_COMPILER)
     message(FATAL_ERROR "check_language(${lang}) did not set result")

+ 17 - 0
Tests/CMakeOnly/CheckOBJCCompilerFlag/CMakeLists.txt

@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(CheckOBJCCompilerFlag)
+
+include(CheckOBJCCompilerFlag)
+
+if(CMAKE_COMPILER_IS_GNUOBJC)
+  set(COMPILER_FLAG -fobjc-direct-dispatch)
+else()
+  set(COMPILER_FLAG -fobjc-gc)
+endif()
+
+CHECK_OBJC_COMPILER_FLAGS(${COMPILER_FLAG} HAS_COMPILER_FLAG)
+
+if(NOT HAS_COMPILER_FLAG)
+  message(SEND_ERROR "Test fail: HAS_COMPILER_FLAG: ${COMPILER_FLAG}")
+endif

+ 17 - 0
Tests/CMakeOnly/CheckOBJCXXCompilerFlag/CMakeLists.txt

@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 2.8.12)
+
+project(CheckOBJCXXCompilerFlag)
+
+include(CheckOBJCXXCompilerFlag)
+
+if(CMAKE_COMPILER_IS_GNUOBJCXX)
+  set(COMPILER_FLAG -fobjc-direct-dispatch)
+else()
+  set(COMPILER_FLAG -fobjc-gc)
+endif()
+
+CHECK_OBJCXX_COMPILER_FLAGS(${COMPILER_FLAG} HAS_COMPILER_FLAG)
+
+if(NOT HAS_COMPILER_FLAG)
+  message(SEND_ERROR "Test fail: HAS_COMPILER_FLAG: ${COMPILER_FLAG}")
+endif()

+ 14 - 0
Tests/CMakeOnly/CompilerIdOBJC/CMakeLists.txt

@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(CompilerIdOBJC OBJC)
+
+foreach(v
+    CMAKE_OBJC_COMPILER
+    CMAKE_OBJC_COMPILER_ID
+    CMAKE_OBJC_COMPILER_VERSION
+    )
+  if(${v})
+    message(STATUS "${v}=[${${v}}]")
+  else()
+    message(SEND_ERROR "${v} not set!")
+  endif()
+endforeach()

+ 14 - 0
Tests/CMakeOnly/CompilerIdOBJCXX/CMakeLists.txt

@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8.12)
+project(CompilerIdOBJCXX OBJCXX)
+
+foreach(v
+    CMAKE_OBJCXX_COMPILER
+    CMAKE_OBJCXX_COMPILER_ID
+    CMAKE_OBJCXX_COMPILER_VERSION
+    )
+  if(${v})
+    message(STATUS "${v}=[${${v}}]")
+  else()
+    message(SEND_ERROR "${v} not set!")
+  endif()
+endforeach()

+ 5 - 0
Tests/Objective-C++/cxx-file-extension-test/CMakeLists.txt

@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.15)
+
+project(cxx-file-extension-test CXX)
+
+add_executable(cxx-file-extension-test main.mm)

+ 8 - 0
Tests/Objective-C++/cxx-file-extension-test/main.mm

@@ -0,0 +1,8 @@
+#ifndef __OBJC__
+#  error "Compiler cannot compile Objective-C"
+#endif
+
+int main()
+{
+  return 0;
+}

+ 6 - 0
Tests/Objective-C++/objcxx-file-extension-test/CMakeLists.txt

@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.15)
+
+project(objcxx-file-extension-test OBJCXX CXX)
+
+add_executable(objcxx-file-extension-test main.mm)
+target_link_libraries(objcxx-file-extension-test "-framework Foundation")

+ 14 - 0
Tests/Objective-C++/objcxx-file-extension-test/main.mm

@@ -0,0 +1,14 @@
+#ifndef __OBJC__
+#  error "Compiler is not an Objective-C compiler."
+#endif
+
+#import <Foundation/Foundation.h>
+#include <iostream>
+
+int main()
+{
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+  std::cout << "Hello World" << std::endl;
+  [pool release];
+  return 0;
+}

+ 11 - 0
Tests/Objective-C++/simple-build-test/CMakeLists.txt

@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.15)
+
+set(CMAKE_MACOSX_RPATH OFF)
+
+project(simple-build-test OBJCXX)
+
+add_library(foo SHARED foo.mm)
+target_link_libraries(foo "-framework Foundation")
+
+add_executable(simple-build-test main.mm)
+target_link_libraries(simple-build-test "-framework Foundation" foo)

+ 9 - 0
Tests/Objective-C++/simple-build-test/foo.h

@@ -0,0 +1,9 @@
+#import <Foundation/Foundation.h>
+
+@interface Foo : NSObject {
+  NSNumber* age;
+}
+
+@property (nonatomic, retain) NSNumber* age;
+
+@end

+ 7 - 0
Tests/Objective-C++/simple-build-test/foo.mm

@@ -0,0 +1,7 @@
+#import "foo.h"
+
+@implementation Foo
+
+@synthesize age;
+
+@end

+ 14 - 0
Tests/Objective-C++/simple-build-test/main.mm

@@ -0,0 +1,14 @@
+#import <Foundation/Foundation.h>
+#import "foo.h"
+#include <iostream>
+
+int main(int argc, char **argv)
+{
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+  Foo *theFoo = [[Foo alloc] init];
+  theFoo.age = [NSNumber numberWithInt:argc];
+  NSLog(@"%d\n",[theFoo.age intValue]);
+  std::cout << [theFoo.age intValue] << std::endl;
+  [pool release];
+  return 0;
+}

+ 5 - 0
Tests/Objective-C/c-file-extension-test/CMakeLists.txt

@@ -0,0 +1,5 @@
+cmake_minimum_required(VERSION 3.15)
+
+project(c-file-extension-test C)
+
+add_executable(c-file-extension-test main.m)

+ 8 - 0
Tests/Objective-C/c-file-extension-test/main.m

@@ -0,0 +1,8 @@
+#ifndef __OBJC__
+#  error "Compiler cannot compile Objective-C"
+#endif
+
+int main()
+{
+  return 0;
+}

+ 6 - 0
Tests/Objective-C/objc-file-extension-test/CMakeLists.txt

@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.15)
+
+project(objc-file-extension-test OBJC CXX)
+
+add_executable(objc-file-extension-test main.m)
+target_link_libraries(objc-file-extension-test "-framework Foundation")

+ 12 - 0
Tests/Objective-C/objc-file-extension-test/main.m

@@ -0,0 +1,12 @@
+#ifndef __OBJC__
+#  error "Compiler is not an Objective-C compiler."
+#endif
+
+#import <Foundation/Foundation.h>
+
+int main()
+{
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+  [pool release];
+  return 0;
+}

+ 11 - 0
Tests/Objective-C/simple-build-test/CMakeLists.txt

@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.15)
+
+set(CMAKE_MACOSX_RPATH OFF)
+
+project(simple-build-test OBJC)
+
+add_library(foo SHARED foo.m)
+target_link_libraries(foo "-framework Foundation")
+
+add_executable(simple-build-test main.m)
+target_link_libraries(simple-build-test "-framework Foundation" foo)

+ 9 - 0
Tests/Objective-C/simple-build-test/foo.h

@@ -0,0 +1,9 @@
+#import <Foundation/Foundation.h>
+
+@interface Foo : NSObject {
+  NSNumber* age;
+}
+
+@property (nonatomic, retain) NSNumber* age;
+
+@end

+ 7 - 0
Tests/Objective-C/simple-build-test/foo.m

@@ -0,0 +1,7 @@
+#import "foo.h"
+
+@implementation Foo
+
+@synthesize age;
+
+@end

+ 12 - 0
Tests/Objective-C/simple-build-test/main.m

@@ -0,0 +1,12 @@
+#import <Foundation/Foundation.h>
+#import "foo.h"
+
+int main(int argc, char **argv)
+{
+  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+  Foo *theFoo = [[Foo alloc] init];
+  theFoo.age = [NSNumber numberWithInt:argc];
+  NSLog(@"%d\n",[theFoo.age intValue]);
+  [pool release];
+  return 0;
+}

+ 54 - 0
Tests/TryCompile/CMakeLists.txt

@@ -313,6 +313,60 @@ if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
   TEST_ASSERT(C_STRICT_PROTOTYPES "CHECK_C_COMPILER_FLAG failed -Werror -Wstrict-prototypes")
 endif()
 
+#########################################################################
+#
+# Test that the CHECK_OBJCC_SOURCE_COMPILES, CHECK_OBJCXX_SOURCE_COMPILES
+# CHECK_OBJC_SOURCE_RUNS and CHECK_OBJCXX_SOURCE_RUNS macros work
+
+if (APPLE)
+    enable_language(OBJC)
+    enable_language(OBJCXX)
+
+    include(CheckOBJCSourceCompiles)
+    include(CheckOBJCXXSourceCompiles)
+    include(CheckOBJCSourceRuns)
+    include(CheckOBJCXXSourceRuns)
+
+    CHECK_OBJC_SOURCE_COMPILES("I don't build in Objective-C" OBJC_BUILD_SHOULD_FAIL)
+    CHECK_OBJC_SOURCE_COMPILES("int main() { return 0; }" SIMPLE_OBJC_BUILD_SHOULD_WORK)
+
+    TEST_FAIL(OBJC_BUILD_SHOULD_FAIL "CHECK_OBJC_SOURCE_COMPILES() succeeded, but should have failed")
+    TEST_ASSERT(SIMPLE_OBJC_BUILD_SHOULD_WORK "CHECK_OBJC_SOURCE_COMPILES() failed, but should have succeeded")
+
+    set(CMAKE_REQUIRED_LIBRARIES "-framework Foundation")
+
+    CHECK_OBJC_SOURCE_COMPILES("#import <Foundation/Foundation.h>\nint main()\n{\nNSObject *foo;\nreturn 0;\n}\n" OBJC_BUILD_SHOULD_WORK)
+    CHECK_OBJC_SOURCE_RUNS("int main() { return 2; }" SIMPLE_OBJC_RUN_SHOULD_FAIL)
+    CHECK_OBJC_SOURCE_RUNS("int main() { return 0; }" SIMPLE_OBJC_RUN_SHOULD_WORK)
+    CHECK_OBJC_SOURCE_RUNS("#import <Foundation/Foundation.h>\nint main()\n{\nNSObject *foo;\nreturn 2;\n}\n" OBJC_RUN_SHOULD_FAIL)
+    CHECK_OBJC_SOURCE_RUNS("#import <Foundation/Foundation.h>\nint main()\n{\nNSObject *foo;\nreturn 0;\n}\n" OBJC_RUN_SHOULD_WORK)
+
+    TEST_ASSERT(OBJC_BUILD_SHOULD_WORK "CHECK_OBJC_SOURCE_COMPILES() failed, but should have succeeded")
+    TEST_FAIL(SIMPLE_OBJC_RUN_SHOULD_FAIL "CHECK_OBJC_SOURC_RUNS() succeeds, but should have failed")
+    TEST_ASSERT(SIMPLE_OBJC_RUN_SHOULD_WORK "CHECK_OBJC_SOURCE_RUNS() failed, but should have succeeded")
+    TEST_FAIL(OBJC_RUN_SHOULD_FAIL "CHECK_OBJC_SOURCE_RUNS() succeeds, but should have failed")
+    TEST_ASSERT(OBJC_RUN_SHOULD_WORK "CHECK_OBJC_SOURCE_RUNS() failed, but should have succeeded")
+
+
+    CHECK_OBJCXX_SOURCE_COMPILES("I don't build in Objective-C++" OBJCXX_BUILD_SHOULD_FAIL)
+    CHECK_OBJCXX_SOURCE_COMPILES("int main() { return 0; }" SIMPLE_OBJCXX_BUILD_SHOULD_WORK)
+
+    TEST_FAIL(OBJCXX_BUILD_SHOULD_FAIL "CHECK_OBJCXX_SOURCE_COMPILES() succeeded, but should have failed")
+    TEST_ASSERT(SIMPLE_OBJCXX_BUILD_SHOULD_WORK "CHECK_OBJCXX_SOURCE_COMPILES() failed, but should have succeeded")
+
+    CHECK_OBJCXX_SOURCE_COMPILES("#import <Foundation/Foundation.h>\n#include <iostream>\nint main()\n{\nNSObject *foo;\nstd::cout << \"Hello\" << std::endl;\nreturn 0;\n}\n" OBJCXX_BUILD_SHOULD_WORK)
+    CHECK_OBJCXX_SOURCE_RUNS("int main() { return 2; }" SIMPLE_OBJCXX_RUN_SHOULD_FAIL)
+    CHECK_OBJCXX_SOURCE_RUNS("int main() { return 0; }" SIMPLE_OBJCXX_RUN_SHOULD_WORK)
+    CHECK_OBJCXX_SOURCE_RUNS("#import <Foundation/Foundation.h>\n#include <vector>\nint main()\n{\nNSObject *foo;\nstd::vector<int> bar;\nreturn 2;\n}\n" OBJCXX_RUN_SHOULD_FAIL)
+    CHECK_OBJCXX_SOURCE_RUNS("#import <Foundation/Foundation.h>\n#include <vector>\nint main()\n{\nNSObject *foo;\nstd::vector<int> bar;\nreturn 0;\n}\n" OBJCXX_RUN_SHOULD_WORK)
+
+    TEST_ASSERT(OBJCXX_BUILD_SHOULD_WORK "CHECK_OBJCXX_SOURCE_COMPILES() failed, but should have succeeded")
+    TEST_FAIL(SIMPLE_OBJCXX_RUN_SHOULD_FAIL "CHECK_OBJCXX_SOURC_RUNS() succeeds, but should have failed")
+    TEST_ASSERT(SIMPLE_OBJCXX_RUN_SHOULD_WORK "CHECK_OBJCXX_SOURCE_RUNS() failed, but should have succeeded")
+    TEST_FAIL(OBJCXX_RUN_SHOULD_FAIL "CHECK_OBJCXX_SOURCE_RUNS() succeeds, but should have failed")
+    TEST_ASSERT(OBJCXX_RUN_SHOULD_WORK "CHECK_OBJCXX_SOURCE_RUNS() failed, but should have succeeded")
+endif()
+
 #######################################################################
 #
 # also test that the check_prototype_definition macro works