Skip to content

Conversation

lacasseio
Copy link
Contributor

@lacasseio lacasseio commented Nov 30, 2017

Context

Fixes gradle/gradle-native#192

Gradle Core Team Checklist

  • Verify design and implementation
  • Verify test coverage and CI build status
  • Verify documentation
  • Recognize contributor in release notes

@lacasseio lacasseio added a:feature A new functionality from:member in:native-platform c, cpp, swift and other native languages support, etc labels Nov 30, 2017
@lacasseio lacasseio added this to the 4.5 RC1 milestone Nov 30, 2017
@lacasseio lacasseio self-assigned this Nov 30, 2017
@lacasseio lacasseio force-pushed the lacasseio/native/improve-xcode-ide branch 3 times, most recently from 4473fb0 to 1da0b37 Compare November 30, 2017 06:40
@big-guy big-guy self-requested a review November 30, 2017 20:34
succeeds 'xcode'

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode")
Copy link
Contributor

Choose a reason for hiding this comment

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

We should have built the binaries for the greeter library as well, otherwise this workspace isn't going to be useable.

Copy link
Contributor

Choose a reason for hiding this comment

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

We should add some coverage for the case where the headers are buildable, and make sure they get built.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I may be wrong, but I don't think we have any coverage for buildable headers for Xcode. I wouldn't pull this feature in this PR as it would mean adding it to all of Xcode and will most likely send the PR into a rabbit hole. I would try to stay focus on a single feature and do another PR for this use case instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With regards to building the greeter library, we don't really need to build it as Xcode delegate to Gradle on every build which will ensure that greeter library is built.

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode",
":greeter:xcodeProject", ":greeter:xcodeProjectWorkspaceSettings", ":greeter:xcodeSchemeGreeterSharedLibrary")
rootXcodeWorkspace.contentFile.assertHasProjects("${rootProjectName}.xcodeproj", "${checkoutRelativeDir(repo.name, commit.id.name, repo.id)}/greeter.xcodeproj")
Copy link
Contributor

Choose a reason for hiding this comment

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

we don't want the greeter library to be included in the workspace as a project, but as binaries.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

succeeds 'xcode'

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode")
Copy link
Contributor

Choose a reason for hiding this comment

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

should build the binaries of greeter library

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

Choose a reason for hiding this comment

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

you should update the test to show that the binaries of the greeter library are built. I'm not seeing any changes here.


then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode",
":greeter:xcodeProject", ":greeter:xcodeProjectWorkspaceSettings", ":greeter:xcodeSchemeGreeterSharedLibrary")
Copy link
Contributor

Choose a reason for hiding this comment

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

should build the binaries of the greeter library, not the project files.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode",
":greeter:xcodeProject", ":greeter:xcodeProjectWorkspaceSettings", ":greeter:xcodeSchemeGreeterSharedLibrary")
rootXcodeWorkspace.contentFile.assertHasProjects("${rootProjectName}.xcodeproj", "${checkoutRelativeDir(repo.name, commit.id.name, repo.id)}/greeter.xcodeproj")
Copy link
Contributor

Choose a reason for hiding this comment

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

should not include the greeter library as a project in the workspace, but as binaries.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


import static org.gradle.ide.xcode.internal.XcodeUtils.toSpaceSeparatedList

class XcodeCppExternalSourceDependenciesIntegrationTest extends AbstractXcodeIntegrationSpec {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should add some test coverage where the root project is only a container that does not define any components, and there are 2 subprojects with an application defined in one and library in the other.

Should also cover the case where there are sub projects that don't define any components.

debugSettings.put("SWIFT_INCLUDE_PATHS", toSpaceSeparatedList(xcodeTarget.getCompileModules()));
releaseSettings.put("SWIFT_INCLUDE_PATHS", toSpaceSeparatedList(xcodeTarget.getCompileModules()));
testRunnerSettings.put("SWIFT_INCLUDE_PATHS", toSpaceSeparatedList(xcodeTarget.getCompileModules()));
debugSettings.put("SWIFT_INCLUDE_PATHS", toSpaceSeparatedList(parentDirs(xcodeTarget.getCompileModules())));
Copy link
Contributor

Choose a reason for hiding this comment

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

I think I broke that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not that it was broken, it's just that it didn't behave like everything else.


def ipr = getFile([:], 'root.ipr').text
assert ipr.contains(''' <component name="ProjectModuleManager">
<modules>
Copy link
Contributor

Choose a reason for hiding this comment

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

isn't there a fixture method that does this? Perhaps add it if not.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

return regularFile.getAsFile().getParentFile();
}
}))));
.add(new DefaultSelfResolvingDependency((FileCollectionInternal)project.files(((DefaultSwiftBinary)testedComponent.getDevelopmentBinary()).getModuleFile())));
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can replace the construction of a DefaultSelfResolvingDependency with a call to project.getDependencies().create(project.files(testedComponent.getDevelopmentBinary().getModuleFile())

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will look into that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

LocalComponentArtifactMetadata imlArtifact = localComponentRegistry.findAdditionalArtifact(otherProjectId, "iml");
if (imlArtifact != null) {
xmlProject.addModulePath(imlArtifact.getFile());
Iterator<IdePlugin> it = project.getPlugins().withType(IdePlugin.class).iterator();
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic should live in the plugin. The plugin should create a lazy list of some kind and attach it to this model object, rather than having the model reach across and try to figure out which plugin created it. This removes some complexity.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was trying to move the logic out of there, but I kept running into backward compatibility. If we diverge too much from what we have now, we may break a lot of people that may be using the model in some untested ways. We may be alright with such breakage. I will look at the code again to see if I can remove this.

Copy link
Contributor

Choose a reason for hiding this comment

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

The thing to do here would be to make Project.modulePaths as lazily configured property. That is, add a new property of type SetProperty<Path> and have the old methods delegate to this. Then, the IDEA plugin can add a Provider<Path> to this that provides the convention.

We'd do something similar on the Eclipse and Xcode (and Visual studio) models as well.

Oh, and we'd have to add SetProperty too.

I'd get the Xcode project generation happening correctly first in this PR, then get the Xcode workspace generation happening correctly in the next PR and then finally roll this out to the IDEA and Eclipse and Visual Studio plugins in a later PR (or multiple PRs).

Copy link
Contributor Author

@lacasseio lacasseio left a comment

Choose a reason for hiding this comment

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

Here are some preliminary comments on the code review. It could be useful to discuss some of them.

succeeds 'xcode'

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I may be wrong, but I don't think we have any coverage for buildable headers for Xcode. I wouldn't pull this feature in this PR as it would mean adding it to all of Xcode and will most likely send the PR into a rabbit hole. I would try to stay focus on a single feature and do another PR for this use case instead.


then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode",
":greeter:xcodeProject", ":greeter:xcodeProjectWorkspaceSettings", ":greeter:xcodeSchemeGreeterSharedLibrary")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is exactly the issue I was having and trying to figure out. The code that finds all xcodeproj will search any project/included build that defines xcodeproj artifact. If the source dependency applies the xcode plugin, the root build will find the xcodeproj files and will try to include them. I was asking how to find out is a particular included build was included because of source dependency so we can exclude them. Otherwise, they are going to be included and there isn't much we can do about it (with the current code).

If we only populate the import paths and search directories, all works fine in term of symbol discovery, but the Swift experience may not be the best as you won't be able to jump to the source code. Instead, you will jump to the Swift file representation of the .swiftmodule which only show the class/function prototype.

The middle ground is to include them as normal, but any change to the project source file will be overwritten on each build as Gradle will do a git reset --hard on the folder. This way you can jump to the implementation, but won't be able to change it.

succeeds 'xcode'

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

With regards to building the greeter library, we don't really need to build it as Xcode delegate to Gradle on every build which will ensure that greeter library is built.

project.getConfigurations().getByName("ide").getResolvedConfiguration();

return CollectionUtils.collect(
allXcodeprojArtifactsInComposite(serviceRegistry),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure I completely understand. We aren't changing how we include project files in the workspace. The getIdeArtifactMetadata is the same implementation of what used to be allXcodeprojArtifactsInComposite. The reason why we are forcing the resolution is because workspace.dependsOn will not find the source dependency project as they weren't evaluated yet. This means they are not part of the ProjectPathRegistry. However when the task executes and resolve workspaceTask.setXcodeProjectLocations, the source dependency project have been evaluated and now we find the Xcode project path. This cause the workspace to include Xcode project that will not be built because we don't have any task dependency on them.

You are right that we could add a dependency from Xcode project generation task to binary compile configuration. This would, in fact, fix some of the problems, maybe all of them, that we have now.

debugSettings.put("SWIFT_INCLUDE_PATHS", toSpaceSeparatedList(xcodeTarget.getCompileModules()));
releaseSettings.put("SWIFT_INCLUDE_PATHS", toSpaceSeparatedList(xcodeTarget.getCompileModules()));
testRunnerSettings.put("SWIFT_INCLUDE_PATHS", toSpaceSeparatedList(xcodeTarget.getCompileModules()));
debugSettings.put("SWIFT_INCLUDE_PATHS", toSpaceSeparatedList(parentDirs(xcodeTarget.getCompileModules())));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's not that it was broken, it's just that it didn't behave like everything else.

LocalComponentArtifactMetadata imlArtifact = localComponentRegistry.findAdditionalArtifact(otherProjectId, "iml");
if (imlArtifact != null) {
xmlProject.addModulePath(imlArtifact.getFile());
Iterator<IdePlugin> it = project.getPlugins().withType(IdePlugin.class).iterator();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was trying to move the logic out of there, but I kept running into backward compatibility. If we diverge too much from what we have now, we may break a lot of people that may be using the model in some untested ways. We may be alright with such breakage. I will look at the code again to see if I can remove this.

return regularFile.getAsFile().getParentFile();
}
}))));
.add(new DefaultSelfResolvingDependency((FileCollectionInternal)project.files(((DefaultSwiftBinary)testedComponent.getDevelopmentBinary()).getModuleFile())));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will look into that.

@lacasseio lacasseio force-pushed the lacasseio/native/improve-xcode-ide branch from 1da0b37 to 429c773 Compare December 4, 2017 06:51
Copy link
Contributor Author

@lacasseio lacasseio left a comment

Choose a reason for hiding this comment

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

It should be mostly fixed. I differ the final fix for IdeaPlugin in another PR. This PR only offers a partial fix (remove the code duplication but doesn't introduce SetProperty).

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode",
":greeter:xcodeProject", ":greeter:xcodeProjectWorkspaceSettings", ":greeter:xcodeSchemeGreeterSharedLibrary")
rootXcodeWorkspace.contentFile.assertHasProjects("${rootProjectName}.xcodeproj", "${checkoutRelativeDir(repo.name, commit.id.name, repo.id)}/greeter.xcodeproj")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

succeeds 'xcode'

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode",
":greeter:xcodeProject", ":greeter:xcodeProjectWorkspaceSettings", ":greeter:xcodeSchemeGreeterSharedLibrary")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode",
":greeter:xcodeProject", ":greeter:xcodeProjectWorkspaceSettings", ":greeter:xcodeSchemeGreeterSharedLibrary")
rootXcodeWorkspace.contentFile.assertHasProjects("${rootProjectName}.xcodeproj", "${checkoutRelativeDir(repo.name, commit.id.name, repo.id)}/greeter.xcodeproj")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

succeeds 'xcode'

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppSharedLibrary", ":xcode")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppSharedLibrary", ":xcode",
":greeter:xcodeProject", ":greeter:xcodeProjectWorkspaceSettings", ":greeter:xcodeSchemeGreeterSharedLibrary")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

project.getConfigurations().getByName("ide").getResolvedConfiguration();

return CollectionUtils.collect(
allXcodeprojArtifactsInComposite(serviceRegistry),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The ide configuration is removed.

project.getConfigurations().getByName("ide").getResolvedConfiguration();

return CollectionUtils.collect(
allXcodeprojArtifactsInComposite(serviceRegistry),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think I understand your idea now. Have a look at the latest changes.

return regularFile.getAsFile().getParentFile();
}
}))));
.add(new DefaultSelfResolvingDependency((FileCollectionInternal)project.files(((DefaultSwiftBinary)testedComponent.getDevelopmentBinary()).getModuleFile())));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


def ipr = getFile([:], 'root.ipr').text
assert ipr.contains(''' <component name="ProjectModuleManager">
<modules>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


/**
* Returns an path for every implicit project in a build, including projects from included builds.
* Always returns the same set for the lifetime of the build.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this is true, and even if it is, it shouldn't be part of the contract. Implicit builds can be added at pretty much any time, and consumers of this interface should deal with this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Does this mean we should also remove this mention from the getAllProjectPaths?


/**
* Returns an path for every explicit project in a build, including projects from included builds.
* Always returns the same set for the lifetime of the build.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it should.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

appProject.indexTarget.getBuildSettings().HEADER_SEARCH_PATHS == toSpaceSeparatedList(file('src/main/headers'), checkoutDir(repo.name, commit.id.name, repo.id).file('src/main/public'))
}

def "adds source dependencies Swift module of main component to Xcode indexer search path when no component in root project"() {
Copy link
Contributor

Choose a reason for hiding this comment

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

"Swift" should be "C++"?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, done.

succeeds 'xcode'

then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode")
Copy link
Contributor

Choose a reason for hiding this comment

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

you should update the test to show that the binaries of the greeter library are built. I'm not seeing any changes here.


then:
executedAndNotSkipped(":xcodeProject", ":xcodeProjectWorkspaceSettings", ":xcodeSchemeAppExecutable", ":xcode")
rootXcodeWorkspace.contentFile.assertHasProjects("${rootProjectName}.xcodeproj")//, "${checkoutRelativeDir(repo.name, commit.id.name, repo.id)}/greeter.xcodeproj")
Copy link
Contributor

Choose a reason for hiding this comment

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

should get rid of the dead code in the comment

succeeds 'xcode'

then:
executedAndNotSkipped(":app:xcodeProject", ":app:xcodeProjectWorkspaceSettings", ":app:xcodeSchemeAppExecutable",
Copy link
Contributor

Choose a reason for hiding this comment

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

should show that the module file of the greeter library is built.

}

@Internal
@Optional
Copy link
Contributor

Choose a reason for hiding this comment

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

why optional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, removed.

"""

//when
executer.usingBuildScript(buildFile).usingSettingsFile(settingsFile).withTasks("idea").run()
Copy link
Contributor

Choose a reason for hiding this comment

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

can you make this a spock test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@Override
public List<FileCollection> call() throws Exception {
return CollectionUtils.collect(
getIdeArtifactMetadata("xcodeproj"),
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this parameter should be type

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, changed.


for (Path projectPath : projectPathRegistry.getAllExplicitProjectPaths()) {
ProjectComponentIdentifier projectId = projectPathRegistry.getProjectComponentIdentifier(projectPath);
LocalComponentArtifactMetadata xcodeprojArtifact = localComponentRegistry.findAdditionalArtifact(projectId, type);
Copy link
Contributor

Choose a reason for hiding this comment

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

variable should probably not have xcodeproj in its name

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, changed.

@adammurdoch
Copy link
Contributor

adammurdoch commented Dec 5, 2017

You're still trying to change how the workspace is generated. You should instead change how the project file is generated. Otherwise the result is wrong and is working by coincidence only.

Specifically:

  1. Filter the cpp compile configuration to remove the project components that will be included as xcode projects, attach this as an input to the project generation task, to generate the header path in the xcode project file.
  2. Filter the swift compile configuration in the same way, attach this as input to the project generation task, to generate the module search path in the xcode project file.

@lacasseio lacasseio force-pushed the lacasseio/native/improve-xcode-ide branch from 86e5eb8 to d75fe42 Compare December 6, 2017 06:54
@lacasseio
Copy link
Contributor Author

I think I understood what you wanted Adam. Basically, we want to ensure that Swift module and headers are present for source dependencies as they should build be able to compile without issue as opposed to the Swift module and headers from the current build where they could have failures in it which would be annoying when generating the Xcode project.

I had to add some additional modification to make the filtering work such as exposing the include path configuration for C++ and exposing the Swift module of the application so it can be consumed by XCTest as well as filtered out when adding the task dependencies.

CI is running and you can have another look at the code.

@lacasseio lacasseio force-pushed the lacasseio/native/improve-xcode-ide branch from d75fe42 to c51847c Compare December 7, 2017 03:29

def appProject = xcodeProject("${rootProjectName}.xcodeproj").projectFile
appProject.targets.find { it.isUnitTest() }.getBuildSettings().SWIFT_INCLUDE_PATHS == toSpaceSeparatedList(file('build/modules/main/debug'), checkoutDir(repo.name, commit.id.name, repo.id).file('build/modules/main/debug'))
appProject.indexTarget.getBuildSettings().SWIFT_INCLUDE_PATHS == toSpaceSeparatedList(file('build/modules/main/debug'), checkoutDir(repo.name, commit.id.name, repo.id).file('build/modules/main/debug'))
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do we need to add the main module file here when we don't in the previous cases? I would guess that Xcode doesn't need that connection between the tests and production sources for a project to be made explicit like this. If we do add it to the include path, we should probably build it during generation, so that the result doesn't change when Gradle builds the modules later on.

This isn't related to this PR, but it's something we should tidy up as a separate issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are so right. My bad for not questioning this enough when developing this code. I will open an issue for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Issue created: gradle/gradle-native#331.

public ConfigurableFileCollection getCompileModules() {
return compileModules;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

The headerSearchPath, compileModules and sources file collections should all just carry the task dependency information. These task dependencies shouldn't be tracked separately, otherwise they get out of sync, for example when someone adds something to the header file set but we don't update the task dependencies. Or when someone queries the files but forgets to query the task dependencies.

Maybe just merge what we have here and we can simplify it later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with you on this. When I discuss this with Sterling, we figure that changing the model to correctly add @Input annotation or changing the task to take individual properties would have been too risky of going down a rabbit hole. I will open an issue for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Issue created: gradle/gradle-native#332.


Configuration implementation = application.getImplementationDependencies();

Configuration debugApiElements = configurations.maybeCreate("debugSwiftApiElements");
Copy link
Contributor

Choose a reason for hiding this comment

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

An application doesn't provide a Swift API, otherwise it's a library. We shouldn't be adding these configurations.

Maybe just merge this for now and we can remove these later.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought the same thing when I was writing this and would have wanted to discuss it with you. The issue I was having is when we add a dependency from the test component on the main component, the artifactView wasn't filtering out the main component because the way we used to add it didn't add a ComponentIdentifier. This ended up compiling the code from the main component in if XCTest plugin was applied. My thinking is this allow someone to add a test on the main component in a different project. I'm not sure if this is something we want, but it's something that is valid. I will open an issue for this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Issue created: gradle/gradle-native#333.

Copy link
Contributor Author

@lacasseio lacasseio left a comment

Choose a reason for hiding this comment

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

Thanks for the awesome feedback Adam. I will merge it now and open/link issues tomorrow.

public ConfigurableFileCollection getCompileModules() {
return compileModules;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with you on this. When I discuss this with Sterling, we figure that changing the model to correctly add @Input annotation or changing the task to take individual properties would have been too risky of going down a rabbit hole. I will open an issue for this.


def appProject = xcodeProject("${rootProjectName}.xcodeproj").projectFile
appProject.targets.find { it.isUnitTest() }.getBuildSettings().SWIFT_INCLUDE_PATHS == toSpaceSeparatedList(file('build/modules/main/debug'), checkoutDir(repo.name, commit.id.name, repo.id).file('build/modules/main/debug'))
appProject.indexTarget.getBuildSettings().SWIFT_INCLUDE_PATHS == toSpaceSeparatedList(file('build/modules/main/debug'), checkoutDir(repo.name, commit.id.name, repo.id).file('build/modules/main/debug'))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are so right. My bad for not questioning this enough when developing this code. I will open an issue for this.


Configuration implementation = application.getImplementationDependencies();

Configuration debugApiElements = configurations.maybeCreate("debugSwiftApiElements");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought the same thing when I was writing this and would have wanted to discuss it with you. The issue I was having is when we add a dependency from the test component on the main component, the artifactView wasn't filtering out the main component because the way we used to add it didn't add a ComponentIdentifier. This ended up compiling the code from the main component in if XCTest plugin was applied. My thinking is this allow someone to add a test on the main component in a different project. I'm not sure if this is something we want, but it's something that is valid. I will open an issue for this.

@lacasseio lacasseio merged commit 94b2b96 into master Dec 7, 2017
@lacasseio lacasseio deleted the lacasseio/native/improve-xcode-ide branch December 7, 2017 08:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a:feature A new functionality in:native-platform c, cpp, swift and other native languages support, etc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants