diff --git a/build.gradle b/build.gradle index 9ce544a2..3979a128 100644 --- a/build.gradle +++ b/build.gradle @@ -38,7 +38,6 @@ if (clang_versions.length == 0) { " Make sure a ${llvm_home}/lib/clang/ directory exists") } def clang_version = clang_versions[0] - def buildDir = layout.buildDirectory.get() def jextract_version = "23" def jmods_dir = "$buildDir/jmods" @@ -73,24 +72,32 @@ jar { task copyLibClang(type: Sync) { into("$buildDir/jmod_inputs") - // make sure we only pick up the "real" shared library file from LLVM installation - // (e.g. exclude symlinks on Linux) - def clang_path_include = (Os.isFamily(Os.FAMILY_UNIX) && !Os.isFamily(Os.FAMILY_MAC)) ? - "libclang.so.${clang_version}" : "*clang*" - - from("${libclang_dir}") { - include(clang_path_include) - include("libLLVM.*") - exclude("clang.exe") - into("libs") - // make sure we drop shared library version name (Linux only) - rename("libclang.so.${clang_version}", "libclang.so") - } - - from("$clang_include_dir") { + // make sure we only pick up the "real" shared library file from LLVM installation + // (e.g. exclude symlinks on Linux) + def isAix = Os.isName("AIX") || Os.isName("aix") + def isUnixNotMac = Os.isFamily(Os.FAMILY_UNIX) && !Os.isFamily(Os.FAMILY_MAC) + def clang_path_include = + isAix ? "libclang.a" : + isUnixNotMac ? "libclang.so.${clang_version}" : + "*clang*" + from("${libclang_dir}") { + include(clang_path_include) + include("libLLVM.*") + exclude("clang.exe") + into("libs") + // make sure we drop shared library version name (Linux only) + rename("libclang.so.*", "libclang.so") + + } + from("${libclang_dir}") { + include("libclang.a") + into("$buildDir/test-libs") + } + from("$clang_include_dir") { include("*.h") into("conf/jextract") - } + } + } task createJextractJmod(type: Exec) { @@ -203,6 +210,7 @@ task cmakeConfigure(type: Exec) { ] } + task cmakeBuild(type: Exec) { dependsOn cmakeConfigure @@ -238,7 +246,7 @@ void createJtregTask(String name, String jacocoAgent, String os_lib_dir) { "-javacoption:--add-exports=org.openjdk.jextract/org.openjdk.jextract.json.parser=ALL-UNNAMED", "-javaoption:--add-exports=org.openjdk.jextract/org.openjdk.jextract.json.parser=ALL-UNNAMED", "-avm", "-conc:auto", "-verbose:summary,fail,error", - "-retain:fail,error", + "-retain:fail,error" ] if (jacocoAgent != null) { @@ -258,6 +266,20 @@ if (jacocoAgent != null) { createJtregTask("jtregWithCoverage", jacocoAgent, os_lib_dir) } + +tasks.register("copyLibClangToTestLib", Copy) { + def srcFile = file("${project.buildDir}/jmod_inputs/libs/libclang.a") + def destDir = file("${project.buildDir}/test-lib/libs") + dependsOn(copyLibClang) + from(srcFile) + into(destDir) +} + +// Make jtreg depend on it +tasks.named("jtreg") { + dependsOn("copyLibClangToTestLib") +} + tasks.register("coverage", JavaExec) { dependsOn jtregWithCoverage diff --git a/make/Build.gmk b/make/Build.gmk index 1dafbec9..cc6baebc 100644 --- a/make/Build.gmk +++ b/make/Build.gmk @@ -14,6 +14,8 @@ endif ifeq ($(PLATFORM_OS), macosx) TAR_SUPPORTS_TRANSFORM := false +else ifeq ($(PLATFORM_OS), aix) + TAR_SUPPORTS_TRANSFORM := false else TAR_SUPPORTS_TRANSFORM := true endif @@ -29,6 +31,8 @@ JEXTRACT_JMOD_CONF_DIR := $(BUILD_DIR)/jextract_jmod_conf ifeq ($(PLATFORM_OS), macosx) BUNDLE_PLATFORM := macos-$(PLATFORM_CPU) +else ifeq ($(PLATFORM_OS), aix) + BUNDLE_PLATFORM := aix-$(PLATFORM_CPU) else BUNDLE_PLATFORM := $(PLATFORM) endif @@ -55,6 +59,8 @@ $(BUILD_CLASSES_DIR): ifeq ($(PLATFORM_OS), linux) LIBCLANG_COPY_PATH := "libclang.so.$(LIBCLANG_VERSION)" +else ifeq ($(PLATFORM_OS), aix) + LIBCLANG_COPY_PATH := "libclang.a" else LIBCLANG_COPY_PATH := "*clang.*" endif @@ -70,7 +76,6 @@ $(BUILD_MODULES_DIR): $(BUILD_CLASSES_DIR) $(CP) "$(LIBCLANG_INCLUDE_DIR)/"*.h "$(JEXTRACT_JMOD_CONF_DIR)/jextract/" [ ! -f $(JEXTRACT_JMOD_LIBS_DIR)/libclang.so.$(LIBCLANG_VERSION) ] || \ $(MV) "$(JEXTRACT_JMOD_LIBS_DIR)/libclang.so.$(LIBCLANG_VERSION)" "$(JEXTRACT_JMOD_LIBS_DIR)/libclang.so" - # create jextract jmod file $(FIXPATH) $(PANAMA_JAVA_HOME)/bin/jmod \ create \ diff --git a/make/Common.gmk b/make/Common.gmk index a87c9feb..08a8fae2 100644 --- a/make/Common.gmk +++ b/make/Common.gmk @@ -68,39 +68,53 @@ endef X := SPACE:=$(X) $(X) - +UNAME_P := $(shell uname -p) UNAME_M := $(shell uname -m) + +# CPU detection ifeq ($(UNAME_M),x86_64) - DEVKIT_VS_CPU_VAR_NAME := x86_64 - PLATFORM_CPU := x64 -else ifeq ($(UNAME_M),arm64) - DEVKIT_VS_CPU_VAR_NAME := aarch64 - PLATFORM_CPU := aarch64 -else ifeq ($(UNAME_M),aarch64) - DEVKIT_VS_CPU_VAR_NAME := aarch64 - PLATFORM_CPU := aarch64 + DEVKIT_VS_CPU_VAR_NAME := x86_64 + PLATFORM_CPU := x64 else - $(error "Unknown CPU: $(UNAME_M)") + ifeq ($(UNAME_M),arm64) + DEVKIT_VS_CPU_VAR_NAME := aarch64 + PLATFORM_CPU := aarch64 + else + ifeq ($(UNAME_M),aarch64) + DEVKIT_VS_CPU_VAR_NAME := aarch64 + PLATFORM_CPU := aarch64 + else + ifeq ($(UNAME_P),powerpc) + DEVKIT_VS_CPU_VAR_NAME := ppc64 + PLATFORM_CPU := ppc64 + else + $(error "Unknown CPU: $(UNAME_M)") + endif + endif + endif endif +# OS detection ifeq ($(OS),Windows_NT) - PLATFORM_OS := windows - FIXPATH := bash $(TOPDIR)/make/scripts/fixpath.sh exec + PLATFORM_OS := windows + FIXPATH := bash $(TOPDIR)/make/scripts/fixpath.sh exec else - FIXPATH := - - UNAME_S := $(shell uname -s) - ifeq ($(UNAME_S), Darwin) - PLATFORM_OS := macosx - else - ifeq ($(UNAME_S), Linux) - PLATFORM_OS := linux + FIXPATH := + UNAME_S := $(shell uname -s) + ifeq ($(UNAME_S),Darwin) + PLATFORM_OS := macosx else - $(error "Unknown OS: $(UNAME_S)") + ifeq ($(UNAME_S),Linux) + PLATFORM_OS := linux + else + ifeq ($(UNAME_S),AIX) + PLATFORM_OS := aix + else + $(error "Unknown OS: $(UNAME_S)") + endif + endif endif - endif endif - PLATFORM := $(PLATFORM_OS)-$(PLATFORM_CPU) ECHO := echo diff --git a/make/NativeCompilation.gmk b/make/NativeCompilation.gmk index daf9e9a5..38da31cc 100644 --- a/make/NativeCompilation.gmk +++ b/make/NativeCompilation.gmk @@ -86,6 +86,19 @@ else CFLAGS += --sysroot=$(SYSROOT) endif endif + ifeq ($(PLATFORM_OS), aix) + SHARED_LIB_SUFFIX := .a + CC_NAME := xlc + LINK_NAME := xlc + + # xlc typically requires -q64 for 64-bit builds + CFLAGS += -q64 -bexpall -qhalt=e -qalign=power -sysroot=$(SYSROOT) -m64 + LDFLAGS += -q64 -G -Wl,-bnoentry -Wl,-bexpall, -malign-power -m64 + CPPFLAGS += -D_AIX + + # AIX-specific export file handling can be added here if needed + endif + endif CC := $(call FindTool,$(CC_NAME),$(TOOL_SEARCH_PATH)) diff --git a/src/main/java/org/openjdk/jextract/clang/libclang/Index_h.java b/src/main/java/org/openjdk/jextract/clang/libclang/Index_h.java index 531b1b06..ea9d2d3f 100644 --- a/src/main/java/org/openjdk/jextract/clang/libclang/Index_h.java +++ b/src/main/java/org/openjdk/jextract/clang/libclang/Index_h.java @@ -33,9 +33,10 @@ import java.util.*; import java.util.function.*; import java.util.stream.*; - import static java.lang.foreign.ValueLayout.*; +import java.util.StringTokenizer; import static java.lang.foreign.MemoryLayout.PathElement.*; +import java.io.File; public class Index_h { @@ -80,15 +81,34 @@ static MemoryLayout align(MemoryLayout layout, long align) { }; } + static SymbolLookup SYMBOL_LOOKUP; static { - String libName = System.getProperty("os.name").startsWith("Windows") ? "libclang" : "clang"; - System.loadLibrary(libName); + String osName = System.getProperty("os.name"); + String libName = ""; + if (osName.startsWith("AIX")) { + List pathsToCheck = new ArrayList<>(Arrays.asList( + System.getProperty("java.library.path").split(File.pathSeparator) + )); + // 2. Add alternate calculated paths + String currentDir = System.getProperty("user.dir"); // wherever JVM was launched + pathsToCheck.add(currentDir + "/build/jextract-jdk-test-image/lib"); + pathsToCheck.add(currentDir + "/../../../jextract-jdk-test-image/lib"); // in case running from subdir + // 3. Try to find the library + for (String path : pathsToCheck) { + File f = new File(path, "libclang.a"); // AIX uses .a, Linux .so + if (f.exists() && !f.isDirectory()) { + libName = f.getAbsolutePath(); + break; + } + } + SYMBOL_LOOKUP = SymbolLookup.libraryLookup(libName + "(libclang.so.14)", Arena.global()); + } else { + libName = osName.startsWith("Windows") ? "libclang" : "clang"; + System.loadLibrary(libName); + SYMBOL_LOOKUP = SymbolLookup.loaderLookup().or(Linker.nativeLinker().defaultLookup()); + } } - - static final SymbolLookup SYMBOL_LOOKUP = SymbolLookup.loaderLookup() - .or(Linker.nativeLinker().defaultLookup()); - public static final ValueLayout.OfBoolean C_BOOL = ValueLayout.JAVA_BOOLEAN; public static final ValueLayout.OfByte C_CHAR = ValueLayout.JAVA_BYTE; public static final ValueLayout.OfShort C_SHORT = ValueLayout.JAVA_SHORT; diff --git a/test/test-support/CMakeLists.txt b/test/test-support/CMakeLists.txt index e823d6d6..f534eb1c 100644 --- a/test/test-support/CMakeLists.txt +++ b/test/test-support/CMakeLists.txt @@ -2,7 +2,6 @@ cmake_minimum_required(VERSION 3.14) project(TestSupportLibs) option(TEST_SOURCE_ROOT "src directory with test files") - file(GLOB_RECURSE TEST_LIBS ${TEST_SOURCE_ROOT}/*lib*.c) foreach(TEST_LIB ${TEST_LIBS}) @@ -11,13 +10,26 @@ foreach(TEST_LIB ${TEST_LIBS}) string(REGEX REPLACE ".*lib([A-Za-z0-9_]+)\.c(pp)?" "\\1" LIB_NAME ${TEST_LIB}) string(REGEX REPLACE "(.*)/lib[A-Za-z0-9_]+\.c(pp)?" "\\1" PARENT_DIR ${TEST_LIB}) message(STATUS "Lib name: ${LIB_NAME}") + if(${CMAKE_SYSTEM_NAME} MATCHES "AIX") + add_library(${LIB_NAME} SHARED ${TEST_LIB}) + set_target_properties(${LIB_NAME} PROPERTIES + PREFIX "lib" + SUFFIX ".a" + COMPILE_FLAGS "-q64 -qhalt=e" + LINK_FLAGS "-q64 -G -Wl,-bnoentry,-bexpall" + ) + else() + add_library(${LIB_NAME} SHARED ${TEST_LIB}) + endif() - add_library(${LIB_NAME} SHARED ${TEST_LIB}) target_include_directories(${LIB_NAME} PRIVATE ${PARENT_DIR} ) + # Link against libm to resolve sqrt() and other math symbols + target_link_libraries(${LIB_NAME} m) + install( TARGETS ${LIB_NAME}