-
Notifications
You must be signed in to change notification settings - Fork 1.4k
[docs] Requiring System Libraries with .systemLibrary targets #6634
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
Conversation
Documentation/Usage.md
Outdated
targets: [ | ||
// Targets are the basic building blocks of a package, defining a module or a test suite. | ||
// Targets can depend on other targets in this package and products from dependencies. | ||
.executableTarget( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it may be easier to understand if we do this in two steps, first introduce the "Clibgit" target, then show how to use it in the executable target. in other words, I suggest we split this example into two snippets, and build the knowledge in layers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It did feel a little bit overwhelming when I tried to reproduce the steps, so I agree. Rewritten that in two steps, and cleaned up the pkg-config
mention as well.
Documentation/Usage.md
Outdated
by running the following: | ||
|
||
example$ pkg-config --cflags libgit2 | ||
-I/opt/homebrew/Cellar/libgit2/1.6.4/include |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure what this means. can you elaborate what this is about?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving this into the note about system paths, where it makes more sense. My point was that on most systems, for most libraries, running pkg-config --cflags {library-name}
will get you the inclide
and lib
paths.
dependencies: ["CJPEG"], | ||
path: "Sources" | ||
), | ||
.systemLibrary( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto re. splitting the example into two steps
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After splitting the first one, I'm not so sure if we should split this one as well. It would add another blob of code, but since the second example builds up on the first one, I think the concept should be clear even without splitting.
But, happy to split if you'd prefer it in two steps here as well!
thanks so much for helping improve this under-documented area @natikgadzhi, left some comments. |
Hey @tomerd, thank you for the review! I'll clean these up later tonight. As the particular examples get lengthy and contain snippets of code and example commands, I wonder if after this PR, it would make sense to repackage common usage scenarios as docc tutorials? There's some documentation in docc format here, it seems. If there's interest, I would take on that work, and learn a bit more about SwiftPM in the process. |
hi @natikgadzhi I think that is indeed worth considering, but we currently do not have the automation in place to publish such. we are definitely planning to address this at some point in the future tho. |
@tomerd, took another pass on the feedback, and addressed most of it, commented on the rest. Thank you for a thorough read-through and review! How does it look to you now? I'll play around with the idea of tutorials and see how far I can get. If anything, that should help me understand SwiftPM and docc better. If that ends up being useful to someone else — great, if not — no worries, I'm doing that to learn. |
@swift-ci smoke test |
Co-authored-by: Max Desiatov <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall LGTM, just a couple more nits
Co-authored-by: Max Desiatov <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
@swift-ci smoke test |
@swift-ci test windows |
@swift-ci smoke test windows |
@MaxDesiatov, thank you for spending your time on the PR! I know it's a small contribution, and I hope that as I learn the ropes, it'll be worth your time. |
Documentation/Usage.md
Outdated
|
||
example$ swift build -Xlinker -L/usr/local/lib/ | ||
|
||
Create a `module.modulemap` file so it consists of the following: | ||
Next, create a directory `Sources/Clibgit` in your `example` project, and | ||
add a `module.modulemap` to it: | ||
|
||
module Clibgit [system] { | ||
header "/usr/local/include/git2.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is a somewhat better way to do this, namely to create you own header file, which then include the required one with <header>
so that no path hardcoding is required. eg: https://github.com/apple/swift-package-manager/tree/main/Sources/SPMSQLite3
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, long flight — back in PST now.
Ah, that's a TIL for me. So it looks like:
- You can, and probably should, add a header file in Sources/{LibName}/{LibName.h} that just includes {LibName.h} and/or other required headers.
- The
#include
will resolve with the compiler environment, so it should pick up the headers correctly, and thus you don't have to write the absolute header path in themodule.modulemap
.
Right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yup afaik. @neonichu to keep me honest here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yah I believe that is correct
Co-authored-by: Max Desiatov <[email protected]>
@neonichu @tomerd alright, done: f71f92e I've double-checked that the example project builds this way in SwiftPM 5.8. Haven't extensively tested other platforms, though. Considered adjusting the Mergeable? |
@swift-ci please smoke test |
@swift-ci test windows |
@swift-ci smoke test |
Documentation/Usage.md
Outdated
@@ -146,81 +146,116 @@ following files from the libgit2 system-package are of interest: | |||
/usr/local/lib/libgit2.dylib # .so on Linux | |||
/usr/local/include/git2.h | |||
|
|||
Swift packages that provide module maps for system libraries are handled | |||
differently from regular Swift packages. | |||
**Note:** the system library may be located elsewhere on your system, such as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that we should clear up some of the text here. Windows is a support platform, and these paths are not relevant there. Additionally, pkg-config
is not a commonly available utility on Windows.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added an entry on Windows paths.
pkgConfig: "libgit2", | ||
providers: [ | ||
.brew(["libgit2"]), | ||
.apt(["libgit2-dev"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add a .nuget
entry as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm. Should we suggest LibGit2Sharp
? Swift doesn't need the .Net wrapper to build it's package, but there doesn't seem to be another minimal nuget package for it.
Documentation/Usage.md
Outdated
search paths for the system library. Note: If you don't want to use the `pkgConfig` | ||
parameter you can pass the path of a directory containing the library using the | ||
`-L` flag in commandline when building your app: | ||
**Note:** If you don't want to use the `pkgConfig` parameter you can pass the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pkgConfig
should be elided for Windows only packages as pkg-config
is not expected to be available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added that to the note.
|
||
```c | ||
# git2.h | ||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we recommend include guards instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly don't have enough experience with C, so I don't know if using #pragma once
is perfectly fine, or a bad taste. My understanding is that using guards is guaranteed to work anywhere, and using #pragma once
is shorter, but might not work in certain environments?
|
||
module CJPEG [system] { | ||
header "shim.h" | ||
header "/usr/local/include/jpeglib.h" | ||
header "/usr/local/opt/jpeg/include/jpeglib.h" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we recommend something with a VFS example? That would make the majority of the code more cross-platform friendly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this and all your other comments, thank you! I'll catch up and clean things up a bit later today (PST) and ping you when it's all updated.
@compnerd, I cleaned up some text and recommendations around Windows builds. But I don't feel confident re: VFS paths example and guards vs pragma once. I don't have a strong opinion that we should not recommend guards — I just don't have enough experience to have an opinion yet. Same with VFS — I don't have enough experience to suggest where / when to use them, and what a good example might look like. I want to see this little piece of work through. Can you please help me polish those areas? I'm open to suggestions, or perhaps we should merge this pull request, and I should get myself a Windows VM, and try and work through all the documentation on Windows, see what works, what does not, and make another pull request with any cleanup necessary? |
I think this is a big improvement the previous version and we should merge it. @compnerd the previous version did not address windows at all, so I think we can tackle that a separate PR |
@swift-ci smoke test |
@swift-ci smoke test windows |
Updates the usage documentation around requiring system libraries.
Motivation:
I was getting started with Swift package manager, and looking to get a bit more experience using it — and stumbled on #6121, thought I'd play around and try to clean it up. Fixes #6121.
The existing documentation on
main
worked, but following it emitted a build-time warning about wrapping system libraries in a target, instead of it's own package.Modifications
I've tried to make things work without warnings, tested the
.systemLibrary
approach, and documented my steps.clibgit
examplecjpeg
exampleResult:
No functional changes to the package manager behavior — just the documentation change. After the change, one should be able to follow the docs step by step, and it should work without any build warnings.