]> granicus.if.org Git - llvm/commitdiff
Use AIX version detection at LLVM run-time
authorHubert Tong <hubert.reinterpretcast@gmail.com>
Wed, 13 Mar 2019 00:12:43 +0000 (00:12 +0000)
committerHubert Tong <hubert.reinterpretcast@gmail.com>
Wed, 13 Mar 2019 00:12:43 +0000 (00:12 +0000)
Summary:
AIX compilers define macros based on the version of the operating
system.

This patch implements updating of versionless AIX triples to include the
host AIX version. Also, the host triple detection in the build system is
adjusted to strip the AIX version information so that the run-time
detection is preferred.

Reviewers: xingxue, stefanp, nemanjai, jasonliu

Reviewed By: xingxue

Subscribers: mgorny, kristina, jdoerfert, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D58798

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355995 91177308-0d34-0410-b5e6-96231b3b80d8

cmake/modules/GetHostTriple.cmake
lib/Support/Unix/Host.inc
unittests/Support/Host.cpp

index 7b842450b726aefaa44377cb5e8212a66ec42668..9a74ad6c04aff1c67f3c2ad9eadbd9412c2fbd3c 100644 (file)
@@ -23,7 +23,8 @@ function( get_host_triple var )
     if( NOT TT_RV EQUAL 0 )
       message(FATAL_ERROR "Failed to execute ${config_guess}")
     endif( NOT TT_RV EQUAL 0 )
-    set( value ${TT_OUT} )
+    # Defer to dynamic detection of the host AIX version.
+    string(REGEX REPLACE "-aix[0-9][^-]*" "-aix" value ${TT_OUT})
   endif( MSVC )
   set( ${var} ${value} PARENT_SCOPE )
 endfunction( get_host_triple var )
index 4ae261aa8cfed57615ce208749c6f4bd3d16b928..17d78dc18be758f490fe0b82f7e95d5daa5ca5b2 100644 (file)
@@ -49,6 +49,23 @@ static std::string updateTripleOSVersion(std::string TargetTripleString) {
     TargetTripleString += "-darwin";
     TargetTripleString += getOSVersion();
   }
+  // On AIX, the AIX version and release should be that of the current host
+  // unless if the version has already been specified.
+  if (Triple(LLVM_HOST_TRIPLE).getOS() == Triple::AIX) {
+    Triple TT(TargetTripleString);
+    if (TT.getOS() == Triple::AIX && !TT.getOSMajorVersion()) {
+      struct utsname name;
+      if (uname(&name) != -1) {
+        std::string NewOSName = Triple::getOSTypeName(Triple::AIX);
+        NewOSName += name.version;
+        NewOSName += '.';
+        NewOSName += name.release;
+        NewOSName += ".0.0";
+        TT.setOSName(NewOSName);
+        return TT.str();
+      }
+    }
+  }
   return TargetTripleString;
 }
 
index b809317147587ce3bdbf1a8c5cdc079257a6863e..89080f350aaf063530f2a7e94bbf0dde051c1274 100644 (file)
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Support/Host.h"
+#include "llvm/Config/llvm-config.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/FileSystem.h"
@@ -248,6 +249,46 @@ CPU part   : 0x0a1
             "tsv110");
 }
 
+static bool runAndGetCommandOutput(
+    const char *ExePath, ArrayRef<llvm::StringRef> argv,
+    std::unique_ptr<char[]> &Buffer, off_t &Size) {
+  bool Success = false;
+  [ExePath, argv, &Buffer, &Size, &Success] {
+    using namespace llvm::sys;
+    SmallString<128> TestDirectory;
+    ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
+
+    SmallString<128> OutputFile(TestDirectory);
+    path::append(OutputFile, "out");
+    StringRef OutputPath = OutputFile.str();
+
+    const Optional<StringRef> Redirects[] = {
+        /*STDIN=*/None, /*STDOUT=*/OutputPath, /*STDERR=*/None};
+    int RetCode = ExecuteAndWait(ExePath, argv, /*env=*/llvm::None, Redirects);
+    ASSERT_EQ(0, RetCode);
+
+    int FD = 0;
+    ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
+    Size = ::lseek(FD, 0, SEEK_END);
+    ASSERT_NE(-1, Size);
+    ::lseek(FD, 0, SEEK_SET);
+    Buffer = llvm::make_unique<char[]>(Size);
+    ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
+    ::close(FD);
+
+    ASSERT_NO_ERROR(fs::remove(OutputPath));
+    ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+    Success = true;
+  }();
+  return Success;
+}
+
+TEST_F(HostTest, DummyRunAndGetCommandOutputUse) {
+  // Suppress defined-but-not-used warnings when the tests using the helper are
+  // disabled.
+  (void) runAndGetCommandOutput;
+}
+
 #if defined(__APPLE__)
 TEST_F(HostTest, getMacOSHostVersion) {
   using namespace llvm::sys;
@@ -255,31 +296,14 @@ TEST_F(HostTest, getMacOSHostVersion) {
   if (!HostTriple.isMacOSX())
     return;
 
-  SmallString<128> TestDirectory;
-  ASSERT_NO_ERROR(fs::createUniqueDirectory("host_test", TestDirectory));
-  SmallString<128> OutputFile(TestDirectory);
-  path::append(OutputFile, "out");
-
   const char *SwVersPath = "/usr/bin/sw_vers";
   StringRef argv[] = {SwVersPath, "-productVersion"};
-  StringRef OutputPath = OutputFile.str();
-  const Optional<StringRef> Redirects[] = {/*STDIN=*/None,
-                                           /*STDOUT=*/OutputPath,
-                                           /*STDERR=*/None};
-  int RetCode = ExecuteAndWait(SwVersPath, argv, /*env=*/llvm::None, Redirects);
-  ASSERT_EQ(0, RetCode);
-
-  int FD = 0;
-  ASSERT_NO_ERROR(fs::openFileForRead(OutputPath, FD));
-  off_t Size = ::lseek(FD, 0, SEEK_END);
-  ASSERT_NE(-1, Size);
-  ::lseek(FD, 0, SEEK_SET);
-  std::unique_ptr<char[]> Buffer = llvm::make_unique<char[]>(Size);
-  ASSERT_EQ(::read(FD, Buffer.get(), Size), Size);
-  ::close(FD);
+  std::unique_ptr<char[]> Buffer;
+  off_t Size;
+  ASSERT_EQ(runAndGetCommandOutput(SwVersPath, argv, Buffer, Size), true);
+  StringRef SystemVersion(Buffer.get(), Size);
 
   // Ensure that the two versions match.
-  StringRef SystemVersion(Buffer.get(), Size);
   unsigned SystemMajor, SystemMinor, SystemMicro;
   ASSERT_EQ(llvm::Triple((Twine("x86_64-apple-macos") + SystemVersion))
                 .getMacOSXVersion(SystemMajor, SystemMinor, SystemMicro),
@@ -290,8 +314,52 @@ TEST_F(HostTest, getMacOSHostVersion) {
   // Don't compare the 'Micro' version, as it's always '0' for the 'Darwin'
   // triples.
   ASSERT_EQ(std::tie(SystemMajor, SystemMinor), std::tie(HostMajor, HostMinor));
+}
+#endif
+
+#if defined(_AIX)
+TEST_F(HostTest, AIXVersionDetect) {
+  using namespace llvm::sys;
+
+  llvm::Triple HostTriple(getProcessTriple());
+  ASSERT_EQ(HostTriple.getOS(), Triple::AIX);
+
+  llvm::Triple ConfiguredHostTriple(LLVM_HOST_TRIPLE);
+  ASSERT_EQ(ConfiguredHostTriple.getOS(), Triple::AIX);
+
+  const char *ExePath = "/usr/bin/oslevel";
+  StringRef argv[] = {ExePath};
+  std::unique_ptr<char[]> Buffer;
+  off_t Size;
+  ASSERT_EQ(runAndGetCommandOutput(ExePath, argv, Buffer, Size), true);
+  StringRef SystemVersion(Buffer.get(), Size);
+
+  unsigned SystemMajor, SystemMinor, SystemMicro;
+  llvm::Triple((Twine("powerpc-ibm-aix") + SystemVersion))
+      .getOSVersion(SystemMajor, SystemMinor, SystemMicro);
+
+  // Ensure that the host triple version (major) and release (minor) numbers,
+  // unless explicitly configured, match with those of the current system.
+  if (!ConfiguredHostTriple.getOSMajorVersion()) {
+    unsigned HostMajor, HostMinor, HostMicro;
+    HostTriple.getOSVersion(HostMajor, HostMinor, HostMicro);
+    ASSERT_EQ(std::tie(SystemMajor, SystemMinor),
+              std::tie(HostMajor, HostMinor));
+  }
+
+  llvm::Triple TargetTriple(getDefaultTargetTriple());
+  if (TargetTriple.getOS() != Triple::AIX)
+    return;
+
+  // Ensure that the target triple version (major) and release (minor) numbers
+  // match with those of the current system.
+  llvm::Triple ConfiguredTargetTriple(LLVM_DEFAULT_TARGET_TRIPLE);
+  if (ConfiguredTargetTriple.getOSMajorVersion())
+    return; // The version was configured explicitly; skip.
 
-  ASSERT_NO_ERROR(fs::remove(OutputPath));
-  ASSERT_NO_ERROR(fs::remove(TestDirectory.str()));
+  unsigned TargetMajor, TargetMinor, TargetMicro;
+  TargetTriple.getOSVersion(TargetMajor, TargetMinor, TargetMicro);
+  ASSERT_EQ(std::tie(SystemMajor, SystemMinor),
+            std::tie(TargetMajor, TargetMinor));
 }
 #endif