RFR: 8352064: AIX: now also able to build static-jdk image with a statically linked launcher

Magnus Ihse Bursie ihse at openjdk.org
Tue Mar 18 12:12:13 UTC 2025


On Fri, 14 Mar 2025 15:41:56 GMT, Joachim Kern <jkern at openjdk.org> wrote:

> After "JDK-8339480: Build static-jdk image with a statically linked launcher" AIX was not able to build the new target. Therefore with "JDK-8345590 AIX 'make all' fails after JDK-8339480" the new target was disabled again.
> 
> Now with this change we can enable the statically linked launcher target again.
> There are 3 things to do.
> 1.	Modify `dladdr()`. Because this API does not exist on AIX it is implemented based on the `loadquery()` API. Unfortunately, this API does only return the name of the executable, but not its path. Beforehand this was no problem, because we asked for a loaded library, for which the API provides the path. But now we are asking for the executable itself.
> 2.	`dladdr()` is differently implemented three times in the openjdk code. In the static case I supressed now the usage of the additional modules containing version two and three. I know this shouldn't be the final version. Magnus mentioned that they have discussed from time to time to have a "basic JDK utility lib" that can be shared between hotspot and the JDK libraries. I think this is a good idea for the future, but far beyond the scope of this PR. The second best thing Magnus proposed is to only have the `dladdr()` functionality in Hotspot and then export it. Let's see how the community decides.
> 3.	Because we lack a linker flag like `whole-archive`, I had to force the export of all symbols by creating export files containing all symbols of the static libs. I introduced the new rule for the export file generation as "raw" make recipes. Magnus claimed to use the `SetupExecute`. Unfortunately I was not able to make it function. So I still have my "raw" solution in place, but my last try with `SetupExecute` as comment beneath. Help is welcome.

make/StaticLibs.gmk line 112:

> 110: $(STATIC_LIB_EXPORT_FILES): $(STATIC_LIB_FILES)
> 111: 	$(AR) $(ARFLAGS) -w $(patsubst %.exp, %, $@) | $(GREP) -v '^\.' | $(AWK) '{print $$1}' | sort -u >$@
> 112: #$(eval $(call SetupExecute, generate_export_list, \

I think there are multiple issues at hand here.

1) There is a current bug in SetupExecute that requires you to execute any command with redirection in a subshell, that is, you need to wrap the COMMAND in `(` ... `)`.

2) STATIC_LIB_EXPORT_FILES is not a single file, it is a list of file. So what you have written above is not a single recipe, it is a multi-file recipe template. But it's weird, it will evaluate to like:
libjvm.so.exp libjava.so.exp libjli.so.exp: libjvm.so libjava.so libjli.so
which makes no sense, since you do not need to have a dependency to  libjava.so libjli.so for libjvm.so.exp.

What you really want is to have a single rule per library that creates the corresponding exp file for that library, and which is dependent only on that library.

Or, possibly, you can just concatenate the export of all libraries into a single file. It will make the final linker command line simpler, since you would only need a single `-Wl,-bE:<the export file>`, but it is potentially worse for an incremental rebuild, since all native libraries need to be re-scanned for exported functions.

My preferred solution would to make this explicit by creating a loop over STATIC_LIB_FILES, and doing a SetupExecute for each such lib. Then you can get it down to something like:

$(foreach lib, $(STATIC_LIB_FILES), \
  $(eval $(call SetupExecute, generate_export_list_$(lib),
      INFO := Generating export list for $(lib), \
      DEPS :=  $(lib), \
      OUTPUT_FILE := $(lib).exp, \
      COMMAND := ( $(AR) $(ARFLAGS) -w $(lib) | $(GREP) -v '^.' | $(AWK) '{print $$1}' | sort -u > $(lib).exp ), \
  ) \
  $(eval STATIC_LIB_EXPORT_FILES += $(lib).exp) \
)

make/StaticLibs.gmk line 136:

> 134: ))
> 135: 
> 136: $(java): $(STATIC_LIB_FILES) $(if $(call isTargetOs, aix), $(STATIC_LIB_EXPORT_FILES))

This is just clunky. Leave the original line, and add:

ifeq ($(call isTargetOs, aix), true)
  $(java): $(STATIC_LIB_EXPORT_FILES)
endif

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/24062#discussion_r2000901430
PR Review Comment: https://git.openjdk.org/jdk/pull/24062#discussion_r2000904229


More information about the core-libs-dev mailing list