Skip to content
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

Linux support #585

Merged
merged 14 commits into from
Nov 11, 2020
Merged

Conversation

elliottwilliams
Copy link
Contributor

I've been interested in getting XcodeProj compiling and running on Linux. It turns out that it's possible!

Linux support is obviously a little esoteric, but I think it's valuable for users that want to integrate this tool into automated systems which are linux-based. For example: at Yelp, we have a ton of Linux CI capacity and lots of infra that makes it easy to run git-based workflows on linux servers, and being able to use XcodeProj and XcodeGen from them would simplify our tools.

Implementation 👩‍💻👨‍💻

  • Removes XcodeProjCExt, which was added in Optimize bottlenecks #529. This library was based on CommonCrypto which is macOS-only. I've tried to move things back to Swift while retaining the performance gains of the C library:

    • CommentedString.validString is a new implementation that operates in a single pass of the string in the optimal case. In my testing I've been able to get this 30% of the performance of the C implementation. If you'd like, I can go further, but it probably means switching to pointer APIs to avoid ARC overhead.
    • String.md5 includes the old implementation, but uses CryptoKit when it's available.
  • Changes the sourcery template to generate non-overriding functions. Swift's language model doesn't support overriding in extensions, only allowing it for backwards compatibility with objc. When compiling on linux, objc support is not present and it fails.

    • Sourcery now generates internally-visible comparison functions, and I've added a boilerplate override to each model object to call the appropriate comparison.
  • Small fixups:

    • Bumped AEXML to 4.6.0 to fix an issue with importing Foundation on Linux
    • Glibc glob support
    • Support for running PBXProjIntegrationTests on a system with no git author (so that tests pass from a Docker image)

Verification

You can build and test this branch on a linux system using Swift's official docker images:

$ docker pull swift:5.3  # grab swift from docker hub
$ docker run -it -v $PWD:/code swift:5.3 swift test --package-path /code --enable-test-discovery

@elliottwilliams elliottwilliams force-pushed the linux-support-remove-cext branch from 7329195 to 5204ce4 Compare November 7, 2020 00:42
@elliottwilliams elliottwilliams force-pushed the linux-support-remove-cext branch from 62d6bec to a5c8cbe Compare November 9, 2020 18:34
@codecov
Copy link

codecov bot commented Nov 9, 2020

Codecov Report

Merging #585 (355812f) into main (b370051) will increase coverage by 0.00%.
The diff coverage is 83.00%.

Impacted file tree graph

@@           Coverage Diff            @@
##             main     #585    +/-   ##
========================================
  Coverage   84.24%   84.24%            
========================================
  Files         153      154     +1     
  Lines        8535     8663   +128     
========================================
+ Hits         7190     7298   +108     
- Misses       1345     1365    +20     
Impacted Files Coverage Δ
...s/XcodeProj/Objects/BuildPhase/PBXBuildPhase.swift 85.13% <0.00%> (-3.60%) ⬇️
...codeProj/Objects/BuildPhase/PBXRezBuildPhase.swift 22.22% <0.00%> (-11.12%) ⬇️
...ces/XcodeProj/Objects/Files/PBXContainerItem.swift 73.33% <0.00%> (-18.34%) ⬇️
...XcodeProj/Objects/Project/PBXObjectReference.swift 92.59% <ø> (ø)
...ces/XcodeProj/Objects/Project/PBXProjEncoder.swift 99.68% <ø> (ø)
.../XcodeProj/Objects/Targets/PBXReferenceProxy.swift 20.68% <0.00%> (-2.39%) ⬇️
Sources/XcodeProj/Objects/Targets/PBXTarget.swift 76.00% <0.00%> (-1.87%) ⬇️
Sources/XcodeProj/Extensions/String+md5.swift 5.91% <32.00%> (+1.89%) ⬆️
...codeProj/Objects/Sourcery/Equality.generated.swift 96.17% <95.45%> (+2.16%) ⬆️
Sources/XcodeProj/Utils/CommentedString.swift 93.15% <97.82%> (+26.48%) ⬆️
... and 28 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b370051...355812f. Read the comment docs.

Copy link
Contributor

@pepicrft pepicrft left a comment

Choose a reason for hiding this comment

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

First of all, thank you very much for taking your time for bringing support for Linux to the project @elliottwilliams 🙏 🚀. It's something that has been in our backlog for a long time and it finally happened.
I think the performance trade-offs that you are making make total sense for now. We can certainly go further with optimizations but we can do that in follow-up PRs if it turns out we need them.
One minor suggestion that I'd make before merging the PR is including a GitHub action that ensures changes compile in Linux. We can also update the README of the project to indicate that the library has support for both, Linux and macOS. Also, would you mind updating the CHANGELOG?
After that, we can merge and I'll release a new major version of the tool. I think this improvement really deserves a major bump :).
Again, thanks a lot for taking your time, I appreciate it a lot and I think the users of the library will do it too.

@pepicrft
Copy link
Contributor

@all-contributors add @elliottwilliams for code

@allcontributors
Copy link
Contributor

@pepibumur

I've put up a pull request to add @elliottwilliams! 🎉

@pepicrft pepicrft mentioned this pull request Nov 10, 2020
@elliottwilliams
Copy link
Contributor Author

@pepibumur thanks so much!! Yeah, totally agree with your suggestions.

Should I do anything about the swiftlint violations? I can try to fix any this PR adds, but it looks like there are a number of failures from existing code.

@elliottwilliams
Copy link
Contributor Author

@pepibumur

After that, we can merge and I'll release a new major version of the tool. I think this improvement really deserves a major bump :)

qq: Would you actually be open to making this a minor version? I don't think this introduces any API breaks, and I think it'd be easier to advocate for upgrading downstream projects if there isn't a major version bump :)

@elliottwilliams elliottwilliams force-pushed the linux-support-remove-cext branch from b871f5b to 66e446b Compare November 10, 2020 21:22
@elliottwilliams elliottwilliams force-pushed the linux-support-remove-cext branch from 66e446b to e56c0da Compare November 10, 2020 23:23
@elliottwilliams
Copy link
Contributor Author

Should I do anything about the swiftlint violations? I can try to fix any this PR adds, but it looks like there are a number of failures from existing code.

I take it back, they were mine! Fixed.

@elliottwilliams elliottwilliams force-pushed the linux-support-remove-cext branch from 2989ece to c05e0c1 Compare November 11, 2020 00:16
@pepicrft pepicrft merged commit ad2d6cb into tuist:main Nov 11, 2020
@pepicrft
Copy link
Contributor

elliottwilliams added a commit to elliottwilliams/XcodeProj that referenced this pull request May 18, 2021
Swift 5.4 changed something that caused the linux build to (correctly)
fail to compile an @objc declaration. We can do the same thing we did
to the PBXObject hierarchy in tuist#585, and reimplement the dynamic equality
checking using memberwise equality functions generated by sourcery, and
a dynamic method on each XCScheme object.

Tested the generated interface with these changes:

    swift build -Xswiftc -emit-module-interface -Xswiftc -swift-version -Xswiftc 5

The only change to the interface is that RemoteRunnable now exposes an
`==` method:

```diff
+    public static func == (lhs: XcodeProj.XCScheme.RemoteRunnable, rhs: XcodeProj.XCScheme.RemoteRunnable) -> Swift.Bool
```
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