Skip to content

[Sema] Define library levels to detect public import of private modules and more #36608

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 3 commits into from
Mar 29, 2021

Conversation

xymus
Copy link
Contributor

@xymus xymus commented Mar 26, 2021

Intro the concept of library access/distribution level that indicates if it will be distributed widely (api) or reserved for use inside the organization (spi).

In practice, setting the flag -library-level api will warn on public imports of SPI modules and suggests using @_implementationOnly. The imported module SPI-ness is determined from the location it was loaded from and from whether it belongs to a private clang modulemap.( rdar://62934005)

Future work:

  • The flag -library-level spi should affect type-checking, it allows the use of SPI decls in API as the whole module is considered SPI. (rdar://75335462)
  • Infer the library level in the build system from the installation path.
  • Preserve the library level value in the serialized swiftmodule and use it to determine the SPI-ness of imported Swift modules. Let's wait for more compilers to understand this flag in order to avoid a condfail.
  • Support the ipi level for project-internal modules?

@xymus xymus requested review from beccadax and nkcsgexi March 26, 2021 17:36
@xymus
Copy link
Contributor Author

xymus commented Mar 26, 2021

@swift-ci Please smoke test

@xymus xymus force-pushed the lib-access-level branch from 39364cf to 8c3db43 Compare March 26, 2021 17:57
@xymus
Copy link
Contributor Author

xymus commented Mar 26, 2021

I forgot to commit a test.

@swift-ci Please smoke test

@xymus
Copy link
Contributor Author

xymus commented Mar 26, 2021

I may have to wait before I can land the last commit for The flag -library-level spi should affect type-checking, it allows the use of SPI decls in API as the whole module is considered SPI. (rdar://75335462) as this one requires to print the flag in the swift interface which will may lead to condfails.

@xymus xymus force-pushed the lib-access-level branch from 8c3db43 to a7b4597 Compare March 26, 2021 18:38
@xymus
Copy link
Contributor Author

xymus commented Mar 26, 2021

@swift-ci Please smoke test

Copy link
Contributor

@nkcsgexi nkcsgexi left a comment

Choose a reason for hiding this comment

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

This is a really nice approach! Any reason we don't emit -library-level into the interface so we don't need to infer the level from search paths?

SPI,

/// The library has some other undefined distribution.
Other
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need Other here? can we use API for default to simplify the logic?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using API as the default would mean that all projects get warnings on imports of private modules until they manually set the flag -library-level spi or we get a build system to set it automatically. I'm really tempted by that to get results faster but the rollout will be smoother if we wait for the build system to infer the library level.

Also, Other is now relevant to IPI/build time modules. We don't see much of those in Swift but we do import IPI clangmodules.

auto fromPrivateFrameworks = [&](StringRef path) -> bool {
auto sep = llvm::sys::path::get_separator();
auto privateFrameworksPath = ctx.SearchPathOpts.SDKPath +
sep + "System" + sep + "Library" + sep + "PrivateFrameworks" + sep;
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: start with llvm::Twine(ctx.SearchPathOpts.SDKPath) here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

While applying this I came across llvm::sys::path::append which simplifies greatly this piece of code.

@xymus
Copy link
Contributor Author

xymus commented Mar 26, 2021

@nkcsgexi It's on my todo list but we should wait a bit to print -library-level to the interfaces to avoid a condfail. It's not automatic so it wouldn't be an instant condfail but I'm worried project owners would have to hold off using this feature because of it.

Copy link
Contributor

@nkcsgexi nkcsgexi left a comment

Choose a reason for hiding this comment

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

It makes sense. Thank you for the explanation!

xymus added 3 commits March 26, 2021 16:30
Intro the concept of library access or distribution level to identify
layers of libraries and report public imports of private libraries from
public ones.

rdar://62934005
@xymus xymus force-pushed the lib-access-level branch from a7b4597 to 6bbb9f0 Compare March 26, 2021 23:34
@xymus
Copy link
Contributor Author

xymus commented Mar 26, 2021

@swift-ci Please smoke test

@xymus
Copy link
Contributor Author

xymus commented Mar 28, 2021

@swift-ci Please smoke test macOS

1 similar comment
@xymus
Copy link
Contributor Author

xymus commented Mar 29, 2021

@swift-ci Please smoke test macOS

@xymus xymus merged commit 04709c1 into swiftlang:main Mar 29, 2021
@xymus xymus deleted the lib-access-level branch March 29, 2021 19:30
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