1{ stdenv, fetchzip, vscode-utils, jq, mono46, clang-tools, writeScript
2, gdbUseFixed ? true, gdb # The gdb default setting will be fixed to specified. Use version from `PATH` otherwise.
3}:
4
5assert gdbUseFixed -> null != gdb;
6
7/*
8 Note that this version of the extension still has some nix specific issues
9 which could not be fixed merely by patching (inside a C# dll).
10
11 In particular, the debugger requires either gnome-terminal or xterm. However
12 instead of looking for the terminal executable in `PATH`, for any linux platform
13 the dll uses an hardcoded path to one of these.
14
15 So, in order for debugging to work properly, you merely need to create symlinks
16 to one of these terminals at the appropriate location.
17
18 The good news is the the utility library is open source and with some effort
19 we could build a patched version ourselves. See:
20
21 <https://github.com/Microsoft/MIEngine/blob/2885386dc7f35e0f1e44827269341e786361f28e/src/MICore/TerminalLauncher.cs#L156>
22
23 Also, the extension should eventually no longer require an external terminal. See:
24
25 <https://github.com/Microsoft/vscode-cpptools/issues/35>
26
27 Once the symbolic link temporary solution taken, everything shoud run smootly.
28*/
29
30let
31 gdbDefaultsTo = if gdbUseFixed then "${gdb}/bin/gdb" else "gdb";
32
33 langComponentBinaries = stdenv.mkDerivation {
34 name = "cpptools-language-component-binaries";
35
36 src = fetchzip {
37 url = https://download.visualstudio.microsoft.com/download/pr/11991016/8a81aa8f89aac452956b0e4c68e6620b/Bin_Linux.zip;
38 sha256 = "0ma59fxfldbgh6ijlvfbs3hnl4g0cnw5gs6286zdrp065n763sv4";
39 };
40
41 patchPhase = ''
42 elfInterpreter="${stdenv.glibc.out}/lib/ld-linux-x86-64.so.2"
43 patchelf --set-interpreter "$elfInterpreter" ./Microsoft.VSCode.CPP.Extension.linux
44 patchelf --set-interpreter "$elfInterpreter" ./Microsoft.VSCode.CPP.IntelliSense.Msvc.linux
45 chmod a+x ./Microsoft.VSCode.CPP.Extension.linux ./Microsoft.VSCode.CPP.IntelliSense.Msvc.linux
46 '';
47
48 installPhase = ''
49 mkdir -p "$out/bin"
50 find . -mindepth 1 -maxdepth 1 | xargs cp -a -t "$out/bin"
51 '';
52 };
53
54 openDebugAD7Script = writeScript "OpenDebugAD7" ''
55 #!${stdenv.shell}
56 BIN_DIR="$(cd "$(dirname "$0")" && pwd -P)"
57 ${if gdbUseFixed
58 then ''
59 export PATH=''${PATH}''${PATH:+:}${gdb}/bin
60 ''
61 else ""}
62 ${mono46}/bin/mono $BIN_DIR/bin/OpenDebugAD7.exe $*
63 '';
64in
65
66vscode-utils.buildVscodeMarketplaceExtension {
67 mktplcRef = {
68 name = "cpptools";
69 publisher = "ms-vscode";
70 version = "0.17.6";
71 sha256 = "2625be8b922ffc199e1c776f784d39b6e004523212f7956c93ae40f9040ce6d5";
72 };
73
74 buildInputs = [
75 jq
76 ];
77
78 postPatch = ''
79 mv ./package.json ./package_ori.json
80
81 # 1. Add activation events so that the extension is functional. This listing is empty when unpacking the extension but is filled at runtime.
82 # 2. Patch `packages.json` so that nix's *gdb* is used as default value for `miDebuggerPath`.
83 cat ./package_ori.json | \
84 jq --slurpfile actEvts ${./package-activation-events-0-16-1.json} '(.activationEvents) = $actEvts[0]' | \
85 jq '(.contributes.debuggers[].configurationAttributes | .attach , .launch | .properties.miDebuggerPath | select(. != null) | select(.default == "/usr/bin/gdb") | .default) = "${gdbDefaultsTo}"' > \
86 ./package.json
87
88 # Patch `packages.json` so that nix's *gdb* is used as default value for `miDebuggerPath`.
89 substituteInPlace "./package.json" \
90 --replace "\"default\": \"/usr/bin/gdb\"" "\"default\": \"${gdbDefaultsTo}\""
91
92 # Prevent download/install of extensions
93 touch "./install.lock"
94
95 # Move unused files out of the way.
96 mv ./debugAdapters/bin/OpenDebugAD7.exe.config ./debugAdapters/bin/OpenDebugAD7.exe.config.unused
97
98 # Combining the language component binaries as part of our package.
99 find "${langComponentBinaries}/bin" -mindepth 1 -maxdepth 1 | xargs cp -p -t "./bin"
100
101 # Mono runtimes from nix package (used by generated `OpenDebugAD7`).
102 rm "./debugAdapters/OpenDebugAD7"
103 cp -p "${openDebugAD7Script}" "./debugAdapters/OpenDebugAD7"
104
105 # Clang-format from nix package.
106 mkdir -p "./LLVM"
107 find "${clang-tools}" -mindepth 1 -maxdepth 1 | xargs ln -s -t "./LLVM"
108 '';
109
110 meta = with stdenv.lib; {
111 license = licenses.unfree;
112 maintainers = [ maintainers.jraygauthier ];
113 # A 32 bit linux would also be possible with some effort (specific download of binaries +
114 # patching of the elf files with 32 bit interpreter).
115 platforms = [ "x86_64-linux" ];
116 };
117}