nixpkgs mirror (for testing) github.com/NixOS/nixpkgs
nix
at devShellTools-shell 371 lines 11 kB view raw
1{ 2 lib, 3 stdenv, 4 5 server ? false, # build server version 6 7 fetchFromGitHub, 8 fetchNpmDeps, 9 fetchYarnDeps, 10 fetchzip, 11 replaceVars, 12 runCommand, 13 14 ant, 15 cacert, 16 cmake, 17 git, 18 jdk, 19 makeWrapper, 20 nodejs, 21 npmHooks, 22 xcbuild, 23 yarn, 24 yarnConfigHook, 25 zip, 26 27 apple-sdk_11, 28 boost187, 29 electron_36, 30 fontconfig, 31 gnumake, 32 hunspellDicts, 33 libuuid, 34 llvmPackages, 35 openssl, 36 pam, 37 pandoc, 38 quarto, 39 R, 40 soci, 41 sqlite, 42 zlib, 43 44 nixosTests, 45}: 46 47let 48 electron = electron_36; 49 50 mathJaxSrc = fetchzip { 51 url = "https://s3.amazonaws.com/rstudio-buildtools/mathjax-27.zip"; 52 hash = "sha256-J7SZK/9q3HcXTD7WFHxvh++ttuCd89Vc4SEBrUEU0AI="; 53 }; 54 55 # rev should ideally be the last commit of the release/rstudio-[codename] branch 56 quartoSrc = fetchFromGitHub { 57 owner = "quarto-dev"; 58 repo = "quarto"; 59 rev = "8ee12b5d6bd49c7b212eae894bd011ffbeea1c48"; 60 hash = "sha256-pTrWedYeG2SWQ4jl2fstKjsweWhj4aAvVDiSfkdU3No="; 61 }; 62 63 hunspellDictionaries = lib.filter lib.isDerivation (lib.unique (lib.attrValues hunspellDicts)); 64 # These dicts contain identically-named dict files, so we only keep the 65 # -large versions in case of clashes 66 largeDicts = lib.filter (d: lib.hasInfix "-large-wordlist" d.name) hunspellDictionaries; 67 otherDicts = lib.filter ( 68 d: !(lib.hasAttr "dictFileName" d && lib.elem d.dictFileName (map (d: d.dictFileName) largeDicts)) 69 ) hunspellDictionaries; 70 dictionaries = largeDicts ++ otherDicts; 71 72 # rstudio assumes quarto bundles pandoc into bin/tools/ 73 quartoWrapper = runCommand "quarto-wrapper" { } '' 74 mkdir -p $out/bin/tools 75 ln -s ${lib.getExe pandoc} $out/bin/tools/pandoc 76 ln -s ${lib.getExe quarto} $out/bin/quarto 77 ln -s ${quarto}/share $out/share 78 ''; 79in 80stdenv.mkDerivation rec { 81 pname = "RStudio"; 82 version = "2025.05.1+513"; 83 84 src = fetchFromGitHub { 85 owner = "rstudio"; 86 repo = "rstudio"; 87 tag = "v${version}"; 88 hash = "sha256-KaolU82bxzAlYl+aYwlFljqsmNv0dn8XP1llaLK3LQE="; 89 }; 90 91 # sources fetched into _deps via cmake's FetchContent 92 extSrcs = stdenv.mkDerivation { 93 name = "${pname}-${version}-ext-srcs"; 94 inherit src; 95 96 nativeBuildInputs = [ 97 cacert 98 cmake 99 git 100 ]; 101 102 installPhase = '' 103 runHook preInstall 104 105 # this will fail, since this is not meant to be a cmake entrypoint 106 # but it will fetch the dependencies regardless 107 cmake -S src/cpp/ext -B build || true 108 109 mkdir -p "$out" 110 cp -r build/_deps/*-src "$out/" 111 find "$out" -name .git -print0 | xargs -0 rm -rf 112 113 runHook postInstall 114 ''; 115 116 dontConfigure = true; 117 dontBuild = true; 118 dontFixup = true; 119 120 outputHash = "sha256-YW+l0/RZf8ek217pfWTwsR4PTugMGHyW+vaZEwGjMas="; 121 outputHashAlgo = "sha256"; 122 outputHashMode = "recursive"; 123 }; 124 125 nativeBuildInputs = [ 126 cmake 127 git 128 129 ant 130 jdk 131 132 nodejs 133 yarn 134 yarnConfigHook 135 zip 136 ] 137 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 138 xcbuild 139 ] 140 ++ lib.optionals (!server) [ 141 makeWrapper 142 (nodejs.python.withPackages (ps: [ ps.setuptools ])) 143 npmHooks.npmConfigHook 144 ]; 145 146 buildInputs = [ 147 boost187 148 libuuid 149 openssl 150 R 151 soci 152 sqlite.dev 153 ] 154 ++ lib.optionals stdenv.hostPlatform.isDarwin [ 155 apple-sdk_11 156 ] 157 ++ lib.optionals (!server) [ 158 fontconfig 159 ] 160 ++ lib.optionals server [ 161 pam 162 zlib 163 ]; 164 165 cmakeFlags = [ 166 (lib.cmakeFeature "RSTUDIO_TARGET" (if server then "Server" else "Electron")) 167 168 # don't try fetching the external dependencies already fetched in extSrcs 169 (lib.cmakeBool "FETCHCONTENT_FULLY_DISCONNECTED" true) 170 171 (lib.cmakeBool "RSTUDIO_USE_SYSTEM_BOOST" true) 172 (lib.cmakeBool "RSTUDIO_USE_SYSTEM_SOCI" true) 173 174 (lib.cmakeBool "RSTUDIO_DISABLE_CHECK_FOR_UPDATES" true) 175 (lib.cmakeBool "QUARTO_ENABLED" true) 176 (lib.cmakeBool "RSTUDIO_ENABLE_COPILOT" false) # copilot-language-server is unfree 177 (lib.cmakeBool "RSTUDIO_CRASHPAD_ENABLED" false) # This is a NOOP except on x86_64-darwin 178 179 (lib.cmakeFeature "CMAKE_INSTALL_PREFIX" ( 180 (placeholder "out") + (if stdenv.hostPlatform.isDarwin then "/Applications" else "/lib/rstudio") 181 )) 182 ] 183 ++ lib.optionals (!server) [ 184 (lib.cmakeBool "RSTUDIO_INSTALL_FREEDESKTOP" stdenv.hostPlatform.isLinux) 185 ]; 186 187 env = { 188 ELECTRON_SKIP_BINARY_DOWNLOAD = "1"; 189 190 # on Darwin, cmake uses find_library to locate R instead of using the PATH 191 NIX_LDFLAGS = "-L${R}/lib/R/lib"; 192 193 RSTUDIO_VERSION_MAJOR = lib.versions.major version; 194 RSTUDIO_VERSION_MINOR = lib.versions.minor version; 195 RSTUDIO_VERSION_PATCH = lib.versions.patch version; 196 RSTUDIO_VERSION_SUFFIX = "+" + toString (lib.tail (lib.splitString "+" version)); 197 }; 198 199 patches = [ 200 # Hack RStudio to only use the input R and provided libclang. 201 (replaceVars ./r-location.patch { 202 R = lib.getBin R; 203 }) 204 (replaceVars ./clang-location.patch { 205 libclang = lib.getLib llvmPackages.libclang; 206 }) 207 208 ./ignore-etc-os-release.patch 209 ./dont-yarn-install.patch 210 ./fix-darwin.patch 211 ./bump-node-abi.patch 212 ]; 213 214 postPatch = '' 215 # fix .desktop Exec field 216 substituteInPlace src/node/desktop/resources/freedesktop/rstudio.desktop.in \ 217 --replace-fail "\''${CMAKE_INSTALL_PREFIX}/rstudio" "rstudio" 218 219 # set install path of freedesktop files 220 substituteInPlace src/node/desktop/CMakeLists.txt \ 221 --replace-fail "/usr/share" "$out/share" 222 ''; 223 224 yarnOfflineCache = fetchYarnDeps { 225 src = quartoSrc; 226 hash = "sha256-F+gqVNNhLmyrC+tJuElw7cpx5z/WLHOiYow/y86KR5c="; 227 }; 228 229 dontYarnInstallDeps = true; # will call manually in preConfigure 230 231 npmRoot = "src/node/desktop"; 232 233 # don't build native modules with node headers 234 npmFlags = [ "--ignore-scripts" ]; 235 236 makeCacheWritable = true; 237 238 npmDeps = fetchNpmDeps { 239 name = "rstudio-${version}-npm-deps"; 240 inherit src; 241 postPatch = "cd ${npmRoot}"; 242 patches = [ 243 # needed for support for electron versions above electron_34 244 ./bump-node-abi.patch 245 ]; 246 hash = "sha256-64PJPUE/xwdQdxVGiKzy8ADnxXH/qGQtFMib0unZpoA="; 247 }; 248 249 preConfigure = '' 250 # populate the directories used by cmake's FetchContent 251 mkdir -p build/_deps 252 cp -r "$extSrcs"/* build/_deps 253 chmod -R u+w build/_deps 254 255 # set up node_modules directory inside quarto so that panmirror can be built 256 mkdir src/gwt/lib/quarto 257 cp -r --no-preserve=all ${quartoSrc}/* src/gwt/lib/quarto 258 pushd src/gwt/lib/quarto 259 yarnConfigHook 260 popd 261 262 ### set up dependencies that will be copied into the result 263 # note: only the directory names have to match upstream, the actual versions don't 264 # note: symlinks are preserved 265 266 mkdir dependencies/dictionaries 267 for dict in ${builtins.concatStringsSep " " dictionaries}; do 268 for i in "$dict/share/hunspell/"*; do 269 ln -s $i dependencies/dictionaries/ 270 done 271 done 272 273 ln -s ${quartoWrapper} dependencies/quarto 274 275 # version in dependencies/common/install-mathjax 276 ln -s ${mathJaxSrc} dependencies/mathjax-27 277 278 mkdir -p dependencies/common/node 279 # node used by cmake 280 # version in cmake/globals.cmake (RSTUDIO_NODE_VERSION) 281 ln -s ${nodejs} dependencies/common/node/22.13.1 282 283 '' 284 + lib.optionalString (!server) '' 285 pushd $npmRoot 286 287 substituteInPlace package.json \ 288 --replace-fail "npm ci && " "" 289 290 # use electron's headers to make node-gyp compile against the electron ABI 291 export npm_config_nodedir="${electron.headers}" 292 293 ### override the detected electron version 294 substituteInPlace node_modules/@electron-forge/core-utils/dist/electron-version.js \ 295 --replace-fail "return version" "return '${electron.version}'" 296 297 ### create the electron archive to be used by electron-packager 298 cp -r ${electron.dist} electron-dist 299 chmod -R u+w electron-dist 300 301 pushd electron-dist 302 zip -0Xqr ../electron.zip . 303 popd 304 305 rm -r electron-dist 306 307 # force @electron/packager to use our electron instead of downloading it 308 substituteInPlace node_modules/@electron/packager/dist/packager.js \ 309 --replace-fail "await this.getElectronZipPath(downloadOpts)" "'$(pwd)/electron.zip'" 310 311 # Work around known nan issue for electron_33 and above 312 # https://github.com/nodejs/nan/issues/978 313 substituteInPlace node_modules/nan/nan.h \ 314 --replace-fail '#include "nan_scriptorigin.h"' "" 315 316 # now that we patched everything, we still have to run the scripts we ignored with --ignore-scripts 317 npm rebuild 318 319 popd 320 ''; 321 322 postInstall = '' 323 mkdir -p $out/bin 324 '' 325 + lib.optionalString (server && stdenv.hostPlatform.isLinux) '' 326 ln -s $out/lib/rstudio/bin/{crash-handler-proxy,postback,r-ldpath,rpostback,rserver,rserver-pam,rsession,rstudio-server} $out/bin 327 '' 328 + lib.optionalString (!server && stdenv.hostPlatform.isLinux) '' 329 # remove unneeded electron files, since we'll wrap the app with our own electron 330 shopt -s extglob 331 rm -r $out/lib/rstudio/!(locales|resources|resources.pak) 332 333 makeWrapper ${lib.getExe electron} "$out/bin/rstudio" \ 334 --add-flags "$out/lib/rstudio/resources/app/" \ 335 --set-default ELECTRON_FORCE_IS_PACKAGED 1 \ 336 --suffix PATH : ${lib.makeBinPath [ gnumake ]} 337 338 ln -s $out/lib/rstudio/resources/app/bin/{diagnostics,rpostback} $out/bin 339 '' 340 + lib.optionalString (server && stdenv.hostPlatform.isDarwin) '' 341 ln -s $out/Applications/RStudio.app/Contents/MacOS/{crash-handler-proxy,postback,r-ldpath,rpostback,rserver,rserver-pam,rsession,rstudio-server} $out/bin 342 '' 343 + lib.optionalString (!server && stdenv.hostPlatform.isDarwin) '' 344 # electron can't find its files if we use a symlink here 345 makeWrapper $out/Applications/RStudio.app/Contents/MacOS/RStudio $out/bin/rstudio 346 347 ln -s $out/Applications/RStudio.app/Contents/Resources/app/bin/{diagnostics,rpostback} $out/bin 348 ''; 349 350 passthru = { 351 inherit server; 352 tests = lib.optionalAttrs stdenv.hostPlatform.isLinux { 353 inherit (nixosTests) rstudio-server; 354 }; 355 }; 356 357 meta = { 358 changelog = "https://github.com/rstudio/rstudio/tree/${src.rev}/version/news"; 359 description = "Set of integrated tools for the R language"; 360 homepage = "https://www.rstudio.com/"; 361 license = lib.licenses.agpl3Only; 362 maintainers = with lib.maintainers; [ 363 ciil 364 cfhammill 365 tomasajt 366 ]; 367 mainProgram = "rstudio" + lib.optionalString server "-server"; 368 # rstudio-server on darwin is only partially supported by upstream 369 platforms = lib.platforms.linux ++ lib.optionals (!server) lib.platforms.darwin; 370 }; 371}