Skip to content

Handle -version argument #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 3, 2020
Merged

Conversation

cltnschlosser
Copy link
Contributor

Currently we have the following for getting the compiler version. The issue with this is that I'm getting into a state where getToolPath(.swiftCompiler) is /tmp/swift my symlink to my swift-driver. This is causing an infinite loop because swiftCompilerVersion is called from Driver.init.

public func swiftCompilerVersion() throws -> String {
    try Process.checkNonZeroExit(
      args: getToolPath(.swiftCompiler).pathString, "-version",
      environment: env
    ).split(separator: "\n").first.map(String.init) ?? ""
  }

So taking a step back:
Should getToolPath(.swiftCompiler) ever point to my symlink?
If no, what am I doing wrong (was following the README).
If yes, then the implementation needs to change, the code below is in Basic/Version.cpp. Are these constants something we could have access to when building the driver? Does it even make sense for the driver to know about all these versions?

std::string getSwiftFullVersion(Version effectiveVersion) {
  std::string buf;
  llvm::raw_string_ostream OS(buf);

#ifdef SWIFT_VENDOR
  OS << SWIFT_VENDOR " ";
#endif

  OS << "Swift version " SWIFT_VERSION_STRING;
#ifndef SWIFT_COMPILER_VERSION
  OS << "-dev";
#endif

  if (!(effectiveVersion == Version::getCurrentLanguageVersion())) {
    OS << " effective-" << effectiveVersion;
  }

#if defined(SWIFT_COMPILER_VERSION)
  OS << " (swiftlang-" SWIFT_COMPILER_VERSION;
#if defined(CLANG_COMPILER_VERSION)
  OS << " clang-" CLANG_COMPILER_VERSION;
#endif
  OS << ")";
#elif defined(LLVM_REVISION) || defined(CLANG_REVISION) || \
      defined(SWIFT_REVISION)
  OS << " (";
  printFullRevisionString(OS);
  OS << ")";
#endif

  // Suppress unused function warning
  (void)&printFullRevisionString;

  return OS.str();
}

@cltnschlosser
Copy link
Contributor Author

@DougGregor ran into this issue when trying to use swift-driver with MovieSwiftUI

@DougGregor
Copy link
Member

Hmm. I think this issue with the symlinks was introduced via #25, where we reworked how tools are found, and I'm seeing it here, too. There are a few solutions:

  • As a short-term hack, delete your swift symlink: Xcode will point at your swiftc symlink, but the driver is looking for swift so it will go find the real Swift compiler.
  • The -driver-use-frontend-path option lets you specify exactly which Swift compiler to use. However, it's broken! I'm fixing it via Respect -driver-use-frontend-path throughout job creation #50
  • At some point, I'll land [CMake] Make swift-frontend the primary Swift binary. swift#28003 to make the Swift frontend (the real compiler) named swift-frontend, so we'll look for that. Then swift and swiftc are reserved for the driver, whether it's the old one or the new one.

@cltnschlosser cltnschlosser marked this pull request as ready for review January 3, 2020 17:40
@cltnschlosser
Copy link
Contributor Author

@DougGregor Using -driver-use-frontend-path I was able to verify that this works like the cpp driver. This forwards the version check to the compiler. (I think technically this is handled in the cpp driver and not the compiler, but it's using versions that are unique to the compiler).

@@ -632,6 +641,11 @@ extension Driver {

return try exec(path: tool, args: arguments)
}

private func printVersion<S: OutputByteStream>(outputStream: inout S) throws {
outputStream.write(try Process.checkNonZeroExit(args: swiftCompiler.pathString, "--version"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically in line with what we're doing today, but it reminds me that we shouldn't probably virtualize standard output / standard error for library clients. Constructing a Driver instance that happens to print help or version information shouldn't pollute the clients standard output / standard error: they should be able to capture that output themselves. Similarly, I could imagine clients wanting to handle process execution themselves rather than having the Driver initializer directly invoking processes. (Again, for another PR. This follows the precedent already established)

@DougGregor
Copy link
Member

@swift-ci please test

1 similar comment
@DougGregor
Copy link
Member

@swift-ci please test

@DougGregor DougGregor merged commit 44ff59f into swiftlang:master Jan 3, 2020
@cltnschlosser cltnschlosser deleted the cs_version branch January 3, 2020 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants