Skip to content

Remove Foundation dependency #39216

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 11 commits into from
Nov 6, 2021
Merged

Remove Foundation dependency #39216

merged 11 commits into from
Nov 6, 2021

Conversation

salinas-miguel
Copy link
Contributor

This removes the Swift project's dependency on Foundation on macOS.

resolves rdar://82458394

SWIFT_COMPONENT compiler)

find_library(FOUNDATION NAMES Foundation)
target_link_libraries(swift-stdlib-tool PRIVATE ${FOUNDATION})
set(CMAKE_CXX_STANDARD 17)
Copy link
Contributor

@CodaFi CodaFi Sep 9, 2021

Choose a reason for hiding this comment

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

This means the entire project now requires a C++17-enabled compiler. Please mention this change on the Swift forums.

Copy link
Contributor

Choose a reason for hiding this comment

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

To be clear, I'm not opposed to such a change, but we have a wide variety of adopters with a wide variety of toolchains and we must be careful to make sure we're advertising the correct minimum requirements.

Copy link
Contributor

Choose a reason for hiding this comment

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

Do all of those toolchains need this tool, or is it limited to certain platforms like Darwin?

Copy link
Contributor

Choose a reason for hiding this comment

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

Right now, this tool is built to ship specifically for macOS hosts in Darwin toolchains.

Copy link
Contributor

Choose a reason for hiding this comment

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

That should dramatically reduce impact, because there is only one variety of toolchain we need to worry about compatibility with, then, right?

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 can mention this in the forums. Xcode 13 beta 4 is currently required on macOS and includes a C++17 enabled version of Clang so I thought it would be ok to use C++17 here.

Copy link
Contributor

Choose a reason for hiding this comment

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

That should dramatically reduce impact, because there is only one variety of toolchain we need to worry about compatibility with, then, right?

Yes.

so I thought it would be ok to use C++17 here.

It is okay to use. I just want our adopters to be aware of this change, that's all.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason to use CMAKE_CXX_STANDARD rather than setting CXX_STANDARD on just this target? I know you don't want to diverge too much across the project, but it seems like if you don't have a C++17-capable stdlib, you could just skip building this one target.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah, I'm not very familiar with CMake and didn't know this was possible. I'll use CXX_STANDARD on just this target instead. Thank you.

NSUUID *uuid = (NSUUID *)
CFUUIDCreateFromUUIDBytes(nil, uuid_bytes);
uuid_t uuid;
memcpy(uuid, uuid_cmd->uuid(), 16);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please replace this magic number with a sizeof.

uint32_t len = 0;
_NSGetExecutablePath(nil, &len);
_NSGetExecutablePath(NULL, &len);
std::vector<char> buffer;
buffer.reserve(len);
_NSGetExecutablePath(buffer.data(), &len);
Copy link
Contributor

Choose a reason for hiding this comment

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

Will _NSGetExecutablePath fill in the nul byte at the end? Even if so, I would feel more comfortable if we constructed a std::span with the len here and converted that to a std::filesystem::path.

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 seems like std::span was introduced in C++20. _NSGetExecutablePath returns a string with a size of MAXPATHLEN at most so I was able to remove the first call. It does fill the nul byte at the end but I'm zeroing anyways.


auto const stdOutData = readToEOF(outPipe[0]);

dispatch_semaphore_wait(gotStdErr, DISPATCH_TIME_FOREVER);
Copy link
Contributor

Choose a reason for hiding this comment

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

Waiting forever doesn't seem like the right default. But it's also not your bug so we can deal with this later.

for (NSString *lib in libs) @autoreleasepool {
NSString *src = [src_dir stringByAppendingPathComponent:lib];
NSString *dst = [dst_dir stringByAppendingPathComponent:lib];
for (auto const &pair : libs) {
Copy link
Contributor

Choose a reason for hiding this comment

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

As long as we're using C++17:

Suggested change
for (auto const &pair : libs) {
for (auto const &[lib, srcUUIDs] : libs) {

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, I didn't know this was possible in C++

fail_usage("At least one of --source-libraries and --platform "
"must be set.");
}
else if (src_dir.empty()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: else if consistent with the others please.

const char *launchPath = "/usr/bin/xcrun";

// Tell xcrun to search our toolchain first.
const char *arguments[commandAndArguments.size() + 5];
Copy link
Contributor

Choose a reason for hiding this comment

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

Using std::vector here would avoid a lot of the magic math.

}();

std::vector<uint8_t> readToEOF(int fd) {
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 this function with dispatch_read in a loop.

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 also using this function to read synchronously on line 741 so I think this is probably still needed.

NSMutableDictionary *libs, bool stripBitcode)
void copyLibraries(std::filesystem::path src_dir, std::filesystem::path dst_dir,
std::unordered_map<std::string,
std::unordered_set<std::string>> libs,
Copy link
Contributor

Choose a reason for hiding this comment

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

This is equivalent to std::unordered_multimap

Copy link
Contributor

Choose a reason for hiding this comment

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

Does this routine mutate the map? It doesn't look like it, so take it by const ref please.

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 tried using a std::unordered_multimap but iterating through it in the same way and comparing to dstUUIDs below was a little messier.

@salinas-miguel
Copy link
Contributor Author

@CodaFi I addressed your feedback and also made the C++17 requirement specific to this target as @belkadan suggested. Let me know what you think.

Copy link
Contributor

@CodaFi CodaFi left a comment

Choose a reason for hiding this comment

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

LGTM

Thank you for your patience here.

@swift-ci test

CXX_STANDARD 17
CXX_STANDARD_REQUIRED ON)

target_link_libraries(swift-stdlib-tool PRIVATE)
Copy link
Contributor

Choose a reason for hiding this comment

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

This line doesn't seem to do anything anymore. If there's no need for linking libraries, let's remove it completely.

@@ -418,8 +424,8 @@ ssize_t pread_all(int fd, void *buf, size_t count, off_t offset)

template <typename T>
int parse_macho(int fd, uint32_t offset, uint32_t size,
void (^dylibVisitor)(NSString *path),
void (^uuidVisitor)(NSUUID *uuid))
void (^dylibVisitor)(std::filesystem::path const &path),
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: seems that this line is not correctly indented with the surroundings.

std::back_inserter(retData));
}
return retData;
}

// Runs a tool with `xcrun`.
// Returns NSTask.terminationStatus.
Copy link
Contributor

Choose a reason for hiding this comment

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

Outdated comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

src.fileSystemRepresentation,
dst.fileSystemRepresentation,
nserr.localizedFailureReason.UTF8String);
if (rename(src.c_str(), dst.c_str()) != 0) {
Copy link
Contributor

Choose a reason for hiding this comment

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

rename is different than a copy. Is this an intentional change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for finding this mistake

Comment on lines 1022 to 1023
auto const &lib = worklist.back();
worklist.pop_back();
Copy link
Contributor

Choose a reason for hiding this comment

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

You cannot grab a reference to the back() and immediately pop_back(). It will invalidate the reference. It probably works today because of luck, but it is not guaranteed to work. It is probably safer to remove the reference and pay the price of the copy.

Comment on lines 1153 to 1154
std::move(otherCodesignFlags.begin(), otherCodesignFlags.end(),
std::back_inserter(commandAndArguments));
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not sure that moving in every loop from otherCodesignFlags is the correct thing. Why not std::copy which should be clearly safe?

@drodriguez
Copy link
Contributor

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - de73874

@salinas-miguel
Copy link
Contributor Author

It looks like std::filesystem is only available on macOS 10.15 and later. Apologies for not realizing this sooner. I'll remove its usage so that we can keep the current deployment target (macOS 10.9).

@drodriguez
Copy link
Contributor

@swift-ci please test

(I haven't looked at the code yet. Thanks for your patience)

@salinas-miguel
Copy link
Contributor Author

@drodriguez it looks like the CI was not triggered for some reason

@drodriguez
Copy link
Contributor

@swift-ci please test

@salinas-miguel
Copy link
Contributor Author

I think the Windows failure may be unrelated since this target is not built for Windows.

@salinas-miguel
Copy link
Contributor Author

@CodaFi does this look good to merge? I removed the C++17 requirement since I was only using it for the std::filesystem API which is not available before macOS 10.15.

close(outPipe[0]);
close(errPipe[0]);

execv(launchPath, (char *const *)arguments.data());
Copy link
Contributor

Choose a reason for hiding this comment

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

const_cast<char **> here please.

@@ -418,8 +426,8 @@ ssize_t pread_all(int fd, void *buf, size_t count, off_t offset)

template <typename T>
int parse_macho(int fd, uint32_t offset, uint32_t size,
void (^dylibVisitor)(NSString *path),
void (^uuidVisitor)(NSUUID *uuid))
void (^dylibVisitor)(std::string const &path),
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: LLVM style is west-const.

@@ -487,8 +487,8 @@ int parse_macho(int fd, uint32_t offset, uint32_t size,


int parse_macho(int fd, uint32_t offset, uint32_t size,
void (^dylibVisitor)(NSString *path),
void (^uuidVisitor)(NSUUID *uuid))
void (^dylibVisitor)(std::string const &path),
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here

@@ -515,8 +515,8 @@ int parse_macho(int fd, uint32_t offset, uint32_t size,


int parse_fat(int fd, off_t fsize, char *buffer, size_t size,
void (^dylibVisitor)(NSString *path),
void (^uuidVisitor)(NSUUID *uuid))
void (^dylibVisitor)(std::string const &path),
Copy link
Contributor

Choose a reason for hiding this comment

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

And here

Copy link
Contributor

@CodaFi CodaFi left a comment

Choose a reason for hiding this comment

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

In general, the spacing and brace style in this file do not match the conventions used in this codebase. Please run clang-format against this file.

@salinas-miguel
Copy link
Contributor Author

Pushed a change to reflect the changes in #39996. @CodaFi

@CodaFi
Copy link
Contributor

CodaFi commented Nov 4, 2021

Looks pretty faithful to #39996 to me.

@swift-ci test

@CodaFi
Copy link
Contributor

CodaFi commented Nov 4, 2021

I'm going to squash-merge this when it finally goes in because the history is a bit messy here and I don't want you to have to rebase which will kill the test run.

@swift-ci
Copy link
Contributor

swift-ci commented Nov 5, 2021

Build failed
Swift Test Linux Platform
Git Sha - 1e94613

@salinas-miguel
Copy link
Contributor Author

The linux failure seems unrelated:
/home/buildnode/jenkins/workspace/swift-PR-Linux/branch-main/swift-docc/Tests/SwiftDocCUtilitiesTests/PreviewServer/PreviewServerTests.swift:43: error: PreviewServerTests.testPreviewServerBeforeStarted : failed - The operation could not be completed. (NIO.SocketAddressError error 3.)

@CodaFi
Copy link
Contributor

CodaFi commented Nov 5, 2021

@swift-ci test Linux platform

@CodaFi CodaFi merged commit eab562f into swiftlang:main Nov 6, 2021
CodaFi pushed a commit that referenced this pull request Feb 9, 2022
When used without passing `--source-libraries`, this tool fetches its
current path and uses that to find the directories of the swift
libraries near it.

Since #39216 it was searching the
nearby directories recursively, and only for files, instead of just
looking at 1 level, only for directories. Because of this it would never
discover `path/to/lib/swift-5.0/...` because it was only looking for
files.

This fixes this issue with a new function, and renames the previous
function to be more explicit for the other use case that does want that
behavior.

(cherry picked from commit d1eabf1)
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.

6 participants