Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 36 additions & 13 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ FBFLAGS := -maxerr 1
AS = $(BUILD_PREFIX)as
AR = $(BUILD_PREFIX)ar
CC = $(BUILD_PREFIX)gcc
# Objective-C compiler, used for the native Cocoa graphics driver on Darwin
OBJC = $(CC) -x objective-c
prefix := /usr/local

# Determine the makefile's directory, this may be a relative path when
Expand Down Expand Up @@ -342,8 +344,13 @@ ifneq ($(filter 386 486 586 686 i386 i486 i586 i686,$(TARGET_ARCH)),)
TARGET_ARCH := x86
endif

# Normalize TARGET_ARCH to arm
ifneq ($(filter arm%,$(TARGET_ARCH)),)
# Normalize TARGET_ARCH to aarch64 (macOS reports arm64)
ifneq ($(filter aarch64 arm64,$(TARGET_ARCH)),)
TARGET_ARCH := aarch64
endif

# Normalize TARGET_ARCH to arm (32-bit only, after aarch64 is handled)
ifneq ($(filter armv% arm,$(TARGET_ARCH)),)
TARGET_ARCH := arm
endif

Expand Down Expand Up @@ -579,13 +586,15 @@ ifeq ($(TARGET_OS),solaris)
endif

ifeq ($(TARGET_OS),darwin)
ALLCFLAGS += -I/opt/X11/include -I/usr/include/ffi

ifdef ENABLE_XQUARTZ
ALLFBCFLAGS += -d ENABLE_XQUARTZ
else
ALLCFLAGS += -DDISABLE_X11
endif
# Darwin uses the native Cocoa/CoreGraphics driver, so X11 (XQuartz) is never
# built here: it would drag in an extra runtime dependency for the legacy
# path only. FB's OpenGL support lives in the X11 gfx driver, so without it
# there is no GL driver either -- gfx_opengl.c would otherwise still call
# the driver hook fb_hGL_GetProcAddress(), leaving libfbgfx with an undefined
# symbol.
ALLCFLAGS += -I/usr/include/ffi
ALLCFLAGS += -DDISABLE_X11
ALLCFLAGS += -DDISABLE_OPENGL
endif

ifneq ($(filter cygwin win32,$(TARGET_OS)),)
Expand Down Expand Up @@ -717,10 +726,15 @@ LIBFBRTMTPIC_C := $(patsubst %,$(libfbmtpicobjdir)/%,$(filter-out $(patsubst $(l
LIBFBGFX_H := $(sort $(foreach i,$(GFXLIB2_DIRS),$(wildcard $(i)/*.h)) $(LIBFB_H))
LIBFBGFX_C := $(sort $(foreach i,$(GFXLIB2_DIRS),$(patsubst $(i)/%.c,$(libfbgfxobjdir)/%.o,$(wildcard $(i)/*.c))))
LIBFBGFX_S := $(sort $(foreach i,$(GFXLIB2_DIRS),$(patsubst $(i)/%.s,$(libfbgfxobjdir)/%.o,$(wildcard $(i)/*.s))))
# Objective-C sources (the native Cocoa driver on Darwin)
LIBFBGFX_M := $(sort $(foreach i,$(GFXLIB2_DIRS),$(patsubst $(i)/%.m,$(libfbgfxobjdir)/%.o,$(wildcard $(i)/*.m))))
LIBFBGFXPIC_C := $(patsubst $(libfbgfxobjdir)/%,$(libfbgfxpicobjdir)/%,$(LIBFBGFX_C))
LIBFBGFXPIC_M := $(patsubst $(libfbgfxobjdir)/%,$(libfbgfxpicobjdir)/%,$(LIBFBGFX_M))
LIBFBGFXMT_C := $(patsubst $(libfbgfxobjdir)/%,$(libfbgfxmtobjdir)/%,$(LIBFBGFX_C))
LIBFBGFXMT_S := $(patsubst $(libfbgfxobjdir)/%,$(libfbgfxmtobjdir)/%,$(LIBFBGFX_S))
LIBFBGFXMT_M := $(patsubst $(libfbgfxobjdir)/%,$(libfbgfxmtobjdir)/%,$(LIBFBGFX_M))
LIBFBGFXMTPIC_C := $(patsubst $(libfbgfxobjdir)/%,$(libfbgfxmtpicobjdir)/%,$(LIBFBGFX_C))
LIBFBGFXMTPIC_M := $(patsubst $(libfbgfxobjdir)/%,$(libfbgfxmtpicobjdir)/%,$(LIBFBGFX_M))


RTL_LIBS := $(libdir)/$(FB_LDSCRIPT)
Expand Down Expand Up @@ -768,6 +782,7 @@ ifndef V
QUIET_FBC = @echo "FBC $@";
QUIET_LINK = @echo "LINK $@";
QUIET_CC = @echo "CC $@";
QUIET_OBJC = @echo "OBJC $@";
QUIET_CPPAS = @echo "CPPAS $@";
QUIET_AS = @echo "AS $@";
QUIET_AR = @echo "AR $@";
Expand Down Expand Up @@ -984,29 +999,37 @@ $(LIBFBMTRTPIC_BAS): $(libfbrtmtpicobjdir)/%.o: %.c $(LIBFBRT_BI) | $(libfbrtmtp
.PHONY: gfxlib2
gfxlib2: $(GFX_LIBS)

$(libdir)/libfbgfx.a: $(LIBFBGFX_C) $(LIBFBGFX_S) | $(libdir)
$(libdir)/libfbgfx.a: $(LIBFBGFX_C) $(LIBFBGFX_S) $(LIBFBGFX_M) | $(libdir)
$(QUIET_AR)rm -f $@; $(AR) rcs $@ $^
$(LIBFBGFX_C): $(libfbgfxobjdir)/%.o: %.c $(LIBFBGFX_H) | $(libfbgfxobjdir)
$(QUIET_CC)$(CC) $(ALLCFLAGS) -c $< -o $@
$(LIBFBGFX_S): $(libfbgfxobjdir)/%.o: %.s $(LIBFBGFX_H) | $(libfbgfxobjdir)
$(QUIET_CPPAS)$(CC) -x assembler-with-cpp $(ALLCFLAGS) -c $< -o $@
$(LIBFBGFX_M): $(libfbgfxobjdir)/%.o: %.m $(LIBFBGFX_H) | $(libfbgfxobjdir)
$(QUIET_OBJC)$(OBJC) $(ALLCFLAGS) -c $< -o $@

$(libdir)/libfbgfxpic.a: $(LIBFBGFXPIC_C) | $(libdir)
$(libdir)/libfbgfxpic.a: $(LIBFBGFXPIC_C) $(LIBFBGFXPIC_M) | $(libdir)
$(QUIET_AR)rm -f $@; $(AR) rcs $@ $^
$(LIBFBGFXPIC_C): $(libfbgfxpicobjdir)/%.o: %.c $(LIBFBGFX_H) | $(libfbgfxpicobjdir)
$(QUIET_CC)$(CC) -fPIC $(ALLCFLAGS) -c $< -o $@
$(LIBFBGFXPIC_M): $(libfbgfxpicobjdir)/%.o: %.m $(LIBFBGFX_H) | $(libfbgfxpicobjdir)
$(QUIET_OBJC)$(OBJC) -fPIC $(ALLCFLAGS) -c $< -o $@

$(libdir)/libfbgfxmt.a: $(LIBFBGFXMT_C) $(LIBFBGFXMT_S) | $(libdir)
$(libdir)/libfbgfxmt.a: $(LIBFBGFXMT_C) $(LIBFBGFXMT_S) $(LIBFBGFXMT_M) | $(libdir)
$(QUIET_AR)rm -f $@; $(AR) rcs $@ $^
$(LIBFBGFXMT_C): $(libfbgfxmtobjdir)/%.o: %.c $(LIBFBGFX_H) | $(libfbgfxmtobjdir)
$(QUIET_CC)$(CC) -DENABLE_MT $(ALLCFLAGS) -c $< -o $@
$(LIBFBGFXMT_S): $(libfbgfxmtobjdir)/%.o: %.s $(LIBFBGFX_H) | $(libfbgfxmtobjdir)
$(QUIET_CPPAS)$(CC) -x assembler-with-cpp -DENABLE_MT $(ALLCFLAGS) -c $< -o $@
$(LIBFBGFXMT_M): $(libfbgfxmtobjdir)/%.o: %.m $(LIBFBGFX_H) | $(libfbgfxmtobjdir)
$(QUIET_OBJC)$(OBJC) -DENABLE_MT $(ALLCFLAGS) -c $< -o $@

$(libdir)/libfbgfxmtpic.a: $(LIBFBGFXMTPIC_C) | $(libdir)
$(libdir)/libfbgfxmtpic.a: $(LIBFBGFXMTPIC_C) $(LIBFBGFXMTPIC_M) | $(libdir)
$(QUIET_AR)rm -f $@; $(AR) rcs $@ $^
$(LIBFBGFXMTPIC_C): $(libfbgfxmtpicobjdir)/%.o: %.c $(LIBFBGFX_H) | $(libfbgfxmtpicobjdir)
$(QUIET_CC)$(CC) -DENABLE_MT -fPIC $(ALLCFLAGS) -c $< -o $@
$(LIBFBGFXMTPIC_M): $(libfbgfxmtpicobjdir)/%.o: %.m $(LIBFBGFX_H) | $(libfbgfxmtpicobjdir)
$(QUIET_OBJC)$(OBJC) -DENABLE_MT -fPIC $(ALLCFLAGS) -c $< -o $@

################################################################################

Expand Down
15 changes: 13 additions & 2 deletions src/compiler/ast-node-data.bas
Original file line number Diff line number Diff line change
Expand Up @@ -266,9 +266,20 @@ end function

private sub hCreateDataDesc( )
static as FBARRAYDIM dTB(0)
dim as integer byalign

'' Using FIELD = 1, to pack it as done by the rtlib -- except on Darwin,
'' where the linker requires pointer-sized relocations to be aligned to
'' the pointer size. A packed { short, void* } puts the DATA entries'
'' pointers at offset 2 (and every 10 bytes after that), which ld64
'' rejects ("pointer not aligned ...", fatal on arm64). There the layout
'' must use the natural pointer alignment, matching src/rtlib/fb_data.h.
byalign = 1
if( fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN ) then
byalign = env.pointersize
end if

'' Using FIELD = 1, to pack it as done by the rtlib
ast.data.desc = symbStructBegin( NULL, NULL, NULL, "__FB_DATADESC$", NULL, FALSE, 1, FALSE, 0, 0 )
ast.data.desc = symbStructBegin( NULL, NULL, NULL, "__FB_DATADESC$", NULL, FALSE, byalign, FALSE, 0, 0 )

'' type as short
symbAddField( ast.data.desc, "type", 0, dTB(), _
Expand Down
10 changes: 9 additions & 1 deletion src/compiler/fb.bas
Original file line number Diff line number Diff line change
Expand Up @@ -1768,7 +1768,15 @@ function fbGetBackendValistType _
typedef = FB_CVA_LIST_BUILTIN_ARM

case FB_CPUFAMILY_AARCH64
typedef = FB_CVA_LIST_BUILTIN_AARCH64
select case env.clopt.target
case FB_COMPTARGET_DARWIN
'' Apple's arm64 ABI uses a plain pointer-like va_list (8 bytes,
'' sizeof(va_list) == sizeof(char*)), not the AAPCS64
'' __va_list_tag struct that Linux/BSD aarch64 use.
typedef = FB_CVA_LIST_BUILTIN_POINTER
case else
typedef = FB_CVA_LIST_BUILTIN_AARCH64
end select

case FB_CPUFAMILY_PPC
typedef = FB_CVA_LIST_BUILTIN_POINTER
Expand Down
65 changes: 48 additions & 17 deletions src/compiler/fbc.bas
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,13 @@ private sub hSetOutName( )
select case( fbGetOption( FB_COMPOPT_TARGET ) )
case FB_COMPTARGET_CYGWIN, FB_COMPTARGET_WIN32
fbc.outname += ".dll"
case FB_COMPTARGET_LINUX, FB_COMPTARGET_DARWIN, _
case FB_COMPTARGET_DARWIN
'' Mach-O shared libraries are .dylib; .so is the loadable
'' bundle extension, and fb_DylibLoad() looks for the .dylib
'' name first on Darwin.
fbc.outname = hStripFilename( fbc.outname ) + _
"lib" + hStripPath( fbc.outname ) + ".dylib"
case FB_COMPTARGET_LINUX, _
FB_COMPTARGET_FREEBSD, FB_COMPTARGET_OPENBSD, _
FB_COMPTARGET_NETBSD, FB_COMPTARGET_DRAGONFLY, _
FB_COMPTARGET_SOLARIS, FB_COMPTARGET_ANDROID
Expand Down Expand Up @@ -840,6 +846,8 @@ private function hLinkFiles( ) as integer
case FB_CPUFAMILY_ARM
'' fixme: this is clearly too specific
ldcline += "-arch armv6 "
case FB_CPUFAMILY_AARCH64
ldcline += "-arch arm64 "
end select
end select

Expand Down Expand Up @@ -945,7 +953,13 @@ private function hLinkFiles( ) as integer

if( fbGetOption( FB_COMPOPT_OUTTYPE ) = FB_OUTTYPE_DYNAMICLIB ) then
dllname = hStripPath( hStripExt( fbc.outname ) )
ldcline += " -shared -h" + hStripPath( fbc.outname )
if( fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN ) then
'' Darwin's linker (ld64) has no -shared/-h; it uses -dynamiclib
'' and records the install name via -install_name.
ldcline += " -dynamiclib -install_name " + QUOTE + dllname + QUOTE
else
ldcline += " -shared -h" + hStripPath( fbc.outname )
end if

'' Turn libfoo into foo, so it can be checked against -l foo below
if( left( dllname, 3 ) = "lib" ) then
Expand Down Expand Up @@ -987,7 +1001,13 @@ private function hLinkFiles( ) as integer
if( (fbGetOption( FB_COMPOPT_OUTTYPE ) = FB_OUTTYPE_DYNAMICLIB) or _
fbGetOption( FB_COMPOPT_EXPORT ) ) and _
(fbGetOption( FB_COMPOPT_TARGET ) <> FB_COMPTARGET_SOLARIS) then
ldcline += " --export-dynamic"
'' Darwin links through the clang driver, which wants the option
'' spelled with -Wl, rather than passed through as --export-dynamic
if( fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN ) then
ldcline += " -Wl,-export_dynamic"
else
ldcline += " --export-dynamic"
end if
end if

case FB_COMPTARGET_XBOX
Expand Down Expand Up @@ -1166,7 +1186,10 @@ private function hLinkFiles( ) as integer
FB_COMPTARGET_FREEBSD, FB_COMPTARGET_OPENBSD, _
FB_COMPTARGET_NETBSD, FB_COMPTARGET_DRAGONFLY, FB_COMPTARGET_SOLARIS

if( fbGetOption( FB_COMPOPT_OUTTYPE ) = FB_OUTTYPE_EXECUTABLE) then
'' Darwin's linker takes no explicit crt1.o; the C compiler driver
'' supplies the startup object (it lives inside libSystem).
if( (fbGetOption( FB_COMPOPT_OUTTYPE ) = FB_OUTTYPE_EXECUTABLE) and _
(fbGetOption( FB_COMPOPT_TARGET ) <> FB_COMPTARGET_DARWIN) ) then
if( fbGetOption( FB_COMPOPT_PROFILE ) ) then
select case as const fbGetOption( FB_COMPOPT_TARGET )
case FB_COMPTARGET_OPENBSD, FB_COMPTARGET_NETBSD
Expand Down Expand Up @@ -1286,6 +1309,13 @@ private function hLinkFiles( ) as integer
wend
end scope

'' The native Cocoa gfx driver needs these system frameworks. They ship
'' with every macOS install, and are only added for programs that use gfx.
if( (fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN) and _
fbGetOption( FB_COMPOPT_FBGFX ) ) then
ldcline += " -framework Cocoa -framework QuartzCore -framework CoreGraphics"
end if

if (fbGetOption( FB_COMPOPT_TARGET ) <> FB_COMPTARGET_DARWIN) then
if( fbGetOption( FB_COMPOPT_TARGET ) <> FB_COMPTARGET_JS ) then
'' End of lib group
Expand Down Expand Up @@ -1322,18 +1352,17 @@ private function hLinkFiles( ) as integer

end select

if( fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN ) then
ldcline += " -macosx_version_min 10.4"
end if
'' Note: on Darwin the deployment target (-mmacosx-version-min) is supplied
'' by the C compiler driver used for linking, not hard-coded here.

'' This is required for 64-bit modules on *nix-y platforms
'' for the unwind tables to have any effect
'' Windows doesn't need this option
'' (ld64 rejects --eh-frame-hdr; Darwin is handled by clang instead)
select case as const fbGetOption( FB_COMPOPT_TARGET )
case FB_COMPTARGET_LINUX, FB_COMPTARGET_FREEBSD, _
FB_COMPTARGET_OPENBSD, FB_COMPTARGET_NETBSD, _
FB_COMPTARGET_DRAGONFLY, FB_COMPTARGET_SOLARIS, _
FB_COMPTARGET_DARWIN
FB_COMPTARGET_DRAGONFLY, FB_COMPTARGET_SOLARIS
dim as long outtype = fbGetOption( FB_COMPOPT_OUTTYPE )
if outtype = FB_OUTTYPE_EXECUTABLE OrElse outtype = FB_OUTTYPE_DYNAMICLIB Then
dim as long cpufamily = fbGetCpuFamily( )
Expand Down Expand Up @@ -1408,6 +1437,10 @@ private function hLinkFiles( ) as integer
var ld = FBCTOOL_LD
if( fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_JS ) then
ld = FBCTOOL_EMLD
elseif( fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN ) then
'' ld64 can't be driven like GNU ld (different crt handling, and it
'' rejects several GNU options), so use the C compiler driver to link.
ld = FBCTOOL_CLANG
end if

if( fbcRunBin( "linking", ld, ldcline ) = FALSE ) then
Expand Down Expand Up @@ -4277,11 +4310,9 @@ private sub hAddDefaultLibs( )
fbcAddDefLibPath( "/usr/X11R6/lib" )
#endif

#if defined(__FB_DARWIN__) and defined(ENABLE_XQUARTZ)
fbcAddDefLibPAth( "/opt/X11/lib" )
#endif

#if (not defined(__FB_DARWIN__)) or defined(ENABLE_XQUARTZ)
'' Darwin uses the native Cocoa driver and never links X11, so the
'' X11 libraries below are only added for the other unix targets.
#if not defined(__FB_DARWIN__)
fbcAddDefLib( "X11" )
fbcAddDefLib( "Xext" )
fbcAddDefLib( "Xpm" )
Expand All @@ -4308,9 +4339,9 @@ private sub hAddDefaultLibs( )
end if

case FB_COMPTARGET_DARWIN
fbcAddDefLib( "gcc" )
fbcAddDefLib( "System" )
fbcAddDefLib( "pthread" )
'' There is no libgcc on macOS unless a GCC toolchain is installed;
'' the clang driver pulls in libSystem (and thus libc/libm/pthread)
'' by itself. libncurses is still needed by the FB runtime.
fbcAddDefLib( "ncurses" )

case FB_COMPTARGET_DOS
Expand Down
19 changes: 17 additions & 2 deletions src/compiler/rtl-error.bas
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,16 @@ function rtlErrorCheck( byval expr as ASTNODE ptr ) as ASTNODE ptr
t = astNewLINK( t, astNewBOP( AST_OP_EQ, expr, astNewCONSTi( 0 ), nxtlabel, AST_OPOPT_NONE ), AST_LINK_RETURN_NONE )

'' fb_ErrorThrow()
t = astNewLINK( t, astNewBRANCH( AST_OP_JUMPPTR, NULL, hErrorThrow( reslabel, nxtlabel ) ), AST_LINK_RETURN_NONE )
'' Only -ex (-exx) enables RESUME support, and only then is a resume
'' label handed to the throw. Without one the throw can never return
'' a usable jump target, so a plain call is equivalent -- and it keeps
'' the generated C acceptable to clang, which rejects `goto *ptr` in
'' functions that take no label address.
if( env.clopt.resumeerr ) then
t = astNewLINK( t, astNewBRANCH( AST_OP_JUMPPTR, NULL, hErrorThrow( reslabel, nxtlabel ) ), AST_LINK_RETURN_NONE )
else
t = astNewLINK( t, hErrorThrow( reslabel, nxtlabel ), AST_LINK_RETURN_NONE )
end if

'' end if
t = astNewLINK( t, astNewLABEL( nxtlabel ), AST_LINK_RETURN_NONE )
Expand Down Expand Up @@ -361,7 +370,13 @@ sub rtlErrorThrow _
end if

'' dst
astAdd( astNewBRANCH( AST_OP_JUMPPTR, NULL, proc ) )
'' As in rtlErrorCheck(): an indirect jump is only meaningful when RESUME
'' support (-ex) is enabled and a resume label was passed along.
if( env.clopt.resumeerr ) then
astAdd( astNewBRANCH( AST_OP_JUMPPTR, NULL, proc ) )
else
astAdd( proc )
end if

astAdd( astNewLABEL( nxtlabel ) )
end sub
Expand Down
20 changes: 20 additions & 0 deletions src/gfxlib2/darwin/fb_gfx_cocoa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef __FB_GFX_COCOA_H__
#define __FB_GFX_COCOA_H__

#include <sys/types.h>
#include "../fb_gfx.h"

extern const GFXDRIVER fb_gfxDriverCocoa;

extern void fb_hCocoaLock(void);
extern void fb_hCocoaUnlock(void);
extern void fb_hCocoaWaitVSync(void);
extern void fb_hCocoaSetPalette(int index, int r, int g, int b);
extern int fb_hCocoaGetMouse(int *x, int *y, int *z, int *buttons, int *clip);
extern void fb_hCocoaSetMouse(int x, int y, int cursor, int clip);
extern void fb_hCocoaSetWindowTitle(char *title);
extern int fb_hCocoaSetWindowPos(int x, int y);
extern int *fb_hCocoaFetchModes(int depth, int *size);
extern int fb_hCocoaScreenInfo(ssize_t *width, ssize_t *height, ssize_t *depth, ssize_t *refresh);

#endif
Loading