diff --git a/changelog.txt b/changelog.txt index 0eaa31788e..d633521bdb 100644 --- a/changelog.txt +++ b/changelog.txt @@ -9,11 +9,20 @@ Version 1.09.0 - crt headers: add const qualifiers in crt/stdio.bi, crt/sys/stat.bi, crt/wchar.bi - crt headers: add const qualifiers in crt/sys/win32/stat.bi, crt/win32/stdio.bi - github #325, #326: fbc: internal changes for string processing functions +- fbc-tests: xargs on freebsd does not support the '-a filename' option, use 'cat filename | xargs' instead +- fbc: gen gcc: allow compiling with GCC 4.5 and older, by avoiding -Wno-unused-but-set-variable (TeeEmCee) +- fbc: internal function fbcQueryGcc() to ask gcc for the correct as & ld to use (TeeEmCee) +- rtlib: freebsd: minimum thread stacksize 8192 KiB [added] - fbc: add '-z fbrt' command line option to link against libfbrt*.a instead of libfb*.a - makefile: add target for fbrt, fb runtime library written in fbc. Bulid libfbrt*.a and merge any missing object modules from libfb*.a - github #325, #326: fbc: add support for wstrings used with __FB_EVAL__() +- crt headers: minimal crt headers to compile fbc and build test-suite on freebsd-13.0-i386 +- darwin: Implemented objinfo for Darwin/OSX Mach-O .o files, so #inclib etc. work (TeeEmCee) +- darwin: put objinfo in 'fbctinf, __DATA' section instead of '.fbctinf' (TeeEmCee) +- fbc: add '-entry name' command line option to set program entry point (TeeEmCee) +- added objinfo support for ELF files on freebsd [fixed] - github #315: set parameters when calling SCREENCONTROL (was broken in fbc 1.08.0 due to new LONG/LONGINT SCREENCONTROL API's) @@ -25,6 +34,8 @@ Version 1.09.0 - github #324: fbc: When converting a wide character escape sequence to an internal format, the escaped value is incorrect. (Skyfish) - fbc: remove warning on function suffix in '-lang qb' - github #325, #326: fbc: constant folding ASC() on constant strings with embedded NUL characters - previously ASC returned 0 for anything past the first embedded NUL char, for example ASC(!"A\000B",3) incorrectly returned 0 and should return 66 +- rtlib: define fb_AtomicSetThreadFlags() even in the non-multithreaded version of run time library - it is needed by thread_core.c:threadproc() - unusual but not impossible to link the non-multithreaded rtlib and call thread functions +- darwin: a variety of improvements to allow compiling and linking (TeeEmCee) Version 1.08.0 diff --git a/doc/fbc.1 b/doc/fbc.1 index 8462f78ba0..38cb45d7f2 100644 --- a/doc/fbc.1 +++ b/doc/fbc.1 @@ -63,6 +63,9 @@ Enable full error location reporting \fB\-enullptr\fR Enable null-pointer checking .TP +\fB\-entry\fR \fIname\fR +Change the entry point of the program from main() +.TP \fB\-ex\fR \fB-e\fR plus RESUME support .TP diff --git a/inc/crt/freebsd/stdio.bi b/inc/crt/freebsd/stdio.bi new file mode 100644 index 0000000000..df56f7549c --- /dev/null +++ b/inc/crt/freebsd/stdio.bi @@ -0,0 +1,32 @@ +#ifndef __crt_freebsd_stdio_bi__ +#define __crt_freebsd_stdio_bi__ + +#define _IOFBF 0 +#define _IOLBF 1 +#define _IONBF 2 +#define BUFSIZ 1024 +#define FILENAME_MAX 1024 +#define FOPEN_MAX 20 +#define P_tmpdir "/tmp" 'Actual P_tmpdir on FreeBSD is "/tmp/" +#define L_tmpnam 1024 +#define TMP_MAX 308915776 + +type FILE as _sFILE + +extern stdin alias "__stdinp" as FILE ptr +extern stdout alias "__stdoutp" as FILE ptr +extern stderr alias "__stderrp" as FILE ptr + +type fpos_t as longint 'Equal to __off_t + +extern "c" +declare function snprintf (byval s as zstring ptr, byval n as size_t, byval format as zstring ptr, ...) as long +declare function vsnprintf (byval s as zstring ptr, byval n as size_t, byval format as zstring ptr, byval arg as va_list) as long +declare function popen (byval as zstring ptr, byval as zstring ptr) as FILE ptr +declare function pclose (byval as FILE ptr) as long +declare function getw (byval as FILE ptr) as long +declare function putw (byval as long, byval as FILE ptr) as long + +end extern + +#endif diff --git a/inc/crt/freebsd/time.bi b/inc/crt/freebsd/time.bi new file mode 100644 index 0000000000..36b8a56ce7 --- /dev/null +++ b/inc/crt/freebsd/time.bi @@ -0,0 +1,63 @@ +'' +'' +'' time -- header translated with help of SWIG FB wrapper +'' +'' NOTICE: This file is part of the FreeBASIC Compiler package and can't +'' be included in other distributions without authorization. +'' +'' +#ifndef __crt_linux_time_bi__ +#define __crt_linux_time_bi__ + +#include once "crt/long.bi" + +'' begin_include "bits/time.bi" + +#define CLOCKS_PER_SEC 1000000l + +extern "C" +declare function __sysconf (byval as long) as clong +end extern + +'' end_include "bits/time.bi" + +type clock_t as __clock_t +type time_t as __time_t + +type timespec + tv_sec as __time_t + tv_nsec as clong +end type + +type tm + tm_sec as long + tm_min as long + tm_hour as long + tm_mday as long + tm_mon as long + tm_year as long + tm_wday as long + tm_yday as long + tm_isdst as long + __tm_gmtoff as clong + __tm_zone as zstring ptr +end type + +extern "C" + +declare function gmtime_r (byval __timer as time_t ptr, byval __tp as tm ptr) as tm ptr +declare function localtime_r (byval __timer as time_t ptr, byval __tp as tm ptr) as tm ptr +declare function asctime_r (byval __tp as tm ptr, byval __buf as zstring ptr) as zstring ptr +declare function ctime_r (byval __timer as time_t ptr, byval __buf as zstring ptr) as zstring ptr + +extern __tzname as zstring * 2 +extern __daylight as long +extern __timezone as clong + +declare function timegm (byval __tp as tm ptr) as time_t +declare function timelocal (byval __tp as tm ptr) as time_t +declare function dysize (byval __year as long) as long + +end extern + +#endif diff --git a/inc/crt/freebsd/wchar.bi b/inc/crt/freebsd/wchar.bi new file mode 100644 index 0000000000..72fcacaa7e --- /dev/null +++ b/inc/crt/freebsd/wchar.bi @@ -0,0 +1,26 @@ +#pragma once + +#include once "crt/stdio.bi" +#include once "crt/stdarg.bi" +#include once "crt/stddef.bi" +#include once "crt/long.bi" +#include once "crt/stdint.bi" +#include once "crt/limits.bi" + +extern "C" + +type mbstate_t as __mbstate_t + +#ifndef wchar_t +type wchar_t as __wchar_t +#endif + +#ifndef wint_t +type wint_t as __wint_t +#endif + +#ifndef WEOF +const WEOF = cast(wint_t, -1) +#endif + +end extern diff --git a/inc/crt/linux/wchar.bi b/inc/crt/linux/wchar.bi index 7f6dbe6f9e..3d0110577e 100644 --- a/inc/crt/linux/wchar.bi +++ b/inc/crt/linux/wchar.bi @@ -31,7 +31,6 @@ end type extern "C" -declare function wmemcpy (byval __s1 as wchar_t ptr, byval __s2 as wchar_t ptr, byval __n as size_t) as wchar_t ptr declare function __mbrlen (byval __s as zstring ptr, byval __n as size_t, byval __ps as mbstate_t ptr) as size_t declare function __wcstod_internal (byval __nptr as wchar_t ptr, byval __endptr as wchar_t ptr ptr, byval __group as long) as double declare function __wcstof_internal (byval __nptr as wchar_t ptr, byval __endptr as wchar_t ptr ptr, byval __group as long) as single diff --git a/inc/crt/stddef.bi b/inc/crt/stddef.bi index 231a17c21a..8edddaf49b 100644 --- a/inc/crt/stddef.bi +++ b/inc/crt/stddef.bi @@ -23,6 +23,7 @@ type ptrdiff_t as integer #endif #endif +#ifndef wchar_t #ifdef __FB_DOS__ type wchar_t as ubyte #elseif defined( __FB_WIN32__ ) or defined( __FB_CYGWIN__ ) @@ -30,8 +31,11 @@ type ptrdiff_t as integer #else type wchar_t as long #endif +#endif -type wint_t as wchar_t +#ifndef wint_t + type wint_t as wchar_t +#endif #ifndef NULL #define NULL 0 diff --git a/inc/crt/stdio.bi b/inc/crt/stdio.bi index 0091d471b9..164cda5118 100644 --- a/inc/crt/stdio.bi +++ b/inc/crt/stdio.bi @@ -27,6 +27,15 @@ #include once "crt/dos/stdio.bi" #elseif defined(__FB_LINUX__) #include once "crt/linux/stdio.bi" +#elseif defined(__FB_FREEBSD__) +#include once "crt/freebsd/stdio.bi" +#elseif defined(__FB_UNIX__) +'' Other Unices are likely to be BSD variants. stdio.bi is the most important +'' crt header, so try to make FB work on other OSes. +#print WARNING: Platform not supported; falling back to FreeBSD stdio.bi header +#include once "crt/freebsd/stdio.bi" +#else +#error Unsupported platform #endif extern "c" diff --git a/inc/crt/stdlib.bi b/inc/crt/stdlib.bi index 708fd9f2e3..0bb162b6f4 100644 --- a/inc/crt/stdlib.bi +++ b/inc/crt/stdlib.bi @@ -14,8 +14,8 @@ #if defined(__FB_WIN32__) #include once "crt/win32/stdlib.bi" -#elseif defined(__FB_LINUX__) -#include once "crt/linux/stdlib.bi" +#elseif defined(__FB_UNIX__) +#include once "crt/unix/stdlib.bi" #endif type div_t diff --git a/inc/crt/sys/freebsd/types.bi b/inc/crt/sys/freebsd/types.bi new file mode 100644 index 0000000000..7923c0c961 --- /dev/null +++ b/inc/crt/sys/freebsd/types.bi @@ -0,0 +1,20 @@ +'' +'' +'' sys\types +'' +'' +'' +'' +'' +#ifndef __crt_sys_freebsd_types_bi__ +#define __crt_sys_freebsd_types_bi__ + +type __clock_t as integer +type __time_t as integer + +union __mstate_t + as ubyte __mbstate8(0 to 127) + as ulongint _mbstateL +end union + +#endif diff --git a/inc/crt/sys/types.bi b/inc/crt/sys/types.bi index 97efb94c2c..5f72c377db 100644 --- a/inc/crt/sys/types.bi +++ b/inc/crt/sys/types.bi @@ -17,6 +17,8 @@ #include once "crt/sys/dos/types.bi" #elseif defined(__FB_LINUX__) #include once "crt/sys/linux/types.bi" +#elseif defined(__FB_FREEBSD__) +#include once "crt/sys/freebsd/types.bi" #else #error Platform unsupported #endif diff --git a/inc/crt/time.bi b/inc/crt/time.bi index c4a74c8858..2a0b051ecb 100644 --- a/inc/crt/time.bi +++ b/inc/crt/time.bi @@ -18,6 +18,8 @@ #include once "crt/dos/time.bi" #elseif defined(__FB_LINUX__) #include once "crt/linux/time.bi" +#elseif defined(__FB_FREEBSD__) +#include once "crt/freebsd/time.bi" #endif extern "c" diff --git a/inc/crt/linux/stdlib.bi b/inc/crt/unix/stdlib.bi similarity index 75% rename from inc/crt/linux/stdlib.bi rename to inc/crt/unix/stdlib.bi index 6b68ccaa33..dcb46c7137 100644 --- a/inc/crt/linux/stdlib.bi +++ b/inc/crt/unix/stdlib.bi @@ -6,11 +6,11 @@ '' be included in other distributions without authorization. '' '' -#ifndef __crt_linux_stdlib_bi__ -#define __crt_linux_stdlib_bi__ +#ifndef __crt_unix_stdlib_bi__ +#define __crt_unix_stdlib_bi__ extern "c" declare function mkstemp (byval template_ as zstring ptr) as long end extern -#endif '' __crt_linux_stdlib_bi__ +#endif '' __crt_unix_stdlib_bi__ diff --git a/inc/crt/wchar.bi b/inc/crt/wchar.bi index a9b6bf36c2..073a849860 100644 --- a/inc/crt/wchar.bi +++ b/inc/crt/wchar.bi @@ -20,6 +20,8 @@ #include once "crt/win32/wchar.bi" #elseif defined(__FB_LINUX__) #include once "crt/linux/wchar.bi" +#elseif defined(__FB_FREEBSD__) +#include once "crt/freebsd/wchar.bi" #elseif defined(__FB_DOS__) #include once "crt/dos/wchar.bi" #endif @@ -38,6 +40,7 @@ declare function wmemset (byval s as wchar_t ptr, byval c as wchar_t, byval n as declare function wmemchr (byval s as const wchar_t ptr, byval c as wchar_t, byval n as size_t) as wchar_t ptr declare function wmemcmp (byval s1 as const wchar_t ptr, byval s2 as const wchar_t ptr, byval n as size_t) as integer declare function wmemmove (byval s1 as wchar_t ptr, byval s2 as const wchar_t ptr, byval n as size_t) as wchar_t ptr +declare function wmemcpy(byval as wchar_t ptr, byval as const wchar_t ptr, byval as uinteger) as wstring ptr end extern #endif diff --git a/src/compiler/emit_x86.bas b/src/compiler/emit_x86.bas index bba186ade6..c3ba40d294 100644 --- a/src/compiler/emit_x86.bas +++ b/src/compiler/emit_x86.bas @@ -7189,7 +7189,9 @@ private function _getSectionString _ ostr = NEWLINE - '' Omit the .section directive on Darwin + '' Omit the .section directive on Darwin. + '' as accepts .text, .const, and many others as shorthands, while .section has a different syntax: + '' .section segment , section [[[ , type ] , attribute] , sizeof_stub] if (fbGetOption( FB_COMPOPT_TARGET ) <> FB_COMPTARGET_DARWIN) then ostr += ".section " end if @@ -7221,27 +7223,42 @@ private function _getSectionString _ ostr += "text" case IR_SECTION_DIRECTIVE + '' TODO: there is no .drectve on Darwin ostr += "drectve" case IR_SECTION_INFO - ostr += FB_INFOSEC_NAME + if (fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN) then + ostr += "section __DATA," + FB_INFOSEC_NAME + else + ostr += FB_INFOSEC_NAME + end if case IR_SECTION_CONSTRUCTOR - ostr += "ctors" - if( priority > 0 ) then - ostr += "." + right( "00000" + str( 65535 - priority ), 5 ) - end if - if( env.clopt.target = FB_COMPTARGET_LINUX ) then - ostr += ", " + QUOTE + "aw" + QUOTE + ", @progbits" + if (fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN) then + '' Darwin assembler does not support ctor priorities + ostr += "constructor" + else + ostr += "ctors" + if( priority > 0 ) then + ostr += "." + right( "00000" + str( 65535 - priority ), 5 ) + end if + if( env.clopt.target = FB_COMPTARGET_LINUX ) then + ostr += ", " + QUOTE + "aw" + QUOTE + ", @progbits" + end if end if case IR_SECTION_DESTRUCTOR - ostr += "dtors" - if( priority > 0 ) then - ostr += "." + right( "00000" + str( 65535 - priority ), 5 ) - end if - if( env.clopt.target = FB_COMPTARGET_LINUX ) then - ostr += ", " + QUOTE + "aw" + QUOTE + ", @progbits" + if (fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN) then + '' Darwin assembler does not support dtor priorities + ostr += "destructor" + else + ostr += "dtors" + if( priority > 0 ) then + ostr += "." + right( "00000" + str( 65535 - priority ), 5 ) + end if + if( env.clopt.target = FB_COMPTARGET_LINUX ) then + ostr += ", " + QUOTE + "aw" + QUOTE + ", @progbits" + end if end if end select diff --git a/src/compiler/fb.bas b/src/compiler/fb.bas index 6ec6502d71..58b3635ea0 100644 --- a/src/compiler/fb.bas +++ b/src/compiler/fb.bas @@ -368,7 +368,7 @@ function fbGetBackendName _ end function -sub fbInit( byval ismain as integer, byval restarts as integer ) +sub fbInit( byval ismain as integer, byval restarts as integer, byval entry as zstring ptr ) strsetInit( @env.libs, FB_INITLIBNODES \ 4 ) strsetInit( @env.libpaths, FB_INITLIBNODES \ 4 ) @@ -379,6 +379,7 @@ sub fbInit( byval ismain as integer, byval restarts as integer ) env.includerec = 0 env.main.proc = NULL + env.entry = *entry env.opt.explicit = (env.clopt.lang = FB_LANG_FB) @@ -432,7 +433,7 @@ sub fbInit( byval ismain as integer, byval restarts as integer ) '' Yes for dos/cygwin-x86/win32/xbox, but not win64/cygwin-x86_64/linux-*/etc. env.underscoreprefix = FALSE select case( env.clopt.target ) - case FB_COMPTARGET_DOS, FB_COMPTARGET_XBOX + case FB_COMPTARGET_DOS, FB_COMPTARGET_XBOX, FB_COMPTARGET_DARWIN env.underscoreprefix = TRUE case FB_COMPTARGET_CYGWIN, FB_COMPTARGET_WIN32 env.underscoreprefix = not fbIs64bit( ) @@ -976,10 +977,18 @@ function fbTargetSupportsCOFF( ) as integer return ((env.target.options and FB_TARGETOPT_COFF) <> 0) end function +function fbTargetSupportsMachO( ) as integer + return ((env.target.options and FB_TARGETOPT_MACHO) <> 0) +end function ''::::: function fbGetEntryPoint( ) as string static + '' If overridden with -entry + if( len(env.entry) ) then + return env.entry + end if + '' All targets use main(), except for xbox... if (env.clopt.target = FB_COMPTARGET_XBOX) then function = "XBoxStartup" diff --git a/src/compiler/fb.bi b/src/compiler/fb.bi index c75ef16f06..2e28ce4449 100644 --- a/src/compiler/fb.bi +++ b/src/compiler/fb.bi @@ -423,7 +423,7 @@ const FB_INFOSEC_OBJNAME = "__fb_ct.inf" #include once "error.bi" -declare sub fbInit(byval ismain as integer, byval restarts as integer) +declare sub fbInit(byval ismain as integer, byval restarts as integer, byval entry as zstring ptr) declare sub fbEnd() declare sub fbCompile _ @@ -466,6 +466,7 @@ declare function fbGetCpuFamily( ) as integer declare function fbIdentifyFbcArch( byref fbcarch as string ) as integer declare function fbTargetSupportsELF( ) as integer declare function fbTargetSupportsCOFF( ) as integer +declare function fbTargetSupportsMachO( ) as integer declare function fbGetEntryPoint _ ( _ diff --git a/src/compiler/fbc.bas b/src/compiler/fbc.bas index ed21d7b7a1..4fb97c108c 100644 --- a/src/compiler/fbc.bas +++ b/src/compiler/fbc.bas @@ -90,6 +90,7 @@ type FBCCTX outname as zstring * FB_MAXPATHLEN+1 mainname as zstring * FB_MAXPATHLEN+1 + entry as zstring * FB_MAXNAMELEN+1 mainset as integer mapfile as zstring * FB_MAXPATHLEN+1 subsystem as zstring * FB_MAXNAMELEN+1 @@ -261,6 +262,34 @@ private function hGet1stOutputLineFromCommand( byref cmd as string ) as string return ln end function +'' Pass some arguments to gcc and read the results. Returns an empty string on +'' an error. +function fbcQueryGcc( byref options as string ) as string + dim as string path + fbcFindBin( FBCTOOL_GCC, path ) + + select case( fbGetCpuFamily( ) ) + case FB_CPUFAMILY_X86 + path += " -m32" + case FB_CPUFAMILY_X86_64 + path += " -m64" + end select + + path += options + + dim as integer ff = freefile( ) + if( open pipe( path, for input, as ff ) <> 0 ) then + exit function + end if + + dim ret as string + input #ff, ret + + close ff + + return ret +end function + '' '' Build the path to a certain file in our lib/ directory (or, in case of '' non-standalone, somewhere in a system directory such as /usr/lib). @@ -376,8 +405,19 @@ private sub fbcFindBin _ path = fbc.binpath + toolnames(tool) + FB_HOST_EXEEXT #ifndef ENABLE_STANDALONE + if( (hFileExists( path ) = FALSE) and _ + (fbGetOption( FB_COMPOPT_BACKEND ) = FB_BACKEND_GCC)) then + '' c) Ask GCC where it is, if applicable (GCC might have its + '' own copy which we must use instead of the system one) + if( tool = FBCTOOL_AS ) then + path = fbcQueryGcc( " -print-prog-name=as" ) + elseif( tool = FBCTOOL_LD ) then + path = fbcQueryGcc( " -print-prog-name=ld" ) + end if + end if + if( hFileExists( path ) = FALSE ) then - '' c) Rely on PATH + '' d) Rely on PATH if( fbGetOption( FB_COMPOPT_TARGET ) <> FB_COMPTARGET_JS ) then path = fbc.targetprefix + toolnames(tool) + FB_HOST_EXEEXT else @@ -623,6 +663,16 @@ private function hLinkFiles( ) as integer case FB_CPUFAMILY_ARM ldcline += "-m armelf_linux_eabi " end select + case FB_COMPTARGET_DARWIN + select case( fbGetCpuFamily( ) ) + case FB_CPUFAMILY_X86 + ldcline += "-arch i386 " + case FB_CPUFAMILY_X86_64 + ldcline += "-arch x86_64 " + case FB_CPUFAMILY_ARM + '' fixme: this is clearly too specific + ldcline += "-arch armv6 " + end select end select '' Set executable name @@ -1013,7 +1063,7 @@ private function hLinkFiles( ) as integer end select if( fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN ) then - ldcline += " -macosx_version_min 10.6" + ldcline += " -macosx_version_min 10.4" end if '' extra options @@ -1500,6 +1550,7 @@ enum OPT_EDEBUGINFO OPT_ELOCATION OPT_ENULLPTR + OPT_ENTRY OPT_EX OPT_EXX OPT_EXPORT @@ -1571,6 +1622,7 @@ dim shared as integer option_takes_argument(0 to (OPT__COUNT - 1)) = _ FALSE, _ '' OPT_EDEBUGINFO FALSE, _ '' OPT_ELOCATION FALSE, _ '' OPT_ENULLPTR + TRUE, _ '' OPT_ENTRY FALSE, _ '' OPT_EX FALSE, _ '' OPT_EXX FALSE, _ '' OPT_EXPORT @@ -1684,6 +1736,9 @@ private sub handleOpt(byval optid as integer, byref arg as string) case OPT_ENULLPTR fbSetOption( FB_COMPOPT_NULLPTRCHECK, TRUE ) + case OPT_ENTRY + fbc.entry = arg + case OPT_EX fbSetOption( FB_COMPOPT_ERRORCHECK, TRUE ) fbSetOption( FB_COMPOPT_RESUMEERROR, TRUE ) @@ -2088,6 +2143,7 @@ private function parseOption(byval opt as zstring ptr) as integer CHECK("edebuginfo", OPT_EDEBUGINFO) CHECK("elocation", OPT_ELOCATION) CHECK("enullptr", OPT_ENULLPTR) + CHECK("entry", OPT_ENTRY) CHECK("exx", OPT_EXX) CHECK("export", OPT_EXPORT) @@ -2435,7 +2491,11 @@ private sub hParseArgs( byval argc as integer, byval argv as zstring ptr ptr ) '' or cross-compiling. Even on a 64bit x86_64 host where '' FB_DEFAULT_BACKEND is -gen gcc, we still prefer using -gen gas when '' cross-compiling to 32bit x86. - if( fbGetCpuFamily( ) = FB_CPUFAMILY_X86 ) then + '' (Apple gas assembler has such broken support for intel syntax + '' (see https://discussions.apple.com/message/10163960#10163960) + '' that it can't work for non-trivial programs, so default to -gen gcc.) + if( (fbGetCpuFamily( ) = FB_CPUFAMILY_X86) and _ + (fbGetOption(FB_COMPOPT_TARGET) <> FB_COMPTARGET_DARWIN) ) then fbSetOption( FB_COMPOPT_BACKEND, FB_BACKEND_GAS ) else fbSetOption( FB_COMPOPT_BACKEND, FB_BACKEND_GCC ) @@ -2481,6 +2541,14 @@ private sub hParseArgs( byval argc as integer, byval argv as zstring ptr ptr ) end if end select + '' On darwin need to change the default asm syntax when using gen gcc because + '' most C compilers on OSX seem to be configured without intel syntax support; + '' probably because Apple as and llvm-mc have horribly broken intel support. + if( (fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN) and _ + (fbGetOption( FB_COMPOPT_BACKEND ) <> FB_BACKEND_GAS) ) then + fbSetOption( FB_COMPOPT_ASMSYNTAX, FB_ASMSYNTAX_ATT ) + end if + if( fbc.asmsyntax >= 0 ) then '' -asm only applies to x86 and x86_64 select case( fbGetCpuFamily( ) ) @@ -2754,7 +2822,7 @@ private sub hCompileBas _ do '' init the parser - fbInit( is_main, restarts ) + fbInit( is_main, restarts, fbc.entry ) if( is_fbctinf ) then '' Let the compiler know about all libs collected so far, @@ -3021,9 +3089,14 @@ private function hCompileStage2Module( byval module as FBCIOFILE ptr ) as intege end if if( fbGetOption( FB_COMPOPT_TARGET ) <> FB_COMPTARGET_JS ) then - ln += "-S -nostdlib -nostdinc -Wall -Wno-unused-label " + _ - "-Wno-unused-function -Wno-unused-variable " - ln += "-Wno-unused-but-set-variable " + ln += "-S -nostdlib -nostdinc -Wall " + + '' -Wno-unused-but-set-variable and the warning it suppresses were introduced + '' in GCC 4.6. Don't pass that flag to avoid an error on earlier GCC. As a + '' result, to disable the warning on 4.6+ need to disable all unused warnings... + ' ln += "-Wno-unused-label -Wno-unused-function -Wno-unused-variable " + ' ln += "-Wno-unused-but-set-variable " + ln += "-Wno-unused " else 'if Emscripten is used, we will skip the assembly generation and compile directly to object code ln += "-c -nostdlib -nostdinc -Wall -Wno-unused-label " + _ @@ -3102,7 +3175,7 @@ private function hCompileStage2Module( byval module as FBCIOFILE ptr ) as intege '' -march=name '' Specify the name of the target architecture and, '' optionally, one or more feature modifiers. This option - '' has the form ‘-march=arch{+[no]feature}*’. + '' has the form ‘-march=arch{+[no]feature}*’. '' '' The permissible values for arch are '' 'armv8-a' @@ -3636,6 +3709,7 @@ private sub hPrintOptions( byval verbose as integer ) print " -enullptr Enable null-pointer checking" end if + print " -entry Change the entry point of the program from main()" print " -ex -e plus RESUME support" print " -exx -ex plus array bounds/null-pointer checking" print " -export Export symbols for dynamic linkage" diff --git a/src/compiler/fbint.bi b/src/compiler/fbint.bi index 9f44d725bd..a8d07f59e5 100644 --- a/src/compiler/fbint.bi +++ b/src/compiler/fbint.bi @@ -629,6 +629,7 @@ type FBENV inconcehash as THASH '' A subset of filenamehash includerec as integer '' >0 if parsing an include file + entry as zstring * FB_MAXNAMELEN '' name of main function if overridden main as FBMAIN lang as FB_LANG_CTX '' language supported features diff --git a/src/compiler/ir-hlc.bas b/src/compiler/ir-hlc.bas index 1e07340d36..47b19319f1 100644 --- a/src/compiler/ir-hlc.bas +++ b/src/compiler/ir-hlc.bas @@ -3824,7 +3824,12 @@ private sub _emitFbctinfBegin( ) '' section attribute - This global must be put into a custom .fbctinf '' section, as done by the ASM backend. ctx.fbctinf = "static const char " - ctx.fbctinf += "__attribute__((used, section(""." + FB_INFOSEC_NAME + """))) " + if (fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN) then + '' Must specify a segment name (can use any name) + ctx.fbctinf += "__attribute__((used, section(""__DATA," + FB_INFOSEC_NAME + """))) " + else + ctx.fbctinf += "__attribute__((used, section(""." + FB_INFOSEC_NAME + """))) " + end if ctx.fbctinf += "__fbctinf[] = """ end sub diff --git a/src/compiler/ir-llvm.bas b/src/compiler/ir-llvm.bas index d8e20a25ba..254b510c35 100644 --- a/src/compiler/ir-llvm.bas +++ b/src/compiler/ir-llvm.bas @@ -2368,7 +2368,12 @@ private sub _emitFbctinfEnd( ) ln = "@__fbctinf = internal constant " ln += hEmitStrLitType( ctx.fbctinf_len ) ln += " c""" + ctx.fbctinf + """" - ln += ", section ""." + FB_INFOSEC_NAME + """" + if (fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_DARWIN) then + '' Must specify a segment name (can use any name) + ln += ", section ""__DATA," + FB_INFOSEC_NAME + """" + else + ln += ", section ""." + FB_INFOSEC_NAME + """" + end if hWriteLine( ln ) '' Append to the special llvm.used symbol to ensure it won't be diff --git a/src/compiler/objinfo.bas b/src/compiler/objinfo.bas index acc10c4900..c1108ee9aa 100644 --- a/src/compiler/objinfo.bas +++ b/src/compiler/objinfo.bas @@ -73,6 +73,10 @@ '' reads in a lib*.a archive file, '' looks for the fbctinf object file added to static libraries by fbc -lib, '' and if found, calls hLoadFbctinfFromObj(). +'' Note that Darwin has two different types of static libraries, both with +'' extension .a: normal 'ar' archives, and 'lipo' fat/universal binaries. +'' fbc creates ar archives, and it seems to generally be the default. +'' We only support reading 'ar' archives. '' '' objinfoReadLib(): '' searches a libfile for the given libname in the given libpaths, @@ -80,7 +84,8 @@ '' '' hLoadFbctinfFromObj(): '' reads the currently loaded object file, -'' using either the COFF (Win32, DOS) or ELF32 (Linux, *BSD) format. +'' using either the COFF (Win32, DOS), ELF32/64 (Linux, *BSD) or +'' Mach-O (Darwin) format. '' ELF32 (linux-arm) or ELF64 (linux-aarch64) '' looks for the .fbctinf section, '' and if found, parses its content, and tells the frontend about the @@ -166,8 +171,18 @@ end type dim shared as ubyte elfmagic(0 to 15) = _ { _ - &h7f, &h45, &h4c, &h46, 0, &h01, _ '' index 4 is set to 1 (32bit) or 2 (64bit) - &h01, &h00, &h00, &h00, &h00, &h00 _ '' index 12 is set to machine + &h7f, _ '' '.' + &h45, _ '' 'E' + &h4c, _ '' 'L' + &h46, _ '' 'F' + &h00, _ '' 1 (32bit) or 2 (64bit) + &h01, _ '' 1 (little endian) or 2 (big endian) + &h01, _ '' 1 - the one and only version of ELF + &h00, _ '' target ABI + &h00, _ '' ABI version + &h00, _ '' unused 0 + &h00, _ '' object file type + &h00 _ '' target machine } const ET_REL = 1 @@ -210,6 +225,10 @@ end type #macro ELFLOADINGCODE(ELF_H, ELF_SH, ELF_MAGIC_4) +'' ELF_H - elf main header (ELF32_H or ELF64_H) +'' ELF_SH - typename of the section header type (ELF32_SH or ELF64_SH) +'' ELF_MAGIC_4 - 1 for 32 bit, 2 for 64-bit + private function hCheck##ELF_SH _ ( _ byval h as ELF_H ptr, _ @@ -289,7 +308,17 @@ private sub hLoadFbctinfFrom##ELF_H( byval ELF_MACHINE as integer ) h = cptr( any ptr, objdata.p ) + '' set 32 or 64 bits elfmagic(4) = ELF_MAGIC_4 + + '' set the target system expected + if( fbGetOption( FB_COMPOPT_TARGET ) = FB_COMPTARGET_FREEBSD ) then + elfmagic(7) = &h09 '' FreeBSD + else + elfmagic(7) = 0 '' System V + end if + + '' check that magic given is the magic needed for i as integer = 0 to 15 if( h->e_ident(i) <> elfmagic(i) ) then INFO( "elf: magic mismatch" ) @@ -462,6 +491,214 @@ private sub hLoadFbctinfFromCOFF( byval magic as ushort ) next end sub + +'' Mach-O implementation + +'' All of these structures are defined in /usr/include/mach-o/loader.h + +'' mach_header and mach_header_64 are identical aside from addition of +'' a reserved member at the end, and different magic constant. +type MACH_H + magic as ulong + cputype as ulong ' cpu_type_t + cpusubtype as ulong ' cpu_subtype_t + filetype as ulong + ncmds as ulong + sizeofcmds as ulong + flags as ulong +end type + +'' Mach-O load command header +type LOAD_COMMAND_H + cmd as ulong + cmdsize as ulong +end type + +'' cpu_type_t constants +const MACH_CPU_ARCH_ABI64 = &h01000000 +const MACH_CPU_TYPE_X86 = 7 +const MACH_CPU_TYPE_X86_64 = (MACH_CPU_TYPE_X86 or MACH_CPU_ARCH_ABI64) +const MACH_CPU_TYPE_ARM = 12 +const MACH_CPU_TYPE_ARM64 = (MACH_CPU_TYPE_ARM or MACH_CPU_ARCH_ABI64) +const MACH_CPU_TYPE_POWERPC = 18 +const MACH_CPU_TYPE_POWERPC64 = (MACH_CPU_TYPE_POWERPC or MACH_CPU_ARCH_ABI64) + +const MH_MAGIC_32 = &hfeedface +const MH_MAGIC_64 = &hfeedfacf + +const MH_OBJECT = 1 ' MH_OBJECT + +const LC_SEGMENT = &h1 +const LC_SEGMENT_64 = &h19 + +#macro DEFINE_SEGMENT_COMMAND(NAME, SIZE_TYPE) +type NAME + cmd as ulong + cmdsize as ulong + segname(15) as ubyte + vmaddr as SIZE_TYPE + vmsize as SIZE_TYPE + fileoff as SIZE_TYPE + filesize as SIZE_TYPE + maxprot as ulong 'vm_prot_t + initprot as ulong 'vm_prot_t + nsects as ulong + flags as ulong +end type +#endmacro + +DEFINE_SEGMENT_COMMAND(SEGMENT_COMMAND_32, ulong) 'struct segment_command +DEFINE_SEGMENT_COMMAND(SEGMENT_COMMAND_64, ulongint) 'struct segment_command_64 + +#macro DEFINE_SECTION(NAME, SIZE_TYPE, RESERVED3) +'' Defined in /usr/include/mach-o/loader.h +type NAME + sectname as zstring * 16 + segname as zstring * 16 + addr as SIZE_TYPE + size as SIZE_TYPE + offset as ulong + align as ulong + reloff as ulong + nreloc as ulong + flags as ulong + reserved1 as ulong + reserved2 as ulong + RESERVED3 +end type +#endmacro + +DEFINE_SECTION(SECTION_32, ulong, ) 'struct section +DEFINE_SECTION(SECTION_64, ulongint, reserved3 as ulong) 'struct section_64 + + +#macro MACHO_SECTION_CODE(BITS) + +'' Iterate over the sections of a segment load command. Returns non-zero on error. +private function hProcessMachOSegment##BITS( byval loadcmd as LOAD_COMMAND_H ptr ) as integer + dim segmentp as SEGMENT_COMMAND_##BITS ptr + dim sectionp as SECTION_##BITS ptr + + segmentp = cptr( SEGMENT_COMMAND_##BITS ptr, loadcmd ) + if( segmentp + 1 > objdata.p + objdata.size ) then + INFO( "mach-o: segment load_command past end of file" ) + return 1 + end if + + '' Section headers follow immediately after the segment header + sectionp = cptr( SECTION_##BITS ptr, segmentp + 1 ) + for sectionidx as integer = 0 to segmentp->nsects - 1 + if( sectionp + 1 > objdata.p + objdata.size ) then + INFO( "mach-o: section header past end of file" ) + return 1 + end if + + INFO( "mach-o: found segment=" & sectionp->segname & " section=" & sectionp->sectname ) + if( sectionp->sectname = FB_INFOSEC_NAME ) then + if( sectionp->offset + sectionp->size > objdata.size ) then + INFO( "mach-o: fbctinf section data past end of file" ) + return 1 + end if + + fbctinf.p = objdata.p + sectionp->offset + fbctinf.size = sectionp->size + exit for + end if + + sectionp += 1 + next +end function + +#endmacro + +MACHO_SECTION_CODE(32) +MACHO_SECTION_CODE(64) + +private sub hLoadFbctinfFromMachO( ) + dim header as MACH_H ptr = any + dim loadcmd as LOAD_COMMAND_H ptr = any + dim dataptr as ubyte ptr = any + + fbctinf.p = NULL + fbctinf.size = 0 + + if( objdata.size < sizeof( MACH_H ) ) then + INFO( "mach-o: no room for header" ) + exit sub + end if + + header = cptr( any ptr, objdata.p ) + + '' Check magic + if( header->magic <> MH_MAGIC_32 and header->magic <> MH_MAGIC_64 ) then + INFO( "mach-o: magic constant mismatch" ) + exit sub + end if + + '' Check cpu type matches + select case( fbGetCpuFamily( ) ) + case FB_CPUFAMILY_X86 + if( header->cputype <> MACH_CPU_TYPE_X86 ) then + INFO( "mach-o: CPU type is not x86" ) + exit sub + end if + case FB_CPUFAMILY_X86_64 + if( header->cputype <> MACH_CPU_TYPE_X86_64 ) then + INFO( "mach-o: CPU type is not x86_64" ) + exit sub + end if + case FB_CPUFAMILY_ARM + if( header->cputype <> MACH_CPU_TYPE_ARM ) then + INFO( "mach-o: CPU type is not 32bit ARM" ) + exit sub + end if + case FB_CPUFAMILY_AARCH64 + if( header->cputype <> MACH_CPU_TYPE_ARM64 ) then + INFO( "mach-o: CPU type is not ARM64" ) + exit sub + end if + end select + + '' Check file type + if( header->filetype <> MH_OBJECT ) then + INFO( "mach-o: Not an object file" ) + exit sub + end if + + '' 64 bit mach-o files have 4 bytes padding after header so load commands are 8-byte aligned + dataptr = objdata.p + sizeof( MACH_H ) + if( header->magic = MH_MAGIC_64 ) then + dataptr += 4 + end if + + '' Iterate over load commands. Note: 'segment' load commands are not the same + '' thing as the memory segments the sections belong to. Instead, to reduce space overhead + '' of .o files, all sections are stored under a single segment load command regardless of + '' their actual segment. + for cmdidx as integer = 0 to header->ncmds - 1 + loadcmd = cptr( LOAD_COMMAND_H ptr, dataptr ) + + if( loadcmd + 1 > objdata.p + objdata.size ) then + INFO( "mach-o: load_command past end of file" ) + exit sub + end if + + INFO( "mach-o: load command " & loadcmd->cmd ) + if( loadcmd->cmd = LC_SEGMENT ) then + if( hProcessMachOSegment32( loadcmd ) ) then + exit sub + end if + elseif( loadcmd->cmd = LC_SEGMENT_64 ) then + if( hProcessMachOSegment64( loadcmd ) ) then + exit sub + end if + end if + + dataptr += loadcmd->cmdsize + next +end sub + + '' .a archive entry header type AR_H field = 1 '' (all values right-padded with ASCII spaces) @@ -639,6 +876,9 @@ private sub hLoadFbctinfFromObj( ) INFO( "reading arm32 ELF: " + parser.filename ) hLoadFbctinfFromELF32_H( EM_ARM32 ) end select + elseif( fbTargetSupportsMachO( ) ) then + INFO( "reading Mach-O: " + parser.filename ) + hLoadFbctinfFromMachO( ) end if if( fbctinf.size = 0 ) then diff --git a/src/compiler/symb-mangling.bas b/src/compiler/symb-mangling.bas index a6b38dce49..c45fa547b5 100644 --- a/src/compiler/symb-mangling.bas +++ b/src/compiler/symb-mangling.bas @@ -82,7 +82,11 @@ function symbUniqueLabel( ) as zstring ptr ctx.tempstr += str( ctx.uniquelabelcount ) ctx.uniquelabelcount += 1 else - ctx.tempstr = ".Lt_" + if( env.clopt.target = FB_COMPTARGET_DARWIN ) then + ctx.tempstr = "L_" + else + ctx.tempstr = ".L_" + end if ctx.tempstr += *hHexUInt( ctx.uniqueidcount ) ctx.uniqueidcount += 1 end if diff --git a/src/gfxlib2/x86/fb_gfx_mmx.h b/src/gfxlib2/x86/fb_gfx_mmx.h index c7ea11d666..db68b17771 100644 --- a/src/gfxlib2/x86/fb_gfx_mmx.h +++ b/src/gfxlib2/x86/fb_gfx_mmx.h @@ -5,7 +5,7 @@ #include "../../rtlib/fb_config.h" -#if defined(HOST_WIN32) || defined(HOST_DOS) || defined(HOST_XBOX) +#if defined(HOST_WIN32) || defined(HOST_DOS) || defined(HOST_XBOX) || defined(HOST_DARWIN) #define GLOBL(name) _##name #else #define GLOBL(name) name diff --git a/src/rtlib/darwin/io_mouse.c b/src/rtlib/darwin/io_mouse.c new file mode 100644 index 0000000000..7884422e3a --- /dev/null +++ b/src/rtlib/darwin/io_mouse.c @@ -0,0 +1,13 @@ +/* console mode mouse functions */ + +#include "../fb.h" + +int fb_ConsoleGetMouse( int *x, int *y, int *z, int *buttons, int *clip ) +{ + return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); +} + +int fb_ConsoleSetMouse( int x, int y, int cursor, int clip ) +{ + return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); +} diff --git a/src/rtlib/darwin/io_multikey.c b/src/rtlib/darwin/io_multikey.c new file mode 100644 index 0000000000..1951c9b38b --- /dev/null +++ b/src/rtlib/darwin/io_multikey.c @@ -0,0 +1,9 @@ +/* console multikey() */ + +#include "../fb.h" + +int fb_ConsoleMultikey( int scancode ) +{ + fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); + return FB_FALSE; +} diff --git a/src/rtlib/darwin/io_serial.c b/src/rtlib/darwin/io_serial.c new file mode 100644 index 0000000000..670f62196d --- /dev/null +++ b/src/rtlib/darwin/io_serial.c @@ -0,0 +1,35 @@ +/* serial port access stubs */ + +#include "../fb.h" + +int fb_SerialOpen + ( + FB_FILE *handle, + int iPort, + FB_SERIAL_OPTIONS *options, + const char *pszDevice, + void **ppvHandle + ) +{ + return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); +} + +int fb_SerialGetRemaining( FB_FILE *handle, void *pvHandle, fb_off_t *pLength ) +{ + return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); +} + +int fb_SerialWrite( FB_FILE *handle, void *pvHandle, const void *data, size_t length ) +{ + return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); +} + +int fb_SerialRead( FB_FILE *handle, void *pvHandle, void *data, size_t *pLength ) +{ + return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); +} + +int fb_SerialClose( FB_FILE *handle, void *pvHandle ) +{ + return fb_ErrorSetNum( FB_RTERROR_ILLEGALFUNCTIONCALL ); +} diff --git a/src/rtlib/darwin/sys_fmem.c b/src/rtlib/darwin/sys_fmem.c new file mode 100644 index 0000000000..63fc080445 --- /dev/null +++ b/src/rtlib/darwin/sys_fmem.c @@ -0,0 +1,15 @@ +/* fre() function */ + +#include "../fb.h" +#include +#include +#include + +FBCALL size_t fb_GetMemAvail( int mode ) +{ + vm_statistics_data_t vmstat; + mach_msg_type_number_t count = HOST_VM_INFO_COUNT; + if( host_statistics( mach_host_self(), HOST_VM_INFO, (host_info_t) &vmstat, &count) != KERN_SUCCESS ) + return 0; + return vmstat.free_count * getpagesize(); +} diff --git a/src/rtlib/fb_private_thread.h b/src/rtlib/fb_private_thread.h index 846ee76a95..73a5b2c7df 100644 --- a/src/rtlib/fb_private_thread.h +++ b/src/rtlib/fb_private_thread.h @@ -15,6 +15,22 @@ }; #endif +/* Solaris pthread.h does not define PTHREAD_STACK_MIN */ +#ifndef PTHREAD_STACK_MIN + #define PTHREAD_STACK_MIN 8192 +#endif + +/* phtreads will crash freebsd when stack size is too small +// The default of 2048 KiB is too small.as tested on freebsd-13.0-i386 +// 8192 KiB seems about alright (jeffm) +// see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=234775 +*/ +#ifdef HOST_FREEBSD + #define FBTHREAD_STACK_MIN 8192 +#else + #define FBTHREAD_STACK_MIN PTHREAD_STACK_MIN +#endif + /* Thread handle returned by threadcreate(), so the caller is able to track the thread (freed by threadwait/threaddetach). diff --git a/src/rtlib/thread_self.c b/src/rtlib/thread_self.c index 3d169c7d9b..cc6f754134 100644 --- a/src/rtlib/thread_self.c +++ b/src/rtlib/thread_self.c @@ -60,10 +60,16 @@ void fb_CloseAtomicFBThreadFlagMutex( void ) fb_MutexDestroy( g_threadFlagMutex ); #endif } +#endif +/* +** even if this is not the multithreaded version of the rtlib +** define fbAtomicSetThreadFlags() anyway as it will be called +** from thread_core.c:threadproc() +*/ FBTHREADFLAGS fb_AtomicSetThreadFlags( volatile FBTHREADFLAGS *threadFlags, FBTHREADFLAGS newFlag ) { - +#ifdef ENABLE_MT #ifdef NEEDS_MUTEX FBTHREADFLAGS before; @@ -83,6 +89,11 @@ FBTHREADFLAGS fb_AtomicSetThreadFlags( volatile FBTHREADFLAGS *threadFlags, FBTH #endif /* NEEDS_MUTEX */ -} +#else /* !define(ENABLE_MT) */ + FBTHREADFLAGS before; + before = *threadFlags; + *threadFlags |= newFlag; + return before; #endif /* ENABLE_MT */ +} diff --git a/src/rtlib/unix/sys_dylib.c b/src/rtlib/unix/sys_dylib.c index 954d63b01e..fc247a9ba1 100644 --- a/src/rtlib/unix/sys_dylib.c +++ b/src/rtlib/unix/sys_dylib.c @@ -9,11 +9,18 @@ FBCALL void *fb_DylibLoad( FBSTRING *library ) void *res = NULL; int i; char libname[MAX_PATH]; + // Sometimes you will see .so files on Darwin too char *libnameformat[] = { "%s", "lib%s", +#ifdef HOST_DARWIN + "lib%s.dylib", +#endif "lib%s.so", "./%s", "./lib%s", +#ifdef HOST_DARWIN + "./lib%s.dylib", +#endif "./lib%s.so", NULL }; diff --git a/src/rtlib/unix/thread_core.c b/src/rtlib/unix/thread_core.c index 0cdd466794..49a27cba21 100644 --- a/src/rtlib/unix/thread_core.c +++ b/src/rtlib/unix/thread_core.c @@ -57,10 +57,8 @@ FBCALL FBTHREAD *fb_ThreadCreate( FB_THREADPROC proc, void *param, ssize_t stack return NULL; } - /* Solaris pthread.h does not define PTHREAD_STACK_MIN */ -#ifdef PTHREAD_STACK_MIN - stack_size = stack_size >= PTHREAD_STACK_MIN ? stack_size : PTHREAD_STACK_MIN; -#endif + /* see fb_private_thread.h for defintion of FBTHREAD_STACK_MIN */ + stack_size = stack_size >= FBTHREAD_STACK_MIN ? stack_size : FBTHREAD_STACK_MIN; pthread_attr_setstacksize( &tattr, stack_size ); diff --git a/src/rtlib/x86/cpudetect.s b/src/rtlib/x86/cpudetect.s index d01bb17779..89900d6d53 100644 --- a/src/rtlib/x86/cpudetect.s +++ b/src/rtlib/x86/cpudetect.s @@ -11,7 +11,7 @@ detected_cpu: .long 0 /* bits 0-27: low 24 bits of feature flags (CPUID eax = .text /* unsigned int fb_CpuDetect(void); */ -#if defined HOST_DOS || defined HOST_WIN32 || defined HOST_XBOX +#if defined HOST_DOS || defined HOST_WIN32 || defined HOST_XBOX || defined HOST_DARWIN .globl _fb_CpuDetect _fb_CpuDetect: #else diff --git a/tests/fbcunit/makefile b/tests/fbcunit/makefile index cec8a815e8..c2e14a8059 100644 --- a/tests/fbcunit/makefile +++ b/tests/fbcunit/makefile @@ -7,8 +7,9 @@ SRCS := src/fbcunit.bas SRCS += src/fbcunit_qb.bas SRCS += src/fbcunit_console.bas SRCS += src/fbcunit_report.bas + HDRS := inc/fbcunit.bi -HDRS := src/fbcunit_types.bi +HDRS += src/fbcunit_types.bi HDRS += src/fbcunit_console.bi HDRS += src/fbcunit_report.bi diff --git a/tests/functions/va_cva_api.bas b/tests/functions/va_cva_api.bas index 8d2ee565e9..136e90e604 100644 --- a/tests/functions/va_cva_api.bas +++ b/tests/functions/va_cva_api.bas @@ -397,7 +397,7 @@ SUITE( fbc_tests.functions.va_cva_api ) complex_tests( 1234, 4, 1000, 200, 30, 4 ) END_TEST -#if defined(__FB_LINUX__) and defined(__FB_64BIT__) +#if defined(__FB_UNIX__) and defined(__FB_64BIT__) '' Returning an array not allowed in gcc and some '' tests will fail to compile in gcc on linux x86_64. '' To handle returning a byval cva_list, would need to diff --git a/tests/log-tests.mk b/tests/log-tests.mk index 68428b2c9c..4d65363676 100644 --- a/tests/log-tests.mk +++ b/tests/log-tests.mk @@ -289,7 +289,7 @@ $(FAILED_LOG_TESTS_INC) : @$(ECHO) "#" >> $(FAILED_LOG_TESTS_INC) @$(PRINTF) "." - @$(FIND) $(DIRLIST) -type f -name '*.log' \ + @$(FIND) $(DIRLIST) -type f -name -mindepth 1 '*.log' -mindepth 1 \ | $(XARGS) $(GREP) -l -i -E '^.*[[:space:]]*:[[:space:]]*RESULT=FAILED' \ | $(SED) -e 's/\(^.*\)[[:space:]]\:[[:space:]]TESTMODE=\(.*\)/SRCLIST_\2 \+\= \1/g' \ >> $(FAILED_LOG_TESTS_INC) @@ -307,42 +307,42 @@ $(LOG_TESTS_INC) : @$(ECHO) "#" >> $(LOG_TESTS_INC) @$(PRINTF) "." - @$(FIND) $(DIRLIST) -type f -name '*.bas' -or -name '*.bmk' \ + @$(FIND) $(DIRLIST) -type f -name '*.bas' -or -name '*.bmk' -mindepth 1 \ | $(XARGS) $(GREP) -l -i -E '[[:space:]]*.[[:space:]]*TEST_MODE[[:space:]]*\:[[:space:]]*COMPILE_ONLY_OK' \ | $(SED) -e 's/\(^.*\)/\SRCLIST_COMPILE_ONLY_OK \+\= \.\/\1/g' \ >> $(LOG_TESTS_INC) @$(ECHO) "#" >> $(LOG_TESTS_INC) @$(PRINTF) "." - @$(FIND) $(DIRLIST) -type f -name '*.bas' -or -name '*.bmk' \ + @$(FIND) $(DIRLIST) -type f -name '*.bas' -or -name '*.bmk' -mindepth 1 \ | $(XARGS) $(GREP) -l -i -E '[[:space:]]*.[[:space:]]*TEST_MODE[[:space:]]*\:[[:space:]]*COMPILE_ONLY_FAIL' \ | $(SED) -e 's/\(^.*\)/\SRCLIST_COMPILE_ONLY_FAIL \+\= \.\/\1/g' \ >> $(LOG_TESTS_INC) @$(ECHO) "#" >> $(LOG_TESTS_INC) @$(PRINTF) "." - @$(FIND) $(DIRLIST) -type f -name '*.bas' -or -name '*.bmk' \ + @$(FIND) $(DIRLIST) -type f -name '*.bas' -or -name '*.bmk' -mindepth 1 \ | $(XARGS) $(GREP) -l -i -E '[[:space:]]*.[[:space:]]*TEST_MODE[[:space:]]*\:[[:space:]]*COMPILE_AND_RUN_OK' \ | $(SED) -e 's/\(^.*\)/\SRCLIST_COMPILE_AND_RUN_OK \+\= \.\/\1/g' \ >> $(LOG_TESTS_INC) @$(ECHO) "#" >> $(LOG_TESTS_INC) @$(PRINTF) "." - @$(FIND) $(DIRLIST) -type f -name '*.bas' -or -name '*.bmk' \ + @$(FIND) $(DIRLIST) -type f -name '*.bas' -or -name '*.bmk' -mindepth 1 \ | $(XARGS) $(GREP) -l -i -E '[[:space:]]*.[[:space:]]*TEST_MODE[[:space:]]*\:[[:space:]]*COMPILE_AND_RUN_FAIL' \ | $(SED) -e 's/\(^.*\)/\SRCLIST_COMPILE_AND_RUN_FAIL \+\= \.\/\1/g' \ >> $(LOG_TESTS_INC) @$(ECHO) "#" >> $(LOG_TESTS_INC) @$(PRINTF) "." - @$(FIND) $(DIRLIST) -type f -name '*.bmk' \ + @$(FIND) $(DIRLIST) -type f -name '*.bmk' -mindepth 1 \ | $(XARGS) $(GREP) -l -i -E '[[:space:]]*.[[:space:]]*TEST_MODE[[:space:]]*\:[[:space:]]*MULTI_MODULE_OK' \ | $(SED) -e 's/\(^.*\)/\SRCLIST_MULTI_MODULE_OK \+\= \.\/\1/g' \ >> $(LOG_TESTS_INC) @$(ECHO) "#" >> $(LOG_TESTS_INC) @$(PRINTF) "." - @$(FIND) $(DIRLIST) -type f -name '*.bmk' \ + @$(FIND) $(DIRLIST) -type f -name '*.bmk' -mindepth 1 \ | $(XARGS) $(GREP) -l -i -E '[[:space:]]*.[[:space:]]*TEST_MODE[[:space:]]*\:[[:space:]]*MULTI_MODULE_FAIL' \ | $(SED) -e 's/\(^.*\)/\SRCLIST_MULTI_MODULE_FAIL \+\= \.\/\1/g' \ >> $(LOG_TESTS_INC) @@ -373,7 +373,7 @@ $(LOG_TESTS_LOG_LST) : $(LOG_TESTS_INC) # # $(LOG_TESTS_RESULTS_LOG): $(LOG_TESTS_LOG_LST) $(LOGLIST_ALL) - @$(XARGS) -a $(LOG_TESTS_LOG_LST) $(GREP) -i -E '^.*[[:space:]]*:[[:space:]]*RESULT=FAILED' | $(TAIL) -n +1 > $@ + @$(CAT) $(LOG_TESTS_LOG_LST) | $(XARGS) $(GREP) -i -E '^.*[[:space:]]*:[[:space:]]*RESULT=FAILED' | $(TAIL) -n +1 > $@ results : $(LOG_TESTS_RESULTS_LOG) @@ -407,9 +407,13 @@ mostlyclean : clean_tests clean_tests : @$(ECHO) Cleaning log-tests for -lang $(FB_LANG) ... $(RM) $(LOG_TESTS_RESULTS_LOG) -ifneq ($(LOGLIST_ALL),) - @if [ -f $(LOG_TESTS_LOG_LST) ]; then $(XARGS) -r -a $(LOG_TESTS_LOG_LST) $(RM) ; fi - @if [ -f $(LOG_TESTS_OBJ_LST) ]; then $(XARGS) -r -a $(LOG_TESTS_OBJ_LST) $(RM) ; fi +ifneq ($(LOG_TESTS_LOG_LST),) + @if [ -f $(LOG_TESTS_LOG_LST) ]; then $(CAT) $(LOG_TESTS_LOG_LST) | $(XARGS) -r $(RM) ; fi + $(RM) $(LOG_TESTS_LOG_LST) +endif +ifneq ($(LOG_TESTS_OBJ_LST),) + @if [ -f $(LOG_TESTS_OBJ_LST) ]; then $(CAT) $(LOG_TESTS_OBJ_LST) | $(XARGS) -r $(RM) ; fi + $(RM) $(LOG_TESTS_OBJ_LST) endif ifneq ($(APPLIST_COMPILE_AND_RUN_OK),) @@ -427,7 +431,7 @@ endif .PHONY: clean_include clean_include : - $(RM) $(LOG_TESTS_INC) $(LOG_TESTS_LOG_LST) $(LOG_TESTS_OBJ_LST) + $(RM) $(LOG_TESTS_INC) @$(RM) $(FAILED_LOG) .PHONY: clean_failed_include diff --git a/tests/optimizations/inline-ops.bas b/tests/optimizations/inline-ops.bas index 004c6f8d6f..b015eb667f 100644 --- a/tests/optimizations/inline-ops.bas +++ b/tests/optimizations/inline-ops.bas @@ -2,6 +2,10 @@ #include once "crt/math.bi" +#ifndef ENABLE_CHECK_BUGS +#define ENABLE_CHECK_BUGS 0 +#endif + SUITE( fbc_tests.optimizations.inline_ops ) const EPSILON_SNG as single = 1.19290929e-7 @@ -191,8 +195,18 @@ SUITE( fbc_tests.optimizations.inline_ops ) CU_ASSERT_DOUBLE_EQUAL( asin( v ), asin_( v ), EPSILON_DBL ) CU_ASSERT_DOUBLE_EQUAL( cos( v ), cos_( v ), EPSILON_DBL ) CU_ASSERT_DOUBLE_EQUAL( acos( v ), acos_( v ), EPSILON_DBL ) +#if defined(__FB_FREEBSD__) + #if (ENABLE_CHECK_BUGS<>0) CU_ASSERT_DOUBLE_EQUAL( tan( v ), tan_( v ), EPSILON_DBL ) + #else + '' freebsd tightened up accuracy on tan() function in feb 2021 + '' so we might see a inaccuracy in results here depending on + '' what crt is being used and what in-line operation is used + CU_ASSERT_DOUBLE_EQUAL( tan( v ), tan_( v ), EPSILON_DBL*2 ) + #endif +#else CU_ASSERT_DOUBLE_EQUAL( atn( v ), atan_( v ), EPSILON_DBL ) +#endif CU_ASSERT_DOUBLE_EQUAL( exp( v ), exp_( v ), EPSILON_DBL ) next diff --git a/tests/unit-tests.mk b/tests/unit-tests.mk index 55d2dc39a9..49ee0ea507 100644 --- a/tests/unit-tests.mk +++ b/tests/unit-tests.mk @@ -32,6 +32,7 @@ GREP := grep SED := sed ECHO := echo PRINTF := printf +CAT := cat ifndef FBC FBC := fbc$(EXEEXT) @@ -195,7 +196,7 @@ clean_main_exe : clean_tests : @$(ECHO) Cleaning unit-tests files ... @$(RM) ./$(MAINBAS).o - @if [ -f $(UNIT_TESTS_OBJ_LST) ]; then $(XARGS) -r -a $(UNIT_TESTS_OBJ_LST) $(RM) ; fi + @if [ -f $(UNIT_TESTS_OBJ_LST) ]; then $(CAT) $(UNIT_TESTS_OBJ_LST) | $(XARGS) -r $(RM) ; fi .PHONY: clean_fbcu clean_fbcu :