1# Arguments that this derivation gets when it is created with `callPackage`
2{ stdenv
3, lib
4, symlinkJoin
5, makeWrapper
6, runCommand
7, file
8}:
9
10open-watcom:
11
12let
13 wrapper =
14 {}:
15 let
16 archToBindir = with stdenv.hostPlatform; if isx86 then
17 "bin"
18 else if isAarch then
19 "arm"
20 # we don't support running on AXP
21 # don't know what MIPS, PPC bindirs are called
22 else throw "Don't know where ${system} binaries are located!";
23
24 binDirs = with stdenv.hostPlatform; if isWindows then [
25 (lib.optionalString is64bit "${archToBindir}nt64")
26 "${archToBindir}nt"
27 (lib.optionalString is32bit "${archToBindir}w")
28 ] else if (isDarwin) then [
29 (lib.optionalString is64bit "${archToBindir}o64")
30 # modern Darwin cannot execute 32-bit code anymore
31 (lib.optionalString is32bit "${archToBindir}o")
32 ] else [
33 (lib.optionalString is64bit "${archToBindir}l64")
34 "${archToBindir}l"
35 ];
36 # TODO
37 # This works good enough as-is, but should really only be targetPlatform-specific
38 # but we don't support targeting DOS, OS/2, 16-bit Windows etc Nixpkgs-wide so this needs extra logic
39 includeDirs = with stdenv.hostPlatform; [
40 "h"
41 ]
42 ++ lib.optional isWindows "h/nt"
43 ++ lib.optional isLinux "lh";
44 listToDirs = list: lib.strings.concatMapStringsSep ":" (dir: "${placeholder "out"}/${dir}") list;
45 name = "${open-watcom.passthru.prettyName}-${open-watcom.version}";
46 in
47 symlinkJoin {
48 inherit name;
49
50 paths = [ open-watcom ];
51
52 nativeBuildInputs = [ makeWrapper ];
53
54 postBuild = ''
55 mkdir $out/bin
56
57 for binDir in ${lib.strings.concatStringsSep " " binDirs}; do
58 for exe in $(find ${open-watcom}/$binDir \
59 -type f -executable \
60 ${lib.optionalString stdenv.hostPlatform.isLinux "-not -iname '*.so' -not -iname '*.exe'"} \
61 ); do
62 if [ ! -f $out/bin/$(basename $exe) ]; then
63 makeWrapper $exe $out/bin/$(basename $exe) \
64 --set WATCOM ${open-watcom} \
65 --prefix PATH : ${listToDirs binDirs} \
66 --set EDPATH ${open-watcom}/eddat \
67 --set INCLUDE ${listToDirs includeDirs}
68 fi
69 done
70 done
71 '';
72
73 passthru = {
74 unwrapped = open-watcom;
75 tests = let
76 wrapped = wrapper { };
77 in {
78 simple = runCommand "${name}-test-simple" { nativeBuildInputs = [ wrapped ]; } ''
79 cat <<EOF >test.c
80 #include <stdio.h>
81 int main() {
82 printf ("Testing OpenWatcom C89 compiler.\n");
83 return 0;
84 }
85 EOF
86 cat test.c
87 wcl386 -fe=test_c test.c
88 # Only test execution if hostPlatform is targetable
89 ${lib.optionalString (!stdenv.hostPlatform.isDarwin && !stdenv.hostPlatform.isAarch) "./test_c"}
90
91 cat <<EOF >test.cpp
92 #include <string>
93 #include <iostream>
94 int main() {
95 std::cout << "Testing OpenWatcom C++ library implementation." << std::endl;
96 watcom::istring HELLO ("HELLO");
97 if (HELLO != "hello") {
98 return 1;
99 }
100 if (HELLO.find ("ello") != 1) {
101 return 2;
102 }
103 return 0;
104 }
105 EOF
106 cat test.cpp
107 wcl386 -fe=test_cpp test.cpp
108 # Only test execution if hostPlatform is targetable
109 ${lib.optionalString (!stdenv.hostPlatform.isDarwin && !stdenv.hostPlatform.isAarch) "./test_cpp"}
110 touch $out
111 '';
112 cross = runCommand "${name}-test-cross" { nativeBuildInputs = [ wrapped file ]; } ''
113 cat <<EOF >test.c
114 #include <stdio.h>
115 int main() {
116 printf ("Testing OpenWatcom cross-compilation.\n");
117 return 0;
118 }
119 EOF
120 cat test.c
121
122 echo "Test compiling"
123 wcl386 -bcl=linux -fe=linux test.c
124 wcl386 -bcl=nt -fe=nt test.c
125 wcl386 -bcl=dos4g -fe=dos4g test.c
126 wcl -bcl=windows -fe=windows test.c
127 wcl -bcl=dos -fe=dos test.c
128
129 echo "Test file format"
130 file ./linux | grep "32-bit" | grep "Linux"
131 file ./nt.exe | grep "PE32" | grep "Windows"
132 file ./dos4g.exe | grep "MS-DOS" | grep "LE executable"
133 file ./windows.exe | grep "MS-DOS" | grep "Windows 3.x"
134 file ./dos.exe | grep "MS-DOS" | grep -v "LE" | grep -v "Windows 3.x"
135 touch $out
136 '';
137 };
138 };
139
140 inherit (open-watcom) meta;
141 };
142in
143lib.makeOverridable wrapper