Pārlūkot izejas kodu

Merge topic 'objc-trycompile' into release-3.16

7447aa4b34 ObjC: Add try_compile support

Acked-by: Kitware Robot <[email protected]>
Merge-request: !4006
Brad King 6 gadi atpakaļ
vecāks
revīzija
5e328c6d74

+ 128 - 80
Source/cmCoreTryCompile.cxx

@@ -136,13 +136,19 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
   std::string copyFile;
   std::string copyFileError;
   std::string cStandard;
+  std::string objcStandard;
   std::string cxxStandard;
+  std::string objcxxStandard;
   std::string cudaStandard;
   std::string cStandardRequired;
   std::string cxxStandardRequired;
+  std::string objcStandardRequired;
+  std::string objcxxStandardRequired;
   std::string cudaStandardRequired;
   std::string cExtensions;
   std::string cxxExtensions;
+  std::string objcExtensions;
+  std::string objcxxExtensions;
   std::string cudaExtensions;
   std::vector<std::string> targets;
   std::vector<std::string> linkOptions;
@@ -154,12 +160,18 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
   bool didCopyFileError = false;
   bool didCStandard = false;
   bool didCxxStandard = false;
+  bool didObjCStandard = false;
+  bool didObjCxxStandard = false;
   bool didCudaStandard = false;
   bool didCStandardRequired = false;
   bool didCxxStandardRequired = false;
+  bool didObjCStandardRequired = false;
+  bool didObjCxxStandardRequired = false;
   bool didCudaStandardRequired = false;
   bool didCExtensions = false;
   bool didCxxExtensions = false;
+  bool didObjCExtensions = false;
+  bool didObjCxxExtensions = false;
   bool didCudaExtensions = false;
   bool useSources = argv[2] == "SOURCES";
   std::vector<std::string> sources;
@@ -176,12 +188,18 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     DoingCopyFileError,
     DoingCStandard,
     DoingCxxStandard,
+    DoingObjCStandard,
+    DoingObjCxxStandard,
     DoingCudaStandard,
     DoingCStandardRequired,
     DoingCxxStandardRequired,
+    DoingObjCStandardRequired,
+    DoingObjCxxStandardRequired,
     DoingCudaStandardRequired,
     DoingCExtensions,
     DoingCxxExtensions,
+    DoingObjCExtensions,
+    DoingObjCxxExtensions,
     DoingCudaExtensions,
     DoingSources,
     DoingCMakeInternal
@@ -212,6 +230,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     } else if (argv[i] == "CXX_STANDARD") {
       doing = DoingCxxStandard;
       didCxxStandard = true;
+    } else if (argv[i] == "OBJC_STANDARD") {
+      doing = DoingObjCStandard;
+      didObjCStandard = true;
+    } else if (argv[i] == "OBJCXX_STANDARD") {
+      doing = DoingObjCxxStandard;
+      didObjCxxStandard = true;
     } else if (argv[i] == "CUDA_STANDARD") {
       doing = DoingCudaStandard;
       didCudaStandard = true;
@@ -221,6 +245,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     } else if (argv[i] == "CXX_STANDARD_REQUIRED") {
       doing = DoingCxxStandardRequired;
       didCxxStandardRequired = true;
+    } else if (argv[i] == "OBJC_STANDARD_REQUIRED") {
+      doing = DoingObjCStandardRequired;
+      didObjCStandardRequired = true;
+    } else if (argv[i] == "OBJCXX_STANDARD_REQUIRED") {
+      doing = DoingObjCxxStandardRequired;
+      didObjCxxStandardRequired = true;
     } else if (argv[i] == "CUDA_STANDARD_REQUIRED") {
       doing = DoingCudaStandardRequired;
       didCudaStandardRequired = true;
@@ -230,6 +260,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     } else if (argv[i] == "CXX_EXTENSIONS") {
       doing = DoingCxxExtensions;
       didCxxExtensions = true;
+    } else if (argv[i] == "OBJC_EXTENSIONS") {
+      doing = DoingObjCExtensions;
+      didObjCExtensions = true;
+    } else if (argv[i] == "OBJCXX_EXTENSIONS") {
+      doing = DoingObjCxxExtensions;
+      didObjCxxExtensions = true;
     } else if (argv[i] == "CUDA_EXTENSIONS") {
       doing = DoingCudaExtensions;
       didCudaExtensions = true;
@@ -285,6 +321,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     } else if (doing == DoingCxxStandard) {
       cxxStandard = argv[i];
       doing = DoingNone;
+    } else if (doing == DoingObjCStandard) {
+      objcStandard = argv[i];
+      doing = DoingNone;
+    } else if (doing == DoingObjCxxStandard) {
+      objcxxStandard = argv[i];
+      doing = DoingNone;
     } else if (doing == DoingCudaStandard) {
       cudaStandard = argv[i];
       doing = DoingNone;
@@ -294,6 +336,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     } else if (doing == DoingCxxStandardRequired) {
       cxxStandardRequired = argv[i];
       doing = DoingNone;
+    } else if (doing == DoingObjCStandardRequired) {
+      objcStandardRequired = argv[i];
+      doing = DoingNone;
+    } else if (doing == DoingObjCxxStandardRequired) {
+      objcxxStandardRequired = argv[i];
+      doing = DoingNone;
     } else if (doing == DoingCudaStandardRequired) {
       cudaStandardRequired = argv[i];
       doing = DoingNone;
@@ -303,6 +351,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     } else if (doing == DoingCxxExtensions) {
       cxxExtensions = argv[i];
       doing = DoingNone;
+    } else if (doing == DoingObjCExtensions) {
+      objcExtensions = argv[i];
+      doing = DoingNone;
+    } else if (doing == DoingObjCxxExtensions) {
+      objcxxExtensions = argv[i];
+      doing = DoingNone;
     } else if (doing == DoingCudaExtensions) {
       cudaExtensions = argv[i];
       doing = DoingNone;
@@ -754,16 +808,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     fprintf(fout, ")\n");
 
     bool const testC = testLangs.find("C") != testLangs.end();
+    bool const testObjC = testLangs.find("OBJC") != testLangs.end();
     bool const testCxx = testLangs.find("CXX") != testLangs.end();
+    bool const testObjCxx = testLangs.find("OBJCXX") != testLangs.end();
     bool const testCuda = testLangs.find("CUDA") != testLangs.end();
 
     bool warnCMP0067 = false;
     bool honorStandard = true;
 
-    if (!didCStandard && !didCxxStandard && !didCudaStandard &&
-        !didCStandardRequired && !didCxxStandardRequired &&
-        !didCudaStandardRequired && !didCExtensions && !didCxxExtensions &&
-        !didCudaExtensions) {
+    if (!didCStandard && !didCxxStandard && !didObjCStandard &&
+        !didObjCxxStandard && !didCudaStandard && !didCStandardRequired &&
+        !didCxxStandardRequired && !didObjCStandardRequired &&
+        !didObjCxxStandardRequired && !didCudaStandardRequired &&
+        !didCExtensions && !didCxxExtensions && !didObjCExtensions &&
+        !didObjCxxExtensions && !didCudaExtensions) {
       switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
         case cmPolicies::WARN:
           warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
@@ -786,45 +844,42 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
     }
 
     if (honorStandard || warnCMP0067) {
-      if (testC) {
-        if (!didCStandard) {
-          cStandard = this->LookupStdVar("CMAKE_C_STANDARD", warnCMP0067);
-        }
-        if (!didCStandardRequired) {
-          cStandardRequired =
-            this->LookupStdVar("CMAKE_C_STANDARD_REQUIRED", warnCMP0067);
-        }
-        if (!didCExtensions) {
-          cExtensions = this->LookupStdVar("CMAKE_C_EXTENSIONS", warnCMP0067);
-        }
-      }
-      if (testCxx) {
-        if (!didCxxStandard) {
-          cxxStandard = this->LookupStdVar("CMAKE_CXX_STANDARD", warnCMP0067);
-        }
-        if (!didCxxStandardRequired) {
-          cxxStandardRequired =
-            this->LookupStdVar("CMAKE_CXX_STANDARD_REQUIRED", warnCMP0067);
-        }
-        if (!didCxxExtensions) {
-          cxxExtensions =
-            this->LookupStdVar("CMAKE_CXX_EXTENSIONS", warnCMP0067);
-        }
-      }
-      if (testCuda) {
-        if (!didCudaStandard) {
-          cudaStandard =
-            this->LookupStdVar("CMAKE_CUDA_STANDARD", warnCMP0067);
-        }
-        if (!didCudaStandardRequired) {
-          cudaStandardRequired =
-            this->LookupStdVar("CMAKE_CUDA_STANDARD_REQUIRED", warnCMP0067);
-        }
-        if (!didCudaExtensions) {
-          cudaExtensions =
-            this->LookupStdVar("CMAKE_CUDA_EXTENSIONS", warnCMP0067);
-        }
-      }
+
+      auto testLanguage =
+        [&](bool testLang, bool didLangStandard, bool didLangStandardRequired,
+            bool didLangExtensions, std::string& langStandard,
+            std::string& langStandardRequired, std::string& langExtensions,
+            const std::string& lang) {
+          if (testLang) {
+            if (!didLangStandard) {
+              langStandard = this->LookupStdVar(
+                cmStrCat("CMAKE_", lang, "_STANDARD"), warnCMP0067);
+            }
+            if (!didLangStandardRequired) {
+              langStandardRequired = this->LookupStdVar(
+                cmStrCat("CMAKE_", lang, "_STANDARD_REQUIRED"), warnCMP0067);
+            }
+            if (!didLangExtensions) {
+              langExtensions = this->LookupStdVar(
+                cmStrCat("CMAKE_", lang, "_EXTENSIONS"), warnCMP0067);
+            }
+          }
+        };
+
+      testLanguage(testC, didCStandard, didCStandardRequired, didCExtensions,
+                   cStandard, cStandardRequired, cExtensions, "C");
+      testLanguage(testObjC, didObjCStandard, didObjCStandardRequired,
+                   didObjCExtensions, objcStandard, objcStandardRequired,
+                   objcExtensions, "OBJC");
+      testLanguage(testCxx, didCxxStandard, didCxxStandardRequired,
+                   didCxxExtensions, cxxStandard, cxxStandardRequired,
+                   cxxExtensions, "CXX");
+      testLanguage(testObjCxx, didObjCxxStandard, didObjCxxStandardRequired,
+                   didObjCxxExtensions, objcxxStandard, objcxxStandardRequired,
+                   objcxxExtensions, "OBJCXX");
+      testLanguage(testCuda, didCudaStandard, didCudaStandardRequired,
+                   didCudaExtensions, cudaStandard, cudaStandardRequired,
+                   cudaExtensions, "CUDA");
     }
 
     if (!this->WarnCMP0067.empty()) {
@@ -841,44 +896,37 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
       this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
     }
 
-    if (testC) {
-      if (!cStandard.empty()) {
-        writeProperty(fout, targetName, "C_STANDARD", cStandard);
-      }
-      if (!cStandardRequired.empty()) {
-        writeProperty(fout, targetName, "C_STANDARD_REQUIRED",
-                      cStandardRequired);
-      }
-      if (!cExtensions.empty()) {
-        writeProperty(fout, targetName, "C_EXTENSIONS", cExtensions);
-      }
-    }
-
-    if (testCxx) {
-      if (!cxxStandard.empty()) {
-        writeProperty(fout, targetName, "CXX_STANDARD", cxxStandard);
-      }
-      if (!cxxStandardRequired.empty()) {
-        writeProperty(fout, targetName, "CXX_STANDARD_REQUIRED",
-                      cxxStandardRequired);
-      }
-      if (!cxxExtensions.empty()) {
-        writeProperty(fout, targetName, "CXX_EXTENSIONS", cxxExtensions);
-      }
-    }
-
-    if (testCuda) {
-      if (!cudaStandard.empty()) {
-        writeProperty(fout, targetName, "CUDA_STANDARD", cudaStandard);
-      }
-      if (!cudaStandardRequired.empty()) {
-        writeProperty(fout, targetName, "CUDA_STANDARD_REQUIRED",
-                      cudaStandardRequired);
-      }
-      if (!cudaExtensions.empty()) {
-        writeProperty(fout, targetName, "CUDA_EXTENSIONS", cudaExtensions);
+    auto writeLanguageProperties = [&](bool testLang,
+                                       const std::string& langStandard,
+                                       const std::string& langStandardRequired,
+                                       const std::string& langExtensions,
+                                       const std::string& lang) {
+      if (testLang) {
+        if (!langStandard.empty()) {
+          writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD"),
+                        langStandard);
+        }
+        if (!langStandardRequired.empty()) {
+          writeProperty(fout, targetName, cmStrCat(lang, "_STANDARD_REQUIRED"),
+                        langStandardRequired);
+        }
+        if (!langExtensions.empty()) {
+          writeProperty(fout, targetName, cmStrCat(lang, "_EXTENSIONS"),
+                        langExtensions);
+        }
       }
-    }
+    };
+
+    writeLanguageProperties(testC, cStandard, cStandardRequired, cExtensions,
+                            "C");
+    writeLanguageProperties(testObjC, objcStandard, objcStandardRequired,
+                            objcExtensions, "OBJC");
+    writeLanguageProperties(testCxx, cxxStandard, cxxStandardRequired,
+                            cxxExtensions, "CXX");
+    writeLanguageProperties(testObjCxx, objcxxStandard, objcxxStandardRequired,
+                            objcxxExtensions, "OBJCXX");
+    writeLanguageProperties(testCuda, cudaStandard, cudaStandardRequired,
+                            cudaExtensions, "CUDA");
 
     if (!linkOptions.empty()) {
       std::vector<std::string> options;

+ 2 - 0
Tests/RunCMake/CMakeLists.txt

@@ -313,6 +313,8 @@ function(add_RunCMake_test_try_compile)
       CMAKE_CXX_COMPILER_VERSION
       CMAKE_CXX_STANDARD_DEFAULT
       CMake_TEST_CUDA
+      CMAKE_OBJC_STANDARD_DEFAULT
+      CMAKE_OBJCXX_STANDARD_DEFAULT
       )
     if(DEFINED ${var})
       list(APPEND try_compile_ARGS -D${var}=${${var}})

+ 1 - 0
Tests/RunCMake/try_compile/ObjCStandard-result.txt

@@ -0,0 +1 @@
+1

+ 7 - 0
Tests/RunCMake/try_compile/ObjCStandard-stderr.txt

@@ -0,0 +1,7 @@
+^CMake Error at .*/Tests/RunCMake/try_compile/ObjCStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+  OBJC_STANDARD is set to invalid value '3'
++
+CMake Error at ObjCStandard.cmake:[0-9]+ \(try_compile\):
+  Failed to generate test project build system.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$

+ 7 - 0
Tests/RunCMake/try_compile/ObjCStandard.cmake

@@ -0,0 +1,7 @@
+enable_language(OBJC)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.m
+  OBJC_STANDARD 3
+  OUTPUT_VARIABLE out
+  )
+message("try_compile output:\n${out}")

+ 1 - 0
Tests/RunCMake/try_compile/ObjCxxStandard-result.txt

@@ -0,0 +1 @@
+1

+ 7 - 0
Tests/RunCMake/try_compile/ObjCxxStandard-stderr.txt

@@ -0,0 +1,7 @@
+^CMake Error at .*/Tests/RunCMake/try_compile/ObjCxxStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+  OBJCXX_STANDARD is set to invalid value '3'
++
+CMake Error at ObjCxxStandard.cmake:[0-9]+ \(try_compile\):
+  Failed to generate test project build system.
+Call Stack \(most recent call first\):
+  CMakeLists.txt:[0-9]+ \(include\)$

+ 7 - 0
Tests/RunCMake/try_compile/ObjCxxStandard.cmake

@@ -0,0 +1,7 @@
+enable_language(OBJCXX)
+try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
+  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.mm
+  OBJCXX_STANDARD 3
+  OUTPUT_VARIABLE out
+  )
+message("try_compile output:\n${out}")

+ 6 - 0
Tests/RunCMake/try_compile/RunCMakeTest.cmake

@@ -37,11 +37,17 @@ if(CMAKE_C_STANDARD_DEFAULT)
 elseif(DEFINED CMAKE_C_STANDARD_DEFAULT)
   run_cmake(CStandardNoDefault)
 endif()
+if(CMAKE_OBJC_STANDARD_DEFAULT)
+  run_cmake(ObjCStandard)
+endif()
 if(CMAKE_CXX_STANDARD_DEFAULT)
   run_cmake(CxxStandard)
 elseif(DEFINED CMAKE_CXX_STANDARD_DEFAULT)
   run_cmake(CxxStandardNoDefault)
 endif()
+if(CMAKE_OBJCXX_STANDARD_DEFAULT)
+  run_cmake(ObjCxxStandard)
+endif()
 if(CMake_TEST_CUDA)
   if(CMAKE_HOST_WIN32)
     run_cmake(CudaStandardNoDefault)

+ 4 - 0
Tests/RunCMake/try_compile/src.m

@@ -0,0 +1,4 @@
+int main()
+{
+  return 0;
+}

+ 4 - 0
Tests/RunCMake/try_compile/src.mm

@@ -0,0 +1,4 @@
+int main()
+{
+  return 0;
+}

+ 19 - 0
Tests/TryCompile/CMakeLists.txt

@@ -365,6 +365,25 @@ if (APPLE)
     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")
+
+    # try to compile a file that should compile
+    try_compile(SHOULD_PASS
+      ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+      ${TryCompile_SOURCE_DIR}/pass.m
+      OUTPUT_VARIABLE TRY_OUT)
+    if(NOT SHOULD_PASS)
+      message(SEND_ERROR "should pass failed ${TRY_OUT}")
+    endif()
+
+    # try to compile a file that should not compile
+    try_compile(SHOULD_FAIL
+      ${TryCompile_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp
+      ${TryCompile_SOURCE_DIR}/fail.m
+      OUTPUT_VARIABLE TRY_OUT)
+    if(SHOULD_FAIL)
+      message(SEND_ERROR "Should fail passed ${TRY_OUT}")
+    endif()
+
 endif()
 
 #######################################################################

+ 1 - 0
Tests/TryCompile/fail.m

@@ -0,0 +1 @@
+asdflkjasdlj

+ 4 - 0
Tests/TryCompile/pass.m

@@ -0,0 +1,4 @@
+int main()
+{
+  return 0;
+}