# Basic definitions for building Genode apps with Jam/MR.
# This gets loaded before any Jamfile gets executed.

# == Directions ==
# After building Genode, but before building h-o-g, edit the $GenodeRepos
# variable definition below. You probably won't need to edit $GenodeBuild or $GccToolChain,
# unless your build dir or toolchain live in a non-standard location.

# == Known Bugs ==
# the "build/x86_64/var/run/hog-test/boot" symlink
#		might not get built correctly on first run of e.g. "jam t6", making the build fail -- need to invoke "jam -j3 t6" a second time, and on that second launch the build will complete; must be missing a "Depends" somewhere
# The linking stage produces this warning; seems of no consequence though:
#		ld: warning: ld.lib.so, needed by ..../libcache/../../bin/libc.lib.so, not found (try using -rpath or -rpath-link)


# absolute paths.. ///TODO: use $(TOP) or jam-relative paths instead, assuming <genode> lives next to <genode-haiku> ?
#++ could use TOP-relative paths like this:
#GENODE_BASE = $(TOP)/../develop_Genode/genode ;
#UPD: nope, can't do that as things are now, because the compile/link stage calls "cd ....." before calling gcc, so relative paths are no longer valid upon execution ; would need to change that first...

#GenodeRepos   ?= /SamCharlie/nimble_TMP_XPND/develop_hog-19-20-21/genode/repos ;  # adjust this path !
if ! $(GenodeRepos)
{
	EXIT "Jamrules: GenodeRepos undefined -- please define the 'GenodeRepos' variable on the command-line or in Jamrules" ;
}
VersionLibGCC ?= 12.3.0 ;  # gcc12 (use "10.3.0" for the gcc10 toolchain)
GccToolChain  ?= /usr/local/genode/tool/23.05/bin ;  # gcc12 (use ".../21.05/bin" for gcc10)
GenodeBuild   ?= $(GenodeRepos)/../build/x86_64 ;
HoG_TOP ?= $(TOP) ;  # if you're building apps "out of tree" (with their own $TOP value) and including this Jamrules, you'll need to override this value to specify where to find HoG (not needed for building Clock/Pulse/Mandelbrot since they are built from within the HoG source tree)

# Explanation of the above:
# $(GenodeRepos) should look like <genode-dir>/repos :
#		jam will search it for headers and bootloader stuff
# $(GenodeBuild) should look like <genode-dir>/build/x86_64 :
#		jam will search it for its __bin/__ subfolder and lift from it "acpi_drv", "init", "nitpicker" and so on, but also "libc.lib.so", "stdcxx.lib.so" and so on.
#		Those should have been built using the Genode build system.
# $(HoG_TOP) will just be equal to $(TOP) (i.e. this folder) when building HoG itself ;
#		only those who compile out-of-tree applications against HoG -- and thus have a distinct $(TOP) -- need to bother with this one.
# (the remaining rules below also implicitely derives a sort of  "$(GenodeTools)" from GenodeBuild, in order to retrieve tool/boot/bender...)


# For Genode/HoG builds, we specify "obj-HoG"
# by contrast to building for Haiku proper.
OBJDIR_PFX = "obj-HoG" ;
# This one might or might not be defined/hardcoded by Jam:
BE_HOST_CPU ?= $(OSPLAT) ;  # On Linux, unlike Haiku, BE_HOST_CPU is very unlikely to be defined, but we (likely) have a non-Nil $OSPLAT Jam variable... Its value is e.g. "X86" instead of "x86_64" but that should cause no harm
BE_HOST_CPU ?= "unknownplatform" ;  # if STILL not defined, we fall back to a default string that is ugly but (at least) does not depend on a (possibly Nil) variable

## where to find Genode files ############
#

# some of these definitions should occur early, as several are used right away
include $(HoG_TOP)/jam/jamrules-pkg-versions ;


## run/qemu ############
#

include $(HoG_TOP)/jam/jamrules-qemu ;
include $(HoG_TOP)/jam/jamrules-qemu-hog ;



## ar #####################
#

# this 'ar' configuration should solve build issues for bfs-on-genode et al,
# e.g. bizarre outcome differences between "jam" and "jam -a" ..etc.

AR = $(GccToolChain)/genode-x86-ar -rcs ;  # and not "ar ru" as in Haiku
#ARFLAGS = .. ;
#KEEPOBJS = true ? ;
NOARSCAN = true ;
RANLIB = ;

# override to remove the "updated" keyword and call rm before calling ar,
# so that it never works incrementally but always rebuilds from scratch:
actions together piecemeal Archive
{
	$(RM) $(<)  &&  $(AR) $(<) $(>)
}



## g++/link #####################
#

# variable "LINK" is set in rule SolibFromObjects

LINKFLAGS =
	-Wl,-melf_x86_64 -Wl,-gc-sections -Wl,-z -Wl,max-page-size=0x1000
	-Wl,--dynamic-list=$(GenodeRepos)/base/src/ld/genode_dyn.dl
	-nostdlib
	-Wl,-nostdlib -Wl,-Ttext=0x01000000 -m64 -mcmodel=large
	-Wl,--dynamic-linker=ld.lib.so
	-Wl,--eh-frame-hdr
	-Wl,-rpath-link=.  # from StackOverflow: "Note that I used -rpath key instead of -rpath-link. The difference is that -rpath-link is used at linking time only for checking that all symbols in the final executable can be resolved, whereas -rpath actually embeds the path you specify as parameter into the ELF:"
		# turns out we really should (esp. as of Genode 19.11) use "dot", otherwise at runtime ld.lib.so gets confused when trying to find/load the lib.so ROM
		# (even if it means we have to change the CWD before we invoke the linker)
	-Wl,-T
	-Wl,$(GenodeRepos)/base/src/ld/genode_dyn.ld
	#-Wl,--copy-dt-needed-entries  # helps (or not ?) with linking AutoCast, tells /bin/ld to be less pedantic about libs + shared-libs ordering...
	-Wl,--whole-archive
	-Wl,--start-group
	;



## g++/compile #####################
#

CC    = $(GccToolChain)/genode-x86-gcc ;
C++   = $(GccToolChain)/genode-x86-g++ ;
OPTIM = -g -O2 ;  # how come genode uses -g *and* -O at the same time, I thought that was not possible ?


if $(GenodeRepos)
{
	echo "...Compiling for Genode/HoG" ;
	
	DEFINES += __HAIKU__ ;   # used in Haiku's bin/network/ftpd/ to comment out some linux/bsd code etc
	DEFINES += HoG_GENODE ;  # used in HoG code proper, but also CC6 ..etc
}
else
{
	echo "** Compiling for Haiku proper **" ;
}


# Replicate the Genode build system configuration, which removes the GCC bloat:

BareMetalCompiler =
		# -- gcc/GCC headers diagnostic/debugging: display list of included .h headers with their paths (very useful to clear up confusion if there are e.g. multiple headers named "errno.h") --
	#-H    #--> very useful these days
		# -- Genode --
	-m64 -mcmodel=large -fPIC
	-fno-builtin-sin -fno-builtin-cos -fno-builtin-sinf -fno-builtin-cosf
	-ffunction-sections -fno-strict-aliasing -nostdinc
	-D__FreeBSD__=8 # "12" in 19.05+ ?  # seems to be needed for some "edge case" compiling units, otherwise one gets "error: declaration does not declare anything.. typedef __SIZE_TYPE__ __size_t.." -- see http://genodians.org/jschlatow/2021-06-10-screenshot-component
#	-D__ISO_C_VISIBLE=1999  # no longer use this in Genode 19.05+ ?
	-D_GLIBCXX_HAVE_MBSTATE_T -D_GLIBCXX_ATOMIC_BUILTINS_4
	;

CCFLAGS +=
	$(BareMetalCompiler)
	;
C++FLAGS +=
	$(BareMetalCompiler)
		# -- Genode best practices --
	-Wall -Wextra
	#-Weffc++
	#-Werror  # !
		# We stick to c++17 for now as we're still using the old Gcc10 toolchain, which won't handle c++20 in BWindow etc code
		# (if need be, code that might really need c++20 in BSoundPlayer could get special build treatment)
		# Genode now uses "gnu++20" but we remain on 17, as the least worst of 3 choices:
		# 1) use gnu++20, and the Gcc12 stdcxx.lib.so: our Gcc10 toolchain can't build stdcxx...
		# 2) use gnu++20, but force use of older Gcc10 stdcxx.lib.so: Seems it can't be built
		# 3) remain on gnu++17, with older Gcc10 stdcxx lib: The lib can be built,
		# We do build Genode with as-is makefiles (gnu++20) but it is not affected and can be built with Gcc10 (Genode probably makes little to no use of the STL)
	-std=gnu++17
	#  -std=gnu++20  # enabling this silences the warning in rec-play-mixer, but raises a *new* error in STL pair...
	#  -std=c++2a    # same thing with "c++2a" suggested in #5239 and #5227
	# So we remain at gnu++17 and enable "-fconcepts", hopefully that will suffice even in Genode 24.08+:
	-fconcepts  # or "-fconcepts-ts" ?
		# -- Haiku specifics --
	-Wno-register  # recommended by Norman (probably occurs in GCC8, since the C "register" keyword is deprecated)
#	-Wno-attributes  # if using gcc6 on 19.05+ ... xx remove once I switch to the new toolchain
	-Wno-multichar  # multichars are ubiquitous in Haiku code, no cause for alarm
	-Wno-unused-parameter  # unused params are just completely overwhelming in Haiku code <s>...
	-Wno-deprecated-copy  # another overwhelming one in InterfaceKit, ever since I started using Gcc10
		# ! replicate Haiku build setup, which uses the -include "super header" directive: !
	-include $(HoG_TOP)/haiku-on-genode/headers/build/HaikuBuildCompatibility.h
		#-include haiku-on-genode/headers/posix/sys/types.h ;
	;



#pragma mark - Headers handling -

#///ToDo-2: most of these should be in jam/jamrules-qemu-hog

# Forward some rules typically used in Haiku jamfiles, so
# as to re-use them, keeping jamfile modifications to a minimum:
#
rule UseHeaders  subfolders
{
	SetupHeadersHoG ;  #///later: or bail out if $(HDRS) is empty, like UsePrivateHeaders does ?
	
	if $(subfolders) {
		HDRS +=
			$(HeadersTop)/$(subfolders)
			;
	}
	else {
		Echo "  *** UseHeaders called without mandatory parameter ***" ;
	}
}


rule UsePrivateGenodeHeaders
{
	# Specifically, these are _Media Kit_ dependancies:
	HDRS +=
		$(GenodeRepos)/../contrib/$(Contrib_libav)/include/libav
		$(GenodeRepos)/world/src/lib/libav
		;
}

rule UsePublicHeaders  subfolders
{
	if ! $(HDRS) {  Echo "  *** UsePublicHeaders without previous *SetupHeadersHOG* configuration ! ***" ;  }
	
	if $(subfolders) {
		HDRS += $(HeadersTop)/haiku/$(subfolders) ;
	} else {
		Echo "  *** UsePublicHeaders called without *mandatory parameter* ***" ;
	}
}

rule UsePrivateHeaders  subfolders
{
	#SetupHeadersHoG ; -- nah, we don't want to reset HDRS, only append to it.
	# For now, detect that faulty condition and report it:
	if ! $(HDRS) {
		Echo "  *** UsePrivHeaders without previous *SetupHeadersHOG* configuration ! ***" ;
	}
	
	# compatible method, based on passed param:
	if $(subfolders) {
		HDRS +=
			$(HeadersTop)/private/$(subfolders)
			;
	}
	else {
		Echo "  *** UsePrivateHeaders called without *mandatory parameter* ***" ;
	}
}

rule UsePrivateSystemHeaders
{
	# ! reset HDR variable !
#	SetupHeadersHoG ;
	
	# append:
	HDRS +=
		$(HeadersTop)/private
		$(HeadersTop)/private/app
		$(HeadersTop)/private/interface
		$(HeadersTop)/private/locale
		$(HeadersTop)/private/storage
		$(HeadersTop)/private/shared
		$(HeadersTop)/private/support
		$(HeadersTop)/private/system
		;
	
	#xx ToDo: if a jamfile calls e.g. SetSubDirSupportedPlatformsBeOSCompatible after us, that would reset the HDRS to base
}


# -- setup for HoG (compiling Haiku code as a Genode component) --
#
rule SetupHeadersHoG
{
	#++ "local"..
	HeadersTop = $(HoG_TOP)/haiku-on-genode/headers ;
	KitsTop    = $(HoG_TOP)/haiku-on-genode/kits ;
	
	HDRS = ;  # reset! (this is a global var, so don't accumulate each time we read a Jamfile)
	
	HDRS +=
		## maybe figure out cwd-relative paths, for cleaner-looking invoke of gcc:
		##+++	[ FRelPath $(SUBDIR) : $(TOP)/headers/blah ]  #xx
		$(HeadersTop)/
		$(HeadersTop)/config
		$(HeadersTop)/haiku
		$(HeadersTop)/haiku/kernel  # find OS.h, fs_info.h
		$(HeadersTop)/haiku/interface
		$(HeadersTop)/haiku/net
		$(HeadersTop)/haiku/storage
		$(HeadersTop)/haiku/support  # find TypeConstants.h
		$(HeadersTop)/posix_overrides_temp
		$(KitsTop)/
		$(KitsTop)/app
		$(KitsTop)/interface
		$(KitsTop)/locale
		$(KitsTop)/mail
		$(KitsTop)/media
		$(KitsTop)/storage
		$(KitsTop)/support
		$(KitsTop)/translation
		$(GenodeRepos)/libports/include/stdcxx  # (GCC10) for e.g. #include <bits/c++config.h>
		$(GenodeRepos)/libports/include/spec/x86_64/stdcxx  # (GCC6) for e.g. #include <bits/c++config.h>
		$(GenodeRepos)/../contrib/$(Contrib_stdcxx)/include/stdcxx  # for e.g. #include <new>
		$(GenodeRepos)/../contrib/$(Contrib_stdcxx)/include/stdcxx/std  # for e.g. #include <type_traits>
		$(GenodeRepos)/../contrib/$(Contrib_stdcxx)/include/stdcxx/c_global  # for e.g. #include <cstdint>
		$(GenodeRepos)/../contrib/$(Contrib_libc)/include/libc  # for <sys/stat.h> et al
		$(GenodeRepos)/../contrib/$(Contrib_libc)/include/spec/x86_64/libc  # for <machine/_types.h> et al
		$(GenodeRepos)/base-nova/include/spec/64bit
		$(GenodeRepos)/base-nova/include
		$(GenodeRepos)/base/include/spec/x86
		$(GenodeRepos)/base/include/spec/x86_64
		$(GenodeRepos)/base/include/spec/64bit
		$(GenodeRepos)/base/include
		$(GenodeRepos)/os/include/spec/x86
		$(GenodeRepos)/os/include/spec/x86_64
		$(GenodeRepos)/os/include
		$(GenodeRepos)/libports/include/spec/64bit
		#? $(GenodeRepos)/libports/include/libc-genode
		$(GenodeRepos)/libports/include
		;
}



#pragma mark - Compiling and linking -


# cheat and pass eg "haiku.lib.so" (and not "haiku.lib.so.stripped") as first target, and append
# "....stripped" to the name ourselves, otherwise jam never calls Strip for lack of dependancy relevance:
#
actions together Strip
{
	$(GccToolChain)/genode-x86-strip -o $(<).stripped  $(<)
	# $(GccToolChain)/genode-x86-strip -o $(<)  $(>)
}

rule Strip
{
#	used to have a bogus "LocalDepends" (??) line here, oops!
#_d_ these as well:
#	local stripped_bin = $(raw_bin).stripped ;
	

#	Depends files : $(<) ;
	
	# e.g. Pulse.stripped depends on Pulse:
#hmmm nobody depends in "pulse.Stripped"... we hack its usage though symlinks, behind jam's back...

#	Depends $(<) : $(>) ;

#xxx results in "MakeLocate haiku.lib.so.stripped haiku-on-genode/kits/app-private", oops:
#	MakeLocate $(<) : $(LOCATE_TARGET) ;
	
#+ LocalClean clean : $(<) ;
	
	#SEARCH on $(>) = $(SEARCH_SOURCE) ;
}



#pragma mark - Linking: ABIs 1/2 -

GenodeAbi = $(GenodeBuild)/var/run/_common_/linking_abis ;

rule AbiLibrary  lib : from_file
{
	# "/path/<abi>libc.lib.so" -> "libc.lib":
	local abi_library = $(lib:D=:S=:G=) ;
	# "libc.lib" -> "libc"
	local library_prefix = $(abi_library:S=) ;
	# 'Source' file (either passed as a param, or set here to default value otherwise):
	from_file ?= $(GenodeBuild)/var/libcache/$(library_prefix)/$(library_prefix).abi.so ;
	
	SoftLink   $(lib) : $(from_file) ;  # e.g. "ln -s libc.abi.so as libc.lib.so"
}

# *Invoke* AbiLibrary rule here at top level, so that the SoftLinks are done no more than once
#
AbiLibrary  $(GenodeAbi)/haiku.lib.so : haiku.lib.so ;  # no Haiku 'abi', we link against the Haiku lib itself, this one causes no trouble anyway
AbiLibrary  $(GenodeAbi)/posix.lib.so ;
AbiLibrary  $(GenodeAbi)/libc.lib.so ;
AbiLibrary  $(GenodeAbi)/libm.lib.so ;
AbiLibrary  $(GenodeAbi)/stdcxx.lib.so ;
AbiLibrary  $(GenodeAbi)/zlib.lib.so ;
AbiLibrary  $(GenodeAbi)/jpeg.lib.so ;
AbiLibrary  $(GenodeAbi)/avcodec.lib.so ;
AbiLibrary  $(GenodeAbi)/avfilter.lib.so ;
AbiLibrary  $(GenodeAbi)/avformat.lib.so ;
AbiLibrary  $(GenodeAbi)/avresample.lib.so ;
AbiLibrary  $(GenodeAbi)/avutil.lib.so ;
AbiLibrary  $(GenodeAbi)/swscale.lib.so ;


#///ToDo: move to jamrules-qemu (responsible for HoG stuff), keep only GenodeExe (which replicates just Genode base) here
#///later: rename to "BeApplication" for clarity's sake, and add a forward/alias rule to forward from "BeApplication" to "Application", since our (imported) Haiku jamfiles refer indeed to "Application"
rule Application
{
	# Call this for full-fledged applications, e.g. Pulse.
	
	# We call the base rule, and then augment with additional libraries below.
	PosixExecutable $(<) : $(>) ;
	
	#///ToDo: do the Depends inside the "AddMaskedLib" call, not here
	# this one works, prevents going on with "misc-tests" when failing to compile haiku.lib.so
	# !
	Depends $(<) : haiku.lib.so ;
	# !
	#xx this next one, OTOH, does not seem to work, compilation proceeds without realising the lib failed..:
	# temporarily do this to satisfy the CC6 build (which does not SubInclude haiku/src/kits):
	
	# !
	AddMaskedLibrary $(1) : haiku ;
	
	if $(LayerLevel) >= 1  # >= 6  #/// using "6" triggers an LD.lib.so error at runtime, on "jam t1" runs, but only when building from scratch in a new folder... build system bug ? or even gcc itself, that still embeds the symbol somewhere?  anyway let's change to layer 1...
	{
		#///ToDo: use the jam-haiku-like conditional including technique, with an arobase or whatever, to EITHER link against ttf_font.lib.a OR against default-font-tff.o, but not both at the same time...
		NEEDLIBS on $(<) +=
			#$(GenodeBuild)/var/libcache/blit/blit.lib.a #-lblit   use bin/ here! XXX
			#$(GenodeBuild)/var/libcache/ttf_font/ttf_font.lib.a  # full-fledged TrueType font (e.g. Vera.ttf)
			$(GenodeBuild)/app/status_bar/binary_default.tff.o  # trivial-font
			;
	}
	
	# e.g., add a "LinkLibsOfApplication" rule, for use in AC...
	if $(LayerLevel) >= 7
	{
		AddMaskedLibrary $(1) : jpeg ;
		AddMaskedLibrary $(1) : avcodec ;
		AddMaskedLibrary $(1) : avfilter ;
		AddMaskedLibrary $(1) : avformat ;
		AddMaskedLibrary $(1) : avresample ;
		AddMaskedLibrary $(1) : avutil ;
		AddMaskedLibrary $(1) : swscale ;
	}
}



rule PosixExecutable
{
	# We build off GeExe
	GenodeExecutable $(<) : $(>) ;
	
	# Link against *ABI*.so instead of lib.so (needed as of Genode 19.05, otherwise linking fails with "./libc.lib.so: undefined reference to `__emutls_get_address'.... to `freebsd11_readdir' ....")
	# Further, as of Genode 19.11 we don't want to resolve to the "*.lib.so" files any more, but to "*.abi.so" files, which thus go to LINKLIBS instead of NEEDLIBS, via this function:
	AddMaskedLibrary $(1) : libc ;
	AddMaskedLibrary $(1) : libm ;
	AddMaskedLibrary $(1) : stdcxx ;
	if $(LayerLevel) >= 7
	{
		# libav has to be in rule App, and zlib in rule GeExe it seems:
		AddMaskedLibrary $(1) : zlib ;
	}
	
	#posix.lib.so  # we don't use posix.lib/construct.cc
	# (that would interfere with downstream "rule Application", including its use of haiku.lib.so which has its own custom component.construct())
	# (would make sense to refactor/split this rule to have a "rule LibcExecutable" and a genuine "rule PosixExecutable" though)
}


# no need to augment "actions Main", which already does the job.
#actions GenodeExecutable
#{
#}

rule GenodeExecutable
{
	# e.g. "Pulse" => "pulse"
	local LEAF = $(1:L) ;
	
	# T-  (this "optionally choose a special build folder" feature is used by e.g. bfs-on-genode/Jamfile)
	if ! $(LOCATE_ToBuildFolder)
	{
		LOCATE_ToBuildFolder = "bin-haiku_on_genode" ;
	}
	
	# T0
#///ToDo-2: Remove this  and build next to source files ? Or at least, build into $(scenario), e.g. hog-test/
	LOCATE_TARGET = $(GenodeBuild)/$(LOCATE_ToBuildFolder)/$(LEAF) ;  # e.g. <build>/Demos/pulse
	
	# T+
	# reset (hack to make up for "var on x = y" not working...) :
	LOCATE_ToBuildFolder = ;
	
	# link the .o's into an executable
	Main $(<) : $(>) ;
 #	MakeLocate $(<) : $(DEST) ; # tried to just set $(LOCATE_TARGET on main..) but won't work...
	#	LOCATE on $(<) =
	#		$(DEST)  #$(SUBDIR) #_d_ <build>/x86_64/Demos/pulse...
	#		#$(SUBDIR)/obj.$(BE_HOST_CPU) ;  # e.g. obj.x86_64
	#		;
	
	#LINK on $(<) = "$(GccToolChain)/genode-x86-g++" ;
	# xx still need the "libs" bash var for "LD.lib.so", let's get rid of that and delete this line: xx
	LINK on $(<) = "libs=$(GenodeBuild)/var/libcache; $(GccToolChain)/genode-x86-g++" ;
	
	# special stuff
	LINKLIBS on $(1) +=
		$libs/../../init/ld.lib.so  # this one is not a symlink to ld-nova.lib.so, but to LD.ABI.SO... Might be important?
		$(GenodeBuild)/var/libcache/format/format.lib.a  # Format::snprintf()
		-Wl,--no-whole-archive
		-Wl,--end-group
		$(GccToolChain)/../lib/gcc/x86_64-pc-elf/$(VersionLibGCC)/64/libgcc.a
		;
	
	# File..
	Strip  $(<) ;
	#	LOCATE on $(<).stripped =
	#		$(DEST)  ##$(SUBDIR) #_d_ <build>/x86_64/Demos/pulse...
	#		# XXX for now we have "symlinks magic", but ///ToDo: locate to var/run instead some day
	#		;
	
	#+ LocalClean clean : $(<).stripped ;
	
	#+ make a symbolic link of e.g. $(GenodeBuild)/debug/pulse ?
	
	#++++ create the bin/$(CasedLeaf) symlink ourselves!  The QEMU run script still needs it, even if jam based building does not any more..
#	SoftLink zzzz : $(GenodeBuild)/bin/$(CasedLeaf) ;
	
	# Create symlink for the "run" script to find the file, and copy it to e.g. tunetracker.iso
#	local CasedLeaf = $(1) ;
#	SoftLink $(GenodeBuild)/bin/$(CasedLeaf) : $(LOCATE_TARGET)/$(CasedLeaf).stripped ;
# _d_? we no longer need this now that jamrules picks up targets directly from origin
# would need to be kept, to make Jam and Gmake work together as we used to, though.
}



#pragma mark - Linking: ABIs 2/2 -


# careful to make the Elf/Xorriso build dir refer to the LIB.so and not the ABI.so, otherwise it (obviously) won't work,
# and unfortunately it's not obvious what the problem is, the error message has an embedded full-path with a "." dot, and that's it:
#	[init -> ArmyKnife] Error: Could not open ROM session for "/SamCharlie/nimble_TMP_XPND/develop_hog-19-20-21/genode/repos/."

#///ToDo-2: rename to: "LinkAbiLibrary"
rule AddMaskedLibrary  application : lib
{
	# Create $(library_prefix).lib.so as a symlink to var/libcache: $(library_prefix).abi.so
	
	LINKLIBS on $(application) +=
		$(lib).lib.so
		;
	
	local abi_link = <abi>$(lib).lib.so ;
	
	Depends $(application) : $(abi_link) ;  # e.g.: "Depends Pulse <abi>libc.lib.so"
	
	MakeLocate $(abi_link) : $(GenodeAbi) ;  # use a unique location, don't use $(LOCATE_TARGET), which is either bfs_fuse or mandelbrot or basic-layers...
	Depends $(application) : $(GenodeAbi)/$(abi_link:G=) ;  # e.g. "Depends Pulse ....var/run/_common_/linking_abis/<abi>libc.lib.so"
		#xxx the previous "Depends" up there might be useless, unlike this one which is clearly necessary
}



# Used to e.g. link lib_mapm.a to a GenodeExecutable like DeskCalc:
# that requires some gymnastics due to how the "gcc..." invokation follows a "cd" directory change
rule AddStaticLibrary_abiRelocated  application : lib : real_file
{
	LINKLIBS on $(application) += $(lib) ;
	
	Depends $(application) : $(lib) ;
	
	# MakeLocate:
	# we don't call it here, it's up to the library's Jamfile to call it (e.g. hai-src/libs/mapm/Jamfile)
}




## ld ############################################################################
#

rule HaikuKit  archive : sources
{
	# increment e.g. "interface_kit.a"
	Library
		$(achive) :  $(sources) ;
	
	
	local objs = $(sources:S=.o) ;
	
	# increment haiku.lib.a
	LibraryFromObjects
		haiku.lib.a : $(objs) ;
	
	# increment haiku.lib.so
	SolibFromObjects
		haiku.lib.so : $(objs) ;
	
	#++ Strip haiku.lib.a.stripped : haiku.lib.a ;
	#done below, now...:
}


rule SolibFromObjects  #+ "AddSolibObjects" ?  and alias the other to "AddArchiveObjects" ?
{
	local l s ;
	
	makeGristedName s : $(>) ;
	l = $(<:S=.so) ;
	
    DEPENDS lib : $(l) ;
    DEPENDS $(l) : $(s) ;
	
	MakeLocate $(l) $(l)($(s:BS)) : $(LOCATE_TARGET) ;  # xx Why not simply "$l : $locate_target" ? left-over from copy-paste of "LibraryFromObjs" rule ?
	
	Clean clean : $(l) ;
	
	# T0
	LinkSolib $(l) : $(s) ;
	Strip $(l) ;
	
	# T0 settings
	LINK on $(l) = "libs=$(GenodeBuild)/var/libcache; $(GccToolChain)/genode-x86-ld" ;
	
	# We juggle with variables in the order they appear in "rule Link"
	# rather than follow their semantics, so that the correct params
	# appear in the correct order.
	#
	#/// XXXXX should tweak/augment "rule Link" instead, as in "LinkSharedObj" !
	#
	LINKFLAGS on $(<) =
		-soname=$(l)  # e.g. "-soname=haiku.lib.so" (cherry-picked from upstream Genode 23.05+ ca. 2jun23)
		-shared  #$(LINKFLAGS) ;	LINKFLAGS on $(<) += -shared ; #-nostart ;
		--eh-frame-hdr
		-melf_x86_64
		-gc-sections
		-z max-page-size=0x1000
		-T $(GenodeRepos)/base/src/ld/genode_rel.ld
		--entry=0x0
		;
	
	#/// turn these "$libs" bash vars into jam-resolved values (as per $(GenodeBuild)/var/libcache above), and get rid of the bash variable above ?
	UNDEFS  on $(<) =
		--whole-archive --start-group
		$(GenodeBuild)/var/libcache/format/format.lib.a  # Format::snprintf() is used in e.g. vfs plug-ins -> let's make things easy for them...
######## these 3 are not used by genode makefiles when building vfs_fuse..??
#		$libs/base/base.lib.a
#		$libs/../../init/ld.lib.so
#		$libs/../../bin/vfs.lib.so
		$libs/ldso_so_support/ldso_so_support.lib.a
		;
	NEEDLIBS  on $(<) =
		;
	LINKLIBS  on $(<) =
		--end-group --no-whole-archive
		$(GccToolChain)/../lib/gcc/x86_64-pc-elf/$(VersionLibGCC)/64/libgcc.a
		;
}


rule LinkSolib library : objects
{
#	Strip $(library) ; #.stripped : $(library) ;
	
	#///+?	Clean clean : $(objects) ;
}

actions together LinkSolib bind NEEDLIBS
{
	$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) 
}
# -> Most Clean would be to pass some sort of -L or -rpath arg, to specify the folder that contains the objects <-





#### Jambase Overrides ###################################################


# override -I <header> so as to quote the header path (required by e.g. "MatchUTF8 v1.4/", plus it makes all paths clickable in terminal which is a nice bonus)
rule FIncludes
{
	return -I\"$(<)\" ;  #or use FQuote ?
}

# override .c compilation to quote the filepath (we have a couple cases of filepaths with white-spaces, only for C files so far, not C++)
actions Cc
{
	$(CC) -c -o $(<) $(CCFLAGS) $(CCDEFS) $(CCHDRS) "$(>)"
}


# GCC linker and CWD:
# getting away with a "remote" CWD was difficult before, but seems impossible as of Genode 19.11
# so I relented, let's override the rule to invoke "cd" before invoking the linker :
#
actions Link bind NEEDLIBS
{
	OLDCWD=$PWD
	#echo .. $OLDCWD ..
	cd "$(GenodeAbi)"
	
	$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)  &&  cd "$OLDCWD"
}


# override to use UNDEFS instead of NEEDLIBS
rule LinkLibraries
{
	local t ;

	# make library dependencies of target
	# set NEEDLIBS variable used by 'actions Main'

	if $(<:S)
	{
	    t = $(<) ;
	} else {
	    t = $(<:S=$(SUFEXE)) ;
	}

	Depends $(t) : $(>:S=$(SUFLIB)) ;
	
	# When linking AutoCast, UNDEFS gets bound to the correct files, whereas NEEDLIBS's e.g. "libc.lib.so" remains "bare", is not looked up/completed...
	#UPD: seems reversed now, when building NTFS plug-in ?
	NEEDLIBS on $(t) += $(>:S=$(SUFLIB)) ;
# this appears a lot, because jamrules_Maximalist (and its LinkLibraries call) is called not only by applications like AC.. but also by the libs themselves !  Should separate "use headers" and "use-shared-lib for linking"
#echo adding to undefs of .. $(t) .. these:.. $(2) ;
	#UNDEFS on $(t) += $(>:S=$(SUFLIB)) ;
}



# Symbolic links (SoftLink):
# Override to create *absolute* symlinks -- if we're passed a relative path, make it absolute with /bin/realpath.
# (relative links work relative to the link's folder, but jam calculates paths relative to its own CWD instead)
#
actions SoftLink
{
	#ok let's use /bin/realpath, should do the trick:
	ABSPATH=`realpath "$(2)"`
	#echo $ABSPATH
	$(RM) $(1) && $(LN) -s "$ABSPATH" $(1)  #$(RM) $(1) && $(LN) -s "$(2)" $(1)
	
	# old attempt:
	# hack: make the link ABSOLUTE (prefix with $PWD) ; or maybe it's a proper fix? :
	#	$(RM) $(<) && $(LN) -s "$PWD/$(>)" $(<)
	#sometimes it's ALREADY absolute, so we get a trainwreck, dang
}

#rule SoftLink
#{
#	Depends files : $(<) ;
#	Depends $(<) : $(>) ;
#	SEARCH on $(>) = $(SEARCH_SOURCE) ;
#	Clean clean : $(<) ;
#}


