package org.graalvm.polyglot.nativeapi;
import static com.oracle.svm.hosted.NativeImageOptions.CStandards.C11;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.hosted.Feature;
import com.oracle.svm.core.util.InterruptImageBuilding;
import com.oracle.svm.core.util.UserError;
import com.oracle.svm.hosted.NativeImageOptions;
import com.oracle.svm.hosted.c.util.FileUtils;
public class PolyglotNativeAPIFeature implements Feature {
@Override
public void afterRegistration(AfterRegistrationAccess access) {
if (!NativeImageOptions.getCStandard().compatibleWith(C11)) {
throw UserError.abort("Polyglot native API supports only the C11 standard. Pass -H:CStandard=C11 on the command line to make the build work.");
}
}
@Override
public void afterImageWrite(AfterImageWriteAccess access) {
List<String> headerFiles = Collections.singletonList("polyglot_types.h");
Path imagePath = access.getImagePath();
headerFiles.forEach(headerFile -> {
Path source = Paths.get(System.getProperty("org.graalvm.polyglot.nativeapi.libraryPath"), headerFile);
Path destination = imagePath.getParent().resolve(headerFile);
try {
Files.copy(source, destination, REPLACE_EXISTING);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
if (Platform.includedIn(Platform.DARWIN.class)) {
String id = System.getProperty("org.graalvm.polyglot.install_name_id");
if (id == null) {
String msg = String.format("Warning: no id passed through `org.graalvm.polyglot.install_name_id`:" +
"\n%s might include its absolute path as id (see man install_name_tool)", imagePath);
System.err.println(msg);
} else {
List<String> command = Arrays.asList("install_name_tool", "-id", id, imagePath.toString());
Process installToolProcess = null;
try {
installToolProcess = FileUtils.executeCommand(command);
int exitCode = installToolProcess.exitValue();
if (exitCode != 0) {
System.err.println(String.format("Failed to set `id` install name. install_name_tool exited with code %d", exitCode));
}
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new InterruptImageBuilding("Interrupted in call to: " + String.join(" ", command));
} finally {
if (installToolProcess != null) {
installToolProcess.destroy();
}
}
}
}
}
}