Skip to content

Fix Driver/driver-compile.swift #475

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 2 commits into from
Feb 10, 2021

Conversation

cltnschlosser
Copy link
Contributor

@cltnschlosser cltnschlosser commented Feb 8, 2021

  • include swiftDeps without output file map
  • diagnose multiple files with same name

TODO

@cltnschlosser cltnschlosser marked this pull request as ready for review February 9, 2021 04:47
@cltnschlosser
Copy link
Contributor Author

@swift-ci please test

@@ -219,6 +219,9 @@ public struct Driver {
.appending(component: filename + ".priors")
}

/// Whether to consider incremental compilation.
let shouldAttemptIncrementalCompilation: Bool
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if we can clean things up by running this check when we're planning the build in the first place.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, that's where it was before, in the creation of IncrementalCompilationState, but I needed this for computeSupplementaryOutputPath for -emit-reference-dependencies-path. It likely makes sense to delay this check until later, currently if incremental builds are later disabled we still pass -emit-reference-dependencies-path to the frontend. That's the c++ driver logic that I'm imitating here, so that the tests pass, but long term it's worth evaluating if that's the right approach. (I honestly don't know much about incremental builds and swiftDeps, so I can't say for sure one way or the other. My approach so far with swift-driver is trying to get it to feature parity with c++, making sure it can stand in and have the lit tests still pass.)

@CodaFi
Copy link
Contributor

CodaFi commented Feb 10, 2021

@CodaFi CodaFi merged commit 267325f into swiftlang:main Feb 10, 2021
@cltnschlosser cltnschlosser deleted the cs_test_DriverCompile branch February 10, 2021 02:34
@davidungar
Copy link
Contributor

I didn't get a change to look at this before it was merge. I doubt I would have approved it because it diffuses the knowledge about incremental compilation into the Driver, instead of the IncrementalCompilationState.
I don't understand the need to compute the reference dependencies path. Doesn't it come from the OutputFileMap?
What am I missing?
Is this mirroring some change in the legacy driver?

@cltnschlosser
Copy link
Contributor Author

@davidungar

I didn't get a change to look at this before it was merge. I doubt I would have approved it because it diffuses the knowledge about incremental compilation into the Driver, instead of the IncrementalCompilationState.
I don't understand the need to compute the reference dependencies path. Doesn't it come from the OutputFileMap?
What am I missing?
Is this mirroring some change in the legacy driver?

It's mirroring existing logic, but not a change. Maybe the old logic is all wrong, but I'll layout what I was working through.

This is the code that adds the swiftDeps, the only requirement is that Compilation.getIncrementalBuildEnabled() is true. https://github.com/apple/swift/blob/377f23f5dab2413104a1ef38c347e3b6f5d5242b/lib/Driver/Driver.cpp#L3305
This is a value set early in the driver, roughly here: https://github.com/apple/swift/blob/377f23f5dab2413104a1ef38c347e3b6f5d5242b/lib/Driver/Driver.cpp#L934

In most real world cases the path likely comes from OutputFileMap, but in the c++ driver, it was possible to output a swiftDeps file without using an OutputFileMap. This test(taken from: https://github.com/apple/swift/blob/main/test/Driver/driver-compile.swift), shows that behavior:

// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 %s -sdk %S/../Inputs/clang-importer-sdk -Xfrontend -foo -Xfrontend -bar -Xllvm -baz -Xcc -garply -F /path/to/frameworks -Fsystem /path/to/systemframeworks -F /path/to/more/frameworks -I /path/to/headers -I path/to/more/headers -module-cache-path /tmp/modules -incremental 2>&1 > %t.complex.txt
// RUN: %FileCheck %s < %t.complex.txt
// RUN: %FileCheck -check-prefix COMPLEX %s < %t.complex.txt

// COMPLEX-DAG: -emit-reference-dependencies-path {{(.*(/|\\))?driver-compile[^ /]*}}.swiftdeps

This was the failing test that now passes with this change.

@cltnschlosser
Copy link
Contributor Author

It's also worth noting that I'm pretty sure the computed path is almost never used, the important piece here is that the value is non-nil. (Kinda a hack...)

Looking at the following code, the input is only ever nil when !compilerMode.usesPrimaryFileInputs, but we short-circuit early if referenceDependenciesPath is nil.

      addOutputOfType(
        outputType: .swiftDeps,
        finalOutputPath: referenceDependenciesPath,
        input: input,
        flag: "-emit-reference-dependencies-path")
        
func addOutputOfType(
        outputType: FileType, finalOutputPath: VirtualPath?,
        input: TypedVirtualPath?, flag: String
    ) {
      // If there is no final output, there's nothing to do.
      guard let finalOutputPath = finalOutputPath else { return }

      // If the whole of the compiler output is this type, there's nothing to
      // do.
      if outputType == compilerOutputType { return }

      // Compute the output path based on the input path (if there is one), or
      // use the final output.
      let outputPath: VirtualPath
      if let input = input {
        if let outputFileMapPath = outputFileMap?.existingOutput(inputFile: input.file, outputType: outputType) {
          outputPath = outputFileMapPath
        } else if let output = inputOutputMap[input], output.file != .standardOutput, compilerOutputType != nil {
          // Alongside primary output
          outputPath = output.file.replacingExtension(with: outputType)
        } else {
          outputPath = .temporary(RelativePath(input.file.basenameWithoutExt.appendingFileTypeExtension(outputType)))
        }
      } else {
        outputPath = finalOutputPath
      }

      flaggedInputOutputPairs.append((flag: flag, input: input, output: TypedVirtualPath(file: outputPath, type: outputType)))
    }

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.

3 participants