Skip to content
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
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2024, Gluon
* Copyright (c) 2019, 2025, Gluon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -721,6 +721,7 @@ private void extractNativeLibs(String classPath) throws IOException {

List<String> jars = new ClassPath(classPath).filter(s -> s.endsWith(".jar") && !s.contains("javafx-"));
for (String jar : jars) {
Logger.logDebug("Extracting native libs from jar: " + jar);
FileOps.extractFilesFromJar("." + getStaticLibraryFileExtension(), Path.of(jar),
libPath, getTargetSpecificNativeLibsFilter());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2022, Gluon
* Copyright (c) 2020, 2025, Gluon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -29,10 +29,12 @@

import com.gluonhq.substrate.model.InternalProjectConfiguration;
import com.gluonhq.substrate.model.ProcessPaths;
import com.gluonhq.substrate.util.Logger;
import com.gluonhq.substrate.util.ProcessRunner;

import java.io.IOException;
import java.nio.file.Path;
import java.util.function.Predicate;

abstract class DarwinTargetConfiguration extends PosixTargetConfiguration {

Expand All @@ -50,4 +52,25 @@ public boolean createSharedLib() throws IOException, InterruptedException {
ProcessRunner process = new ProcessRunner("install_name_tool", "-id", "@rpath/" + libName, libName);
return process.runProcess("install name", lib.getParent().toFile()) == 0;
}

@Override
Predicate<Path> getTargetSpecificNativeLibsFilter() {
return this::checkFileArchitecture;
}

private boolean checkFileArchitecture(Path path) {
try {
ProcessRunner pr = new ProcessRunner("lipo", "-info", path.toFile().getAbsolutePath());
pr.showSevereMessage(false);
int op = pr.runProcess("lipo");
if (op == 0) {
return true;
}
} catch (IOException | InterruptedException e) {
Logger.logSevere("Unrecoverable error checking file " + path + ": " + e);
}
Logger.logDebug("Ignore file " + path + " since lipo failed on it");
return false;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2024, Gluon
* Copyright (c) 2019, 2025, Gluon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -152,11 +152,6 @@ List<String> getTargetSpecificAOTCompileFlags() throws IOException {
return flags;
}

@Override
Predicate<Path> getTargetSpecificNativeLibsFilter() {
return this::lipoMatch;
}

@Override
public String getAdditionalSourceFileLocation() {
return "/native/ios/";
Expand Down Expand Up @@ -375,21 +370,6 @@ private Path getAndValidateAppPath() throws IOException, InterruptedException {
return app;
}

private boolean lipoMatch(Path path) {
try {
String lp = lipoInfo(path);
if (lp == null) return false;
return lp.indexOf(getTargetArch()) > 0;
} catch (IOException | InterruptedException e) {
Logger.logSevere("Error processing lipo for " + path);
}
return false;
}

private String lipoInfo(Path path) throws IOException, InterruptedException {
return ProcessRunner.runProcessForSingleOutput("lipo", "lipo", "-info", path.toFile().getAbsolutePath());
}

/*
* Copies the .cap files from the jar resource and store them in
* a directory. Return that directory
Expand Down
49 changes: 31 additions & 18 deletions src/main/java/com/gluonhq/substrate/util/FileOps.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2024, Gluon
* Copyright (c) 2019, 2025, Gluon
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -535,29 +535,42 @@ public static void extractFilesFromJar(List<String> extensions, Path sourceJar,
if (!Files.exists(target)) {
Files.createDirectories(target);
}
ZipFile zf = new ZipFile(sourceJar.toFile());
List<? extends ZipEntry> entries = zf.stream()
.filter(ze -> extensions.stream().anyMatch(ext -> ze.getName().endsWith(ext)))
.collect(Collectors.toList());
if (entries.isEmpty()) {
return;

List<String> uniqueObjectFileNames = new ArrayList<>();
try (Stream<Path> list = Files.list(target)) {
uniqueObjectFileNames.addAll(list
.map(p -> p.getFileName().toString())
.collect(Collectors.toList()));
} catch (Exception ex) {
Logger.logSevere("Error listing files from " + target + ": " + ex.getMessage());
}

List<String> uniqueObjectFileNames = Files.list(target)
.map(p -> p.getFileName().toString())
.collect(Collectors.toList());
try (ZipFile zf = new ZipFile(sourceJar.toFile())) {
List<? extends ZipEntry> entries = zf.stream()
.filter(ze -> extensions.stream().anyMatch(ext -> ze.getName().endsWith(ext)))
.collect(Collectors.toList());
if (entries.isEmpty()) {
return;
}

for (ZipEntry ze : entries) {
String uniqueName = new File(ze.getName()).getName();
if (!uniqueObjectFileNames.contains(uniqueName)) {
Path filePath = FileOps.copyStream(zf.getInputStream(ze), target.resolve(uniqueName));
if (filter == null || filter.test(filePath)) {
uniqueObjectFileNames.add(uniqueName);
for (ZipEntry ze : entries) {
String uniqueName = new File(ze.getName()).getName();
if (!uniqueObjectFileNames.contains(uniqueName)) {
Logger.logDebug("Testing file " + ze.getName());
Path filePath = FileOps.copyStream(zf.getInputStream(ze), target.resolve(uniqueName));
if (filter == null || filter.test(filePath)) {
Logger.logDebug("File copied, it passes the filter: " + uniqueName);
uniqueObjectFileNames.add(uniqueName);
} else {
Logger.logDebug("File not copied, doesn't pass filter: " + uniqueName);
Files.delete(filePath);
}
} else {
Logger.logDebug("File not copied, doesn't pass filter: " + uniqueName);
Files.delete(filePath);
Logger.logDebug("File " + ze.getName() + " not tested, a file with the same name already exists");
}
}
} catch (Exception ex) {
Logger.logSevere("Error extracting files from zip: " + ex.getMessage());
}
}

Expand Down
Loading