SubDir HAIKU_TOP src tools gensyscalls ;

# preprocess the syscalls header

rule PreprocessSyscalls
{
	# PreprocessSyscalls <preprocessedHeader> : <header> : <parsable> ;
	#
	local parsable = $(3) ;
	local parsableDefine ;

	if $(parsable) {
		parsableDefine = GEN_SYSCALL_INFOS_PROCESSING ;
	}

	Depends $(<) : $(>) ;

	local headers = [ on $(1) return $(SEARCH_SOURCE) $(SUBDIRHDRS) $(HDRS) ] ;
	local sysHeaders =
		$(TARGET_PRIVATE_SYSTEM_HEADERS)
		[ ArchHeaders $(TARGET_ARCH) ]
		[ on $(1) return $(SUBDIRSYSHDRS) $(SYSHDRS) ]
		$(HAIKU_HDRS) ;

	HDRS on $(<) = $(headers) ;
	SYSHDRS on $(<) = $(sysHeaders) ;

	HDRRULE on $(>) = HdrRule ;
	HDRSCAN on $(>) = $(HDRPATTERN) ;
	HDRSEARCH on $(>) = $(headers) $(sysHeaders) $(STDHDRS) ;
	HDRGRIST on $(>) = $(HDRGRIST) ;

	DEFINES on $(<) += $(HAIKU_DEFINES) $(parsableDefine) ;

	CCFLAGS on $(<) += $(HAIKU_CCFLAGS) $(SUBDIRCCFLAGS) $(OPTIM) ;
	CCHDRS on $(<) = [ FIncludes $(headers) : $(HAIKU_LOCAL_INCLUDES_OPTION) ]
		$(HAIKU_INCLUDES_SEPARATOR)
		[ FSysIncludes $(sysHeaders) : $(HAIKU_SYSTEM_INCLUDES_OPTION) ] ;
	CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
}

actions PreprocessSyscalls
{
	$(HAIKU_C++) -xc++ -E "$(2)" $(CCFLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
}

local syscallsHeader = [ FGristFiles syscalls.h ] ;
SEARCH on $(syscallsHeader) = [ FDirName $(HAIKU_TOP) headers private system ] ;

# We generate two preprocessed headers. One for parsing by gensyscallinfos
# (it contains #pragmas) and one for inclusion by the generated
# gensyscalls_infos.cpp.
local syscallsHeaderPPParsable = [ FGristFiles syscalls.h.pp.parsable ] ;
local syscallsHeaderPP = [ FGristFiles syscalls.h.pp ] ;
MakeLocateArch $(syscallsHeaderPPParsable) $(syscallsHeaderPP) ;

PreprocessSyscalls $(syscallsHeaderPPParsable) : $(syscallsHeader) : true ;
PreprocessSyscalls $(syscallsHeaderPP) : $(syscallsHeader) ;


# build gensyscallinfos

BuildPlatformMain gensyscallinfos
	: gensyscallinfos.cpp
	: $(HOST_LIBSTDC++) $(HOST_LIBSUPC++)
;


# generate the syscall infos source file

local syscallInfos = [ FGristFiles gensyscalls_infos.cpp ] ;
MakeLocateArch $(syscallInfos) ;

rule GenSyscallInfos {
	Depends $(1) : gensyscallinfos $(2) ;
	GenSyscallInfos1 $(1) : gensyscallinfos $(2) ;
}

actions GenSyscallInfos1 {
	$(2[1]) $(2[2]) $(1)
}

GenSyscallInfos $(syscallInfos) : $(syscallsHeaderPPParsable) ;

SubDirHdrs [ FDirName $(SUBDIR) arch $(TARGET_ARCH) ] ;


# build gensyscalls

BuildPlatformMain gensyscalls : gensyscalls.cpp $(syscallInfos) ;
LinkAgainst gensyscalls : $(HOST_LIBSTDC++) $(HOST_LIBSUPC++) ;

# Explicitly tell jam that gensyscalls.cpp includes the generated header.
Includes [ FGristFiles gensyscalls.cpp ] : $(syscallsHeaderPP) ;


# generate the output files

# place them where they are needed
local dir = $(HAIKU_COMMON_DEBUG_OBJECT_DIR) ;
MakeLocate <syscalls>syscalls.S.inc : [ FDirName $(dir) system libroot os ] ;
MakeLocate <syscalls>syscall_dispatcher.h : [ FDirName $(dir) system kernel ] ;
MakeLocate <syscalls>syscall_numbers.h : [ FDirName $(dir) system kernel ] ;
MakeLocate <syscalls>syscall_table.h : [ FDirName $(dir) system kernel ] ;
MakeLocate <syscalls>strace_syscalls.h : [ FDirName $(dir) bin debug strace ] ;

rule GenSyscallsFile {
	Depends $(1) : gensyscalls ;
	GenSyscallsFile1 $(1) : gensyscalls ;
}

actions GenSyscallsFile1 {
	$(2[1]) -c $(1)
}

rule GenSyscallsDispatcher {
	Depends $(1) : gensyscalls ;
	GenSyscallsDispatcher1 $(1) : gensyscalls ;
}

actions GenSyscallsDispatcher1 {
	$(2[1]) -d $(1)
}

rule GenSyscallsNumbers {
	Depends $(1) : gensyscalls ;
	GenSyscallsNumbers1 $(1) : gensyscalls ;
}

actions GenSyscallsNumbers1 {
	$(2[1]) -n $(1)
}

rule GenSyscallsTable {
	Depends $(1) : gensyscalls ;
	GenSyscallsTable1 $(1) : gensyscalls ;
}

actions GenSyscallsTable1 {
	$(2[1]) -t $(1)
}

rule GenSyscallsSTrace {
	Depends $(1) : gensyscalls ;
	GenSyscallsSTrace1 $(1) : gensyscalls ;
}

actions GenSyscallsSTrace1 {
	$(2[1]) -s $(1)
}

GenSyscallsFile <syscalls>syscalls.S.inc ;
GenSyscallsDispatcher <syscalls>syscall_dispatcher.h ;
GenSyscallsNumbers <syscalls>syscall_numbers.h ;
GenSyscallsTable <syscalls>syscall_table.h ;
GenSyscallsSTrace <syscalls>strace_syscalls.h ;
