FB基于GCC工具链和相应的库。但是,每个平台没有一个单一的GCC工具链,但往往是多个稍微不同的。FB通常可以与所有的一起工作,但依赖于选择构建和使用FB的工具链,仍然存在差异。在这里,我们记录了在构建FB和/或制作FB版本时要考虑的一些问题。
Windows(MinGW)
MinGW工具链:
- MinGW.org - 除了MinGW GCC工具链之外,还提供MSYS。没有Win64支持(还)。
- MinGW-w64 - 32位和64位。不同于MinGW.org的运行时库。
- TDM-GCC - 基于MinGW.org的32位,基于MinGW-w64的64位,并进行了修改。
- 各种GNU / Linux发行版的MinGW交叉编译器,例如Debian / Ubuntu和Fedora上的MinGW-w64(i686-w64-mingw32,x86_64-w64-mingw32)
备注:
- GCC异常处理机制:SJLJ setjump / longjump(缓慢而安全),DWARF-2(快速但并不总是工作)。MinGW.org工具链使用DWARF2,而对于MinGW-w64,这两种类型都可用。
FB不支持异常,因此在理论上,底层GCC工具链使用的异常处理机制并不重要。
实际上,DWARF-2 GCC生成堆放放的静态数据,放入.eh_frame部分。问题是,像所有的FB / GCC / MinGW运行时库一样,也会为C代码(不仅仅是C ++代码)生成.eh_frame数据,并且显着增加了.exe大小。这可以通过多种方式避免:
- 使用gcc标志禁止生成.eh_frame数据。FB在其makefile和-gen gcc中使用这个,但是显然它不会影响预构建的MinGW / GCC库(除非整个工具链被重建)。
-fno-exceptions -fno-unwind-tables -fno-asynchronous-unwind-tables
- 链接时丢弃/删除.eh_frame部分(通过使用自定义ldscript)
- 使用SJLJ工具链(即MinGW-w64是为SJLJ而不是MinGW.org而建的)
此外,异常处理方法可能是一个重要的细节(即使您不关心.exe大小),如果要使用FB中的C ++库,以防C ++库使用异常。
- GCC线程模型:Win32线程(本机),POSIX线程(基于winpthreads库)。MinGW.org工具链使用Win32线程,而对于MinGW-w64,这两种类型都可用。
GCC需要POSIX线程来实现某些新的C ++特性,这不是本机的Win32线程功能。因此,MinGW-w64使用提供Windows的POSIX线程功能的winpthreads库。但是,winpthreads不是MinGW-w64主要运行时的一部分,并且具有不同的许可证,这可能需要考虑。
由于FB不关心这些C ++功能,所以我们可以使用MinGW工具链和Win32线程,并避免使用winpthreads。
- MinGW.org和MinGW-w64之间的Globbing(命令行通配符扩展等)行为有所不同,因为它们具有不同的运行时库/启动代码。
- 默认情况下,MinGW.org运行时启用Globbing,但默认情况下MinGW-w64运行时关闭全局,并具有--enable-wildcard配置选项。因此,默认情况下是否启用或禁用,取决于如何构建MinGW-w64。
- 禁用globbing的方式是不同的:
Extern _CRT_glob Alias "_CRT_glob" As Long
Dim Shared _CRT_glob As Long = 0
Extern _dowildcard Alias "_dowildcard" As Long
Dim Shared _dowildcard As Long = 0
- MinGW-w64包含编译FB图形库所需的DirectX头文件。MinGW.org不包含它们;必须手动添加。
- MinGW.org为MinGW工具链和MSYS shell环境提供了一个常见的安装程序。这使得安装比其他工具链更容易,如果需要MSYS也是如此。
DOS (DJGPP)
FB需要DJGPP 2.04 beta运行时(DJGPP 2.03不工作?)。无论哪种方式,这个版本的DJGPP都是非常老的。另一方面,DJGPP最近没有发布,更新只能在DJGPP的CVS中找到。建议只使用DJGPP CVS。
{999796001}Linux{999796002}
GNU / Linux发行版通常会提供原生的gcc + glibc工具链,FB可以开箱即用。
由于系统库和/或版本的差异,例如glibc版本差异或ncurses / libtinfo差异,在一个GNU / Linux发行版上生成的可执行文件(如fbc本身)不一定可以移植到其他GNU / Linux发行版中。fbc最常见的问题是不匹配的glibc版本,即fbc二进制文件运行在具有比它构建的glibc更早的glibc的系统上,并且遇到某种形式的“glibc too old”错误。ncurses库并不总是完全一样,如“ospeed”具有不同的大小,考虑重新链接“运行fbc时的警告。另外,一些发行版已经分离了libncurses和libtinfo,有些只是libncurses,由于没有找到libtinfo共享库,这可能会导致错误。
在理论上,可以使用静态链接来避免共享库的问题:
- fbc -static命令行选项指示链接器更喜欢静态库而不是共享库。这可以(在理论上)也可以在构建fbc本身时使用。它依赖于Linux发行版提供静态版本的系统库。通常不鼓励在GNU / Linux上进行链接,特别是使用glibc(其某些组件不是为静态链接而设计的),而且通常(共享库优先于避免冗余)。
- FB理论上也可以使用不同的libc(而不是glibc),一个显式地支持静态链接,例如USL-libc中.
在这种情况下,您通常会使用自定义gcc工具链,这也需要专门为该工具链构建FB。这种方法一般工作得很好,但可以做很多工作。
除此之外,其他libc可能不会与glibc ABI兼容,如果FB程序是为glibc编写的,则可能会导致FB程序出现问题。最值得一提的是,FB Linux CRT头是基于glibc的。musl-libc(0.9)和glibc之间的ABI差异的一个例子是jmp_buf结构大小(与setjmp()/longjmp()函数一起使用)。由于FB CRT标头定义了glibc jmp_buf,它们与使用较小jmp_buf结构的musl-libc不兼容。
使用不同的libc而不是Linux发行版默认的另一个头痛是,您还需要构建很多库,例如ncurses,X11和Mesa / OpenGL,以满足FB的依赖关系,更不用说任何其他第三方库在你的程序中使用由于两个libc的ABI不兼容,因此可能无法使用预编译为glibc的现有库(至少不安全)。
参考