1{ stdenv
2, buildPackages
3, lib
4, fetchzip
5, fetchpatch
6, gpm
7, libffi
8, libGL
9, libX11
10, libXext
11, libXpm
12, libXrandr
13, ncurses
14}:
15
16stdenv.mkDerivation rec {
17 pname = "fbc";
18 version = "1.09.0";
19
20 src = fetchzip {
21 # Bootstrap tarball has sources pretranslated from FreeBASIC to C
22 url = "https://github.com/freebasic/fbc/releases/download/${version}/FreeBASIC-${version}-source-bootstrap.tar.xz";
23 sha256 = "1q1gxp5kjz4vkcs9jl0x01v8qm1q2j789lgvxvikzd591ay0xini";
24 };
25
26 patches = [
27 # Fixes fbc_tests.udt_wstring_.midstmt ascii getting stuck due to stack corruption
28 # Remove when >1.09.0
29 (fetchpatch {
30 name = "fbc-tests-Fix-stack-corruption.patch";
31 url = "https://github.com/freebasic/fbc/commit/42f4f6dfdaafdd5302a647152f16cda78e4ec904.patch";
32 excludes = [ "changelog.txt" ];
33 sha256 = "sha256-Bn+mnTIkM2/uM2k/b9+Up4HJ7SJWwfD3bWLJsSycFRE=";
34 })
35 # Respect SOURCE_DATE_EPOCH when set
36 # Remove when >1.09.0
37 (fetchpatch {
38 name = "fbc-SOURCE_DATE_EPOCH-support.patch";
39 url = "https://github.com/freebasic/fbc/commit/74ea6efdcfe9a90d1c860f64d11ab4a6cd607269.patch";
40 excludes = [ "changelog.txt" ];
41 sha256 = "sha256-v5FTi4vKOvSV03kigZDiOH8SEGEphhzkBL6p1hd+NtU=";
42 })
43 ];
44
45 postPatch = ''
46 patchShebangs tests/warnings/test.sh
47
48 # Some tests lack proper dependency on libstdc++
49 for missingStdcpp in tests/cpp/{class,call2}-fbc.bas; do
50 sed -i -e "/'"' TEST_MODE : /a #inclib "stdc++"' $missingStdcpp
51 done
52
53 # Help compiler find libstdc++ with gcc backend
54 sed -i -e '/fbcAddLibPathFor( "libgcc.a" )/a fbcAddLibPathFor( "libstdc++.so" )' src/compiler/fbc.bas
55 '';
56
57 dontConfigure = true;
58
59 depsBuildBuild = [
60 buildPackages.stdenv.cc
61 buildPackages.ncurses
62 buildPackages.libffi
63 ];
64
65 buildInputs = [
66 ncurses
67 libffi
68 ] ++ lib.optionals stdenv.hostPlatform.isLinux [
69 gpm
70 libGL
71 libX11
72 libXext
73 libXpm
74 libXrandr
75 ];
76
77 enableParallelBuilding = true;
78
79 hardeningDisable = [
80 "format"
81 ];
82
83 makeFlags = lib.optionals (stdenv.buildPlatform != stdenv.hostPlatform) [
84 "TARGET=${stdenv.hostPlatform.config}"
85 ];
86
87 preBuild = ''
88 export buildJobs=$NIX_BUILD_CORES
89 if [ -z "$enableParallelBuilding" ]; then
90 buildJobs=1
91 fi
92
93 echo Bootstrap an unpatched build compiler
94 make bootstrap-minimal -j$buildJobs \
95 BUILD_PREFIX=${buildPackages.stdenv.cc.targetPrefix} LD=${buildPackages.stdenv.cc.targetPrefix}ld
96
97 echo Compile patched build compiler and host rtlib
98 make compiler -j$buildJobs \
99 "FBC=$PWD/bin/fbc${stdenv.buildPlatform.extensions.executable} -i $PWD/inc" \
100 BUILD_PREFIX=${buildPackages.stdenv.cc.targetPrefix} LD=${buildPackages.stdenv.cc.targetPrefix}ld
101 make rtlib -j$buildJobs \
102 "FBC=$PWD/bin/fbc${stdenv.buildPlatform.extensions.executable} -i $PWD/inc" \
103 ${if (stdenv.buildPlatform == stdenv.hostPlatform) then
104 "BUILD_PREFIX=${buildPackages.stdenv.cc.targetPrefix} LD=${buildPackages.stdenv.cc.targetPrefix}ld"
105 else
106 "TARGET=${stdenv.hostPlatform.config}"
107 }
108
109 echo Install patched build compiler and host rtlib to local directory
110 make install-compiler prefix=$PWD/patched-fbc
111 make install-rtlib prefix=$PWD/patched-fbc ${lib.optionalString (stdenv.buildPlatform != stdenv.hostPlatform) "TARGET=${stdenv.hostPlatform.config}"}
112 make clean
113
114 echo Compile patched host everything with previous patched stage
115 buildFlagsArray+=("FBC=$PWD/patched-fbc/bin/fbc${stdenv.buildPlatform.extensions.executable} -i $PWD/inc")
116 '';
117
118 installFlags = [
119 "prefix=${placeholder "out"}"
120 ];
121
122 # Tests do not work when cross-compiling even if build platform can execute
123 # host binaries, compiler struggles to find the cross compiler's libgcc_s
124 doCheck = stdenv.buildPlatform == stdenv.hostPlatform;
125
126 checkTarget = "unit-tests warning-tests log-tests";
127
128 checkFlags = [
129 "UNITTEST_RUN_ARGS=--verbose" # see what unit-tests are doing
130 "ABORT_CMD=false" # abort log-tests on failure
131 ];
132
133 checkPhase = ''
134 runHook preCheck
135
136 # Some tests fail with too much parallelism
137 export maxCheckJobs=50
138 export checkJobs=$(($NIX_BUILD_CORES<=$maxCheckJobs ? $NIX_BUILD_CORES : $maxCheckJobs))
139 if [ -z "$enableParallelChecking" ]; then
140 checkJobs=1
141 fi
142
143 # Run check targets in series, else the logs are a mess
144 for target in $checkTarget; do
145 make $target -j$checkJobs $makeFlags $checkFlags
146 done
147
148 runHook postCheck
149 '';
150
151 meta = with lib; {
152 homepage = "https://www.freebasic.net/";
153 description = "A multi-platform BASIC Compiler";
154 longDescription = ''
155 FreeBASIC is a completely free, open-source, multi-platform BASIC compiler (fbc),
156 with syntax similar to (and support for) MS-QuickBASIC, that adds new features
157 such as pointers, object orientation, unsigned data types, inline assembly,
158 and many others.
159 '';
160 license = licenses.gpl2Plus; # runtime & graphics libraries are LGPLv2+ w/ static linking exception
161 maintainers = with maintainers; [ OPNA2608 ];
162 platforms = with platforms; windows ++ linux;
163 };
164}