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

* fixed: compilation failed due swift lib not found (libswiftXPC.dylib is not found in swift paths) #783

Merged
merged 1 commit into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ public void processFile(Resource resource, File file, File destDir)

protected void copyDynamicFrameworks(File destDir, File appExecutable) throws IOException {
final Set<String> swiftLibraries = new HashSet<>();
final Set<String> weakSwiftLibraries = new HashSet<>();
File frameworksDir = new File(destDir, "Frameworks");

for (String framework : config.getFrameworks()) {
Expand Down Expand Up @@ -380,7 +381,7 @@ public void processFile(Resource resource, File file, File destDir) throws IOExc
// check if this dylib depends on Swift
// and register those libraries to be copied
// to bundle.app/Frameworks
getSwiftDependencies(file, swiftLibraries);
getSwiftDependencies(file, swiftLibraries, weakSwiftLibraries);
}
}
}
Expand All @@ -392,7 +393,7 @@ public void processFile(Resource resource, File file, File destDir) throws IOExc

if (config.hasSwiftSupport() && config.getSwiftSupport().shouldCopySwiftLibs()) {
// find swift libraries that might be referenced in executable due static linking
getSwiftDependencies(appExecutable, swiftLibraries);
getSwiftDependencies(appExecutable, swiftLibraries, weakSwiftLibraries);

// workaround: check if libs contain reference to swift lib
// if project links against static swift library it requires
Expand All @@ -402,23 +403,30 @@ public void processFile(Resource resource, File file, File destDir) throws IOExc
String p = lib.getValue();
if (p.startsWith("libswift") && p.endsWith(".dylib") && !new File(p).exists()) {
swiftLibraries.add(p);
if (!lib.isForce()) weakSwiftLibraries.add(p);
}
}

// copy Swift libraries if required
if (!swiftLibraries.isEmpty()) {
copySwiftLibs(swiftLibraries, frameworksDir, true);
copySwiftLibs(swiftLibraries, weakSwiftLibraries, frameworksDir, true);
}
}
}

protected void getSwiftDependencies(File file, Collection<String> swiftLibraries) throws IOException {
protected void getSwiftDependencies(File file, Collection<String> swiftLibraries, Collection<String> weakSwiftLibraries) throws IOException {
String dependencies = ToolchainUtil.otool(file);
Pattern swiftLibraryPattern = Pattern.compile("@rpath/(libswift.+\\.dylib)");
// dependency string example
// @rpath/libswiftXPC.dylib (compatibility version 1.0.0, current version 36.100.7, weak)
Pattern swiftLibraryPattern = Pattern.compile("@rpath/(libswift.+\\.dylib)(?:.*(weak))?");
Matcher matcher = swiftLibraryPattern.matcher(dependencies);
while (matcher.find()) {
String library = matcher.group(1);
swiftLibraries.add(library);
if (matcher.groupCount() > 1) {
// `weak` was present, consider library for weak linking
weakSwiftLibraries.add(library);
}
}
}

Expand Down Expand Up @@ -562,13 +570,13 @@ protected void copyWatchApp(File installDir) throws IOException {
}
}

private File locateSwiftLib(File[] swiftDirs, String swiftLib) throws FileNotFoundException {
private File locateSwiftLib(File[] swiftDirs, String swiftLib) {
for (File swiftDir : swiftDirs) {
File f = new File(swiftDir, swiftLib);
if (f.exists())
return f;
}
throw new FileNotFoundException(swiftLib + " is not found in swift paths");
return null;
}

private File[] getSwiftDirs(Config config) throws IOException {
Expand Down Expand Up @@ -645,22 +653,29 @@ private File[] getDefaultSwiftDirs(String system) throws IOException {
return swiftDirs.toArray(new File[0]);
}

protected void copySwiftLibs(Collection<String> swiftLibraries, File targetDir, boolean strip) throws IOException {
protected void copySwiftLibs(Collection<String> swiftLibraries, Collection<String> weakSwiftLibraries,
File targetDir, boolean strip) throws IOException {
File[] swiftDirs = getSwiftDirs(config);

// dkimitsa: there is hidden dependencies possible between swift libraries.
// e.g. one swiftLib has dependency that is not listed in included framework
// solve this by moving through all swiftLibs and resolve their not listed dependencies
Set<String> libsToResolve = new HashSet<>(swiftLibraries);
Set<String> weakLibs = new HashSet<>(weakSwiftLibraries);
Map<String, File> resolvedLibs = new HashMap<>();
while (!libsToResolve.isEmpty()) {
for (String library : new HashSet<>(libsToResolve)) {
libsToResolve.remove(library);
if (!resolvedLibs.containsKey(library)) {
File swiftLibrary = locateSwiftLib(swiftDirs, library);
resolvedLibs.put(library, swiftLibrary);

getSwiftDependencies(swiftLibrary, libsToResolve);
if (swiftLibrary != null) {
resolvedLibs.put(library, swiftLibrary);
getSwiftDependencies(swiftLibrary, libsToResolve, weakLibs);
} else {
if (weakLibs.contains(library))
config.getLogger().warn("Weak " + library + " is not found in swift paths");
else throw new FileNotFoundException(library + " is not found in swift paths");
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -851,7 +851,7 @@ private void packageApplication(File appDir) throws IOException {
}

swiftSupportDir.mkdirs();
copySwiftLibs(Arrays.asList(swiftLibs), swiftSupportDir, false);
copySwiftLibs(Arrays.asList(swiftLibs), Collections.emptyList(), swiftSupportDir, false);
}
}

Expand Down
Loading