├── .editorconfig ├── .gitignore ├── README.md ├── flake.lock ├── flake.nix └── pkgs ├── 7zz ├── default.nix └── symlink.patch └── xilinx-ise ├── default.nix ├── env.nix ├── fhs.nix ├── jtag-fw.nix ├── udev-rules.nix ├── unwrapped.nix └── wrappers.nix /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | trim_trailing_whitespace = true 6 | insert_final_newline = true 7 | 8 | [*.nix] 9 | indent_style = space 10 | indent_size = 2 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | result 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Xilinx ISE Flake 2 | This flake packages ISE as a Nix package. It is derived from ISE 14.7 for Windows 10 as this is in fact a Linux VM with ISE pre-installed and licensed. 3 | 4 | ## Prerequisites 5 | - x86_64 Linux with Nix installed and flakes enabled. 6 | - The `Xilinx_ISE_14.7_Win10_14.7_VM_0213_1.zip` file - this may be downloaded from the [Xilinx website](https://www.xilinx.com/member/forms/download/xef.html?filename=Xilinx_ISE_14.7_Win10_14.7_VM_0213_1.zip). 7 | - The zip file must be added to the Nix store. If your machine has a relatively large amount of memory (>>16GB) then this may be done simply by `nix-store --add-fixed sha256 Xilinx_ISE_14.7_Win10_14.7_VM_0213_1.zip`. If your machine has less memory this will either fail, or take an excessive amount of time, this is because Nix loads the entire file into memory during the process. Instead the file may be added to the store manually as [detailed here](https://nixos.wiki/wiki/Cheatsheet#Adding_files_to_the_store). 8 | - ~100GB of disk space for the install process, once installed the footprint is ~35GB. 9 | 10 | ## Usage 11 | - The `xilinx-ise` wrapper can run any tool normally available on `$PATH` with ISE and will forward any arguments. This may be used directly via `nix run`. For example, to get the help for `par` you might run `nix run .#xilinx-ise -- par -?`. Note, the `--` is required so that Nix does not attempt to parse any arguments passed to the target. 12 | - This flake also provides an overlay with a `xilinx-ise` package, installing this package provides some benefits: 13 | - The following applications have .desktop files and will be available as any other graphical application in your environment. 14 | - Analyzer (ChipScope Pro) 15 | - CompXlib 16 | - Constraints Editor 17 | - CORE Generator 18 | - FPGA Editor 19 | - iMPACT 20 | - Inserter (ChipScope Pro) 21 | - Project Navigator 22 | - Timing Analyzer 23 | - XPower Analyzer 24 | - Those and a number of other binaries have wrappers and are available on `$PATH`. Please check `pkgs/xilinx-ise/wrappers.nix` for the full list. 25 | - This package also provides the `xilinx-ise` wrapper for execution of any other ISE tools. 26 | 27 | ## Using a JTAG cable 28 | - In order to use a JTAG cable with the Xilinx tools a set of udev rules must be installed. The package `xilinx-udev-rules` may be added to `services.udev.packages` on NixOS to install these rules, other distributions will require different steps. 29 | 30 | ## Known issues 31 | - There is no network access for any tool (including those with wrappers). This is because they are run within a network namespace allowing for a dummy NIC with the appropriate MAC for the included license to be added. So far I am only aware of SmartXplorer that this is a problem for - if there is critical functionality that this breaks it may be possible to come up with some solution. 32 | - The FPGA editor tool appears to work but has a couple of minor issues. Firstly it takes a long time to launch, this would typically be resolved by running rpcbind/portmap however due to the broken networking this isn't possible. Additionally once running any file browse buttons in the FPGA editor will not work instead giving the error "Can't access this folder. Path is too long." - the path must be typed into the field. 33 | 34 | ## Contributions 35 | I have had very little experience with ISE, this project was mostly spurred on because of a [Kintex-7 dev board that I recently became aware of](https://twitter.com/lucasteske/status/1473713374953357320). If there are any tools that fail to launch, or there are more tools that you believe should have wrappers by default, please open an issue and PRs to fix issues are very welcome! 36 | -------------------------------------------------------------------------------- /flake.lock: -------------------------------------------------------------------------------- 1 | { 2 | "nodes": { 3 | "nixpkgs": { 4 | "locked": { 5 | "lastModified": 1640798027, 6 | "narHash": "sha256-1e7bsxWJW0ugkA95AMGL3Da9sHugkz+J4kfYB9fTWZc=", 7 | "owner": "NixOS", 8 | "repo": "nixpkgs", 9 | "rev": "8588b14a397e045692d0a87192810b6dddf53003", 10 | "type": "github" 11 | }, 12 | "original": { 13 | "id": "nixpkgs", 14 | "ref": "release-21.11", 15 | "type": "indirect" 16 | } 17 | }, 18 | "root": { 19 | "inputs": { 20 | "nixpkgs": "nixpkgs" 21 | } 22 | } 23 | }, 24 | "root": "root", 25 | "version": 7 26 | } 27 | -------------------------------------------------------------------------------- /flake.nix: -------------------------------------------------------------------------------- 1 | { 2 | description = "FPGA tools for Nix."; 3 | 4 | inputs.nixpkgs.url = "nixpkgs/release-21.11"; 5 | 6 | outputs = { self, nixpkgs }: 7 | let 8 | # System types to support. 9 | supportedSystems = [ "x86_64-linux" ]; 10 | 11 | # Helper function to generate an attrset '{ x86_64-linux = f "x86_64-linux"; ... }'. 12 | forAllSystems = nixpkgs.lib.genAttrs supportedSystems; 13 | 14 | # Nixpkgs instantiated for supported system types. 15 | nixpkgsFor = forAllSystems (system: import nixpkgs { inherit system; overlays = [ self.overlay ]; }); 16 | 17 | in 18 | { 19 | # A Nixpkgs overlay. 20 | overlay = self: super: { 21 | xilinx-ise = super.callPackage ./pkgs/xilinx-ise { }; 22 | xilinx-udev-rules = super.callPackage ./pkgs/xilinx-ise/udev-rules.nix { }; 23 | }; 24 | 25 | # Provide some binary packages for selected system types. 26 | packages = forAllSystems (system: 27 | { 28 | inherit (nixpkgsFor.${system}) xilinx-ise xilinx-udev-rules; 29 | }); 30 | 31 | # Add the wrapper to apps for nix run. 32 | apps = forAllSystems (system: 33 | let 34 | pkgs = nixpkgsFor.${system}; 35 | in { 36 | xilinx-ise = { 37 | type = "app"; 38 | program = "${pkgs.xilinx-ise}/bin/xilinx-ise"; 39 | }; 40 | }); 41 | }; 42 | } 43 | -------------------------------------------------------------------------------- /pkgs/7zz/default.nix: -------------------------------------------------------------------------------- 1 | { pkgs, fetchurl }: 2 | 3 | pkgs._7zz.overrideAttrs (oldAttrs: rec { 4 | version = "21.07"; 5 | sourceRoot = "."; 6 | preBuild = "cd CPP/7zip/Bundles/Alone2"; 7 | makefile = "../../cmpl_gcc.mak"; 8 | patches = [ ./symlink.patch ]; 9 | src = fetchurl { 10 | url = "https://www.7-zip.org/a/7z2107-src.7z"; 11 | sha256 = "d1074d56f415aab99d99e597a7b66dc455dba6349ae8a4c89df76475b6a1284c"; 12 | }; 13 | doInstallCheck = false; 14 | }) 15 | -------------------------------------------------------------------------------- /pkgs/7zz/symlink.patch: -------------------------------------------------------------------------------- 1 | diff -ur a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 2 | --- a/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 2021-12-28 18:37:31.728135781 -0800 3 | +++ b/CPP/7zip/UI/Common/ArchiveExtractCallback.cpp 2021-12-28 18:58:55.163340896 -0800 4 | @@ -1198,6 +1198,13 @@ 5 | if (!_link.linkPath.IsEmpty()) 6 | { 7 | #ifndef UNDER_CE 8 | + if (NFind::DoesFileOrDirExist(fullProcessedPath)) 9 | + { 10 | + if (!DeleteFileAlways(fullProcessedPath)) 11 | + { 12 | + RINOK(SendMessageError_with_LastError("can't delete file", fullProcessedPath)); 13 | + } 14 | + } 15 | { 16 | bool linkWasSet = false; 17 | RINOK(SetFromLinkPath(fullProcessedPath, _link, linkWasSet)); 18 | -------------------------------------------------------------------------------- /pkgs/xilinx-ise/default.nix: -------------------------------------------------------------------------------- 1 | { stdenv, lib, pkgs, callPackage, writeScript, makeDesktopItem }: 2 | 3 | let 4 | buildFHSUserEnv = callPackage ./fhs.nix { }; 5 | unwrapped = callPackage ./unwrapped.nix { }; 6 | xilinx-jtag-fw = callPackage ./jtag-fw.nix { }; 7 | motif3-compat = pkgs: stdenv.mkDerivation { 8 | name = "motif3-compat"; 9 | phases = [ "installPhase" ]; 10 | installPhase = '' 11 | mkdir -p $out/lib 12 | ln -s ${pkgs.motif}/lib/libXm.so.4 $out/lib/libXm.so.3 13 | ''; 14 | }; 15 | in buildFHSUserEnv rec { 16 | name = "xilinx-ise"; 17 | 18 | targetPkgs = pkgs: with pkgs; [ 19 | fontconfig 20 | freetype 21 | glib 22 | iproute2 23 | libstdcxx5 24 | libusb-compat-0_1 25 | libuuid 26 | motif 27 | (motif3-compat pkgs) 28 | xilinx-jtag-fw 29 | xorg.libICE 30 | xorg.libSM 31 | xorg.libX11 32 | xorg.libXcursor 33 | xorg.libXext 34 | xorg.libXft 35 | xorg.libXi 36 | xorg.libXmu 37 | xorg.libXp 38 | xorg.libXrandr 39 | xorg.libXrender 40 | xorg.libXt 41 | xorg.libXtst 42 | zlib 43 | ]; 44 | 45 | multiPkgs = pkgs: with pkgs; [ 46 | ncurses5 47 | ]; 48 | 49 | # Network namespace required so that a dummy NIC with the required MAC can 50 | # be provided. 51 | unshareNet = true; 52 | 53 | extraBwrapArgs = [ 54 | "--ro-bind ${unwrapped}/opt/Xilinx /opt/Xilinx" 55 | "--ro-bind ${unwrapped}/home/ise/.Xilinx/Xilinx.lic ~/.Xilinx/Xilinx.lic" 56 | "--cap-add CAP_NET_ADMIN" 57 | ]; 58 | 59 | extraInstallCommands = let 60 | wrappers = import ./wrappers.nix; 61 | 62 | desktopItemSymlinks = lib.foldr (item: str: 63 | let 64 | desktopItem = makeDesktopItem { 65 | type = "Application"; 66 | name = item.name; 67 | desktopName = item.name; 68 | comment = item.name; 69 | icon = "${unwrapped}/opt/Xilinx/14.7/ISE_DS/ISE/icons/${item.icon}"; 70 | exec = "${name} ${item.exec}"; 71 | }; 72 | in 73 | str + "ln -s ${desktopItem}/share/applications/* $out/share/applications\n" 74 | ) "" wrappers.graphical; 75 | 76 | executables = 77 | (map (item: item.exec) wrappers.graphical) ++ wrappers.commandLine; 78 | in '' 79 | mkdir -p $out/share/applications 80 | ${desktopItemSymlinks} 81 | 82 | WRAPPER=$out/bin/${name} 83 | EXECUTABLES="${lib.concatStringsSep " " (executables)}" 84 | for executable in $EXECUTABLES; do 85 | echo "#!${stdenv.shell}" >> $out/$executable 86 | echo "$WRAPPER $executable \$@" >> $out/$executable 87 | done 88 | cd $out 89 | chmod +x $EXECUTABLES 90 | # link into $out/bin so executables become available on $PATH 91 | ln --symbolic --relative --target-directory $out/bin $EXECUTABLES 92 | ''; 93 | 94 | runScript = writeScript "${name}-wrapper" '' 95 | # Create the eth0 interface required for the included license. 96 | ip link add eth0 type dummy 97 | ip link set dev eth0 address 08:00:27:68:C9:35 98 | 99 | # Configure the environment. 100 | source /opt/Xilinx/14.7/ISE_DS/common/.settings64.sh /opt/Xilinx/14.7/ISE_DS/common 101 | source /opt/Xilinx/14.7/ISE_DS/EDK/.settings64.sh /opt/Xilinx/14.7/ISE_DS/EDK 102 | source /opt/Xilinx/14.7/ISE_DS/PlanAhead/.settings64.sh /opt/Xilinx/14.7/ISE_DS/PlanAhead 103 | source /opt/Xilinx/14.7/ISE_DS/ISE/.settings64.sh /opt/Xilinx/14.7/ISE_DS/ISE 104 | 105 | # Execute target. 106 | exec $@ 107 | ''; 108 | } 109 | -------------------------------------------------------------------------------- /pkgs/xilinx-ise/env.nix: -------------------------------------------------------------------------------- 1 | { stdenv, lib, buildEnv, writeText, writeShellScriptBin, pkgs, pkgsi686Linux }: 2 | 3 | { name, profile ? "" 4 | , targetPkgs ? pkgs: [], multiPkgs ? pkgs: [] 5 | , extraBuildCommands ? "", extraBuildCommandsMulti ? "" 6 | , extraOutputsToInstall ? [] 7 | }: 8 | 9 | # HOWTO: 10 | # All packages (most likely programs) returned from targetPkgs will only be 11 | # installed once--matching the host's architecture (64bit on x86_64 and 32bit on 12 | # x86). 13 | # 14 | # Packages (most likely libraries) returned from multiPkgs are installed 15 | # once on x86 systems and twice on x86_64 systems. 16 | # On x86 they are merged with packages from targetPkgs. 17 | # On x86_64 they are added to targetPkgs and in addition their 32bit 18 | # versions are also installed. The final directory structure looks as 19 | # follows: 20 | # /lib32 will include 32bit libraries from multiPkgs 21 | # /lib64 will include 64bit libraries from multiPkgs and targetPkgs 22 | # /lib will link to /lib32 23 | 24 | let 25 | is64Bit = stdenv.hostPlatform.parsed.cpu.bits == 64; 26 | isMultiBuild = multiPkgs != null && is64Bit; 27 | isTargetBuild = !isMultiBuild; 28 | 29 | # list of packages (usually programs) which are only be installed for the 30 | # host's architecture 31 | targetPaths = targetPkgs pkgs ++ (if multiPkgs == null then [] else multiPkgs pkgs); 32 | 33 | # list of packages which are installed for both x86 and x86_64 on x86_64 34 | # systems 35 | multiPaths = multiPkgs pkgsi686Linux; 36 | 37 | # base packages of the chroot 38 | # these match the host's architecture, glibc_multi is used for multilib 39 | # builds. glibcLocales must be before glibc or glibc_multi as otherwiese 40 | # the wrong LOCALE_ARCHIVE will be used where only C.UTF-8 is available. 41 | basePkgs = with pkgs; 42 | [ glibcLocales 43 | (if isMultiBuild then glibc_multi else glibc) 44 | (toString gcc.cc.lib) bashInteractive coreutils less shadow su 45 | gawk diffutils findutils gnused gnugrep 46 | gnutar gzip bzip2 xz 47 | ]; 48 | baseMultiPkgs = with pkgsi686Linux; 49 | [ (toString gcc.cc.lib) 50 | ]; 51 | 52 | ldconfig = writeShellScriptBin "ldconfig" '' 53 | exec ${pkgs.glibc.bin}/bin/ldconfig -f /etc/ld.so.conf -C /etc/ld.so.cache "$@" 54 | ''; 55 | etcProfile = writeText "profile" '' 56 | export PS1='${name}-chrootenv:\u@\h:\w\$ ' 57 | export LOCALE_ARCHIVE='/usr/lib/locale/locale-archive' 58 | export LD_LIBRARY_PATH="/run/opengl-driver/lib:/run/opengl-driver-32/lib:/usr/lib:/usr/lib32''${LD_LIBRARY_PATH:+:}$LD_LIBRARY_PATH" 59 | export PATH="/run/wrappers/bin:/usr/bin:/usr/sbin:$PATH" 60 | export TZDIR='/etc/zoneinfo' 61 | 62 | # Force compilers and other tools to look in default search paths 63 | unset NIX_ENFORCE_PURITY 64 | export NIX_CC_WRAPPER_TARGET_HOST_${stdenv.cc.suffixSalt}=1 65 | export NIX_CFLAGS_COMPILE='-idirafter /usr/include' 66 | export NIX_CFLAGS_LINK='-L/usr/lib -L/usr/lib32' 67 | export NIX_LDFLAGS='-L/usr/lib -L/usr/lib32' 68 | export PKG_CONFIG_PATH=/usr/lib/pkgconfig 69 | export ACLOCAL_PATH=/usr/share/aclocal 70 | 71 | ${profile} 72 | ''; 73 | 74 | # Compose /etc for the chroot environment 75 | etcPkg = stdenv.mkDerivation { 76 | name = "${name}-chrootenv-etc"; 77 | buildCommand = '' 78 | mkdir -p $out/etc 79 | cd $out/etc 80 | 81 | # environment variables 82 | ln -s ${etcProfile} profile 83 | 84 | # symlink /etc/mtab -> /proc/mounts (compat for old userspace progs) 85 | ln -s /proc/mounts mtab 86 | ''; 87 | }; 88 | 89 | # Composes a /usr-like directory structure 90 | staticUsrProfileTarget = buildEnv { 91 | name = "${name}-usr-target"; 92 | # ldconfig wrapper must come first so it overrides the original ldconfig 93 | paths = [ etcPkg ldconfig ] ++ basePkgs ++ targetPaths; 94 | extraOutputsToInstall = [ "out" "lib" "bin" ] ++ extraOutputsToInstall; 95 | ignoreCollisions = true; 96 | }; 97 | 98 | staticUsrProfileMulti = buildEnv { 99 | name = "${name}-usr-multi"; 100 | paths = baseMultiPkgs ++ multiPaths; 101 | extraOutputsToInstall = [ "out" "lib" ] ++ extraOutputsToInstall; 102 | ignoreCollisions = true; 103 | }; 104 | 105 | # setup library paths only for the targeted architecture 106 | setupLibDirsTarget = '' 107 | # link content of targetPaths 108 | cp -rsHf ${staticUsrProfileTarget}/lib lib 109 | ln -s lib lib${if is64Bit then "64" else "32"} 110 | ''; 111 | 112 | # setup /lib, /lib32 and /lib64 113 | setupLibDirsMulti = '' 114 | mkdir -m0755 lib32 115 | mkdir -m0755 lib64 116 | ln -s lib64 lib 117 | 118 | # copy glibc stuff 119 | cp -rsHf ${staticUsrProfileTarget}/lib/32/* lib32/ && chmod u+w -R lib32/ 120 | 121 | # copy content of multiPaths (32bit libs) 122 | [ -d ${staticUsrProfileMulti}/lib ] && cp -rsHf ${staticUsrProfileMulti}/lib/* lib32/ && chmod u+w -R lib32/ 123 | 124 | # copy content of targetPaths (64bit libs) 125 | cp -rsHf ${staticUsrProfileTarget}/lib/* lib64/ && chmod u+w -R lib64/ 126 | 127 | # symlink 32-bit ld-linux.so 128 | ln -Ls ${staticUsrProfileTarget}/lib/32/ld-linux.so.2 lib/ 129 | ''; 130 | 131 | setupLibDirs = if isTargetBuild then setupLibDirsTarget 132 | else setupLibDirsMulti; 133 | 134 | # the target profile is the actual profile that will be used for the chroot 135 | setupTargetProfile = '' 136 | mkdir -m0755 usr 137 | cd usr 138 | ${setupLibDirs} 139 | ${lib.optionalString isMultiBuild '' 140 | if [ -d "${staticUsrProfileMulti}/share" ]; then 141 | cp -rLf ${staticUsrProfileMulti}/share share 142 | fi 143 | ''} 144 | if [ -d "${staticUsrProfileTarget}/share" ]; then 145 | if [ -d share ]; then 146 | chmod -R 755 share 147 | cp -rLTf ${staticUsrProfileTarget}/share share 148 | else 149 | cp -rLf ${staticUsrProfileTarget}/share share 150 | fi 151 | fi 152 | for i in bin sbin include; do 153 | if [ -d "${staticUsrProfileTarget}/$i" ]; then 154 | cp -rsHf "${staticUsrProfileTarget}/$i" "$i" 155 | fi 156 | done 157 | cd .. 158 | 159 | for i in var etc opt; do 160 | if [ -d "${staticUsrProfileTarget}/$i" ]; then 161 | cp -rsHf "${staticUsrProfileTarget}/$i" "$i" 162 | fi 163 | done 164 | for i in usr/{bin,sbin,lib,lib32,lib64}; do 165 | if [ -d "$i" ]; then 166 | ln -s "$i" 167 | fi 168 | done 169 | ''; 170 | 171 | in stdenv.mkDerivation { 172 | name = "${name}-fhs"; 173 | buildCommand = '' 174 | mkdir -p $out 175 | cd $out 176 | ${setupTargetProfile} 177 | cd $out 178 | ${extraBuildCommands} 179 | cd $out 180 | ${if isMultiBuild then extraBuildCommandsMulti else ""} 181 | ''; 182 | preferLocalBuild = true; 183 | allowSubstitutes = false; 184 | } 185 | -------------------------------------------------------------------------------- /pkgs/xilinx-ise/fhs.nix: -------------------------------------------------------------------------------- 1 | { lib, callPackage, runCommandLocal, writeShellScriptBin, glibc, pkgsi686Linux, coreutils, bubblewrap }: 2 | 3 | let buildFHSEnv = callPackage ./env.nix { }; in 4 | 5 | args @ { 6 | name 7 | , runScript ? "bash" 8 | , extraInstallCommands ? "" 9 | , meta ? {} 10 | , passthru ? {} 11 | , extraBwrapArgs ? [] 12 | , unshareUser ? true 13 | , unshareIpc ? true 14 | , unsharePid ? true 15 | , unshareNet ? false 16 | , unshareUts ? true 17 | , unshareCgroup ? true 18 | , dieWithParent ? true 19 | , ... 20 | }: 21 | 22 | with builtins; 23 | let 24 | buildFHSEnv = callPackage ./env.nix { }; 25 | 26 | env = buildFHSEnv (removeAttrs args [ 27 | "runScript" "extraInstallCommands" "meta" "passthru" "dieWithParent" "extraBwrapArgs" 28 | "unshareUser" "unshareCgroup" "unshareUts" "unshareNet" "unsharePid" "unshareIpc" 29 | ]); 30 | 31 | etcBindFlags = let 32 | files = [ 33 | # NixOS Compatibility 34 | "static" 35 | "nix" # mainly for nixUnstable users, but also for access to nix/netrc 36 | # Shells 37 | "bashrc" 38 | "zshenv" 39 | "zshrc" 40 | "zinputrc" 41 | "zprofile" 42 | # Users, Groups, NSS 43 | "passwd" 44 | "group" 45 | "shadow" 46 | "hosts" 47 | "resolv.conf" 48 | "nsswitch.conf" 49 | # User profiles 50 | "profiles" 51 | # Sudo & Su 52 | "login.defs" 53 | "sudoers" 54 | "sudoers.d" 55 | # Time 56 | "localtime" 57 | "zoneinfo" 58 | # Other Core Stuff 59 | "machine-id" 60 | "os-release" 61 | # PAM 62 | "pam.d" 63 | # Fonts 64 | "fonts" 65 | # ALSA 66 | "alsa" 67 | "asound.conf" 68 | # SSL 69 | "ssl/certs" 70 | "ca-certificates" 71 | "pki" 72 | ]; 73 | in concatStringsSep "\n " 74 | (map (file: "--ro-bind-try /etc/${file} /etc/${file}") files); 75 | 76 | extraArgs = concatStringsSep "\n " extraBwrapArgs; 77 | 78 | # Create this on the fly instead of linking from /nix 79 | # The container might have to modify it and re-run ldconfig if there are 80 | # issues running some binary with LD_LIBRARY_PATH 81 | createLdConfCache = '' 82 | cat > /etc/ld.so.conf < /dev/null 95 | ''; 96 | init = run: writeShellScriptBin "${name}-init" '' 97 | source /etc/profile 98 | ${createLdConfCache} 99 | exec ${run} "$@" 100 | ''; 101 | 102 | bwrapCmd = { initArgs ? "" }: '' 103 | blacklist=(/nix /dev /proc /etc) 104 | ro_mounts=() 105 | symlinks=() 106 | for i in ${env}/*; do 107 | path="/''${i##*/}" 108 | if [[ $path == '/etc' ]]; then 109 | : 110 | elif [[ -L $i ]]; then 111 | symlinks+=(--symlink "$(${coreutils}/bin/readlink "$i")" "$path") 112 | blacklist+=("$path") 113 | else 114 | ro_mounts+=(--ro-bind "$i" "$path") 115 | blacklist+=("$path") 116 | fi 117 | done 118 | 119 | if [[ -d ${env}/etc ]]; then 120 | for i in ${env}/etc/*; do 121 | path="/''${i##*/}" 122 | # NOTE: we're binding /etc/fonts and /etc/ssl/certs from the host so we 123 | # don't want to override it with a path from the FHS environment. 124 | if [[ $path == '/fonts' || $path == '/ssl' ]]; then 125 | continue 126 | fi 127 | ro_mounts+=(--ro-bind "$i" "/etc$path") 128 | done 129 | fi 130 | 131 | declare -a auto_mounts 132 | # loop through all directories in the root 133 | for dir in /*; do 134 | # if it is a directory and it is not in the blacklist 135 | if [[ -d "$dir" ]] && [[ ! "''${blacklist[@]}" =~ "$dir" ]]; then 136 | # add it to the mount list 137 | auto_mounts+=(--bind "$dir" "$dir") 138 | fi 139 | done 140 | 141 | cmd=( 142 | ${bubblewrap}/bin/bwrap 143 | --dev-bind /dev /dev 144 | --proc /proc 145 | --chdir "$(pwd)" 146 | ${lib.optionalString unshareUser "--unshare-user"} 147 | ${lib.optionalString unshareIpc "--unshare-ipc"} 148 | ${lib.optionalString unsharePid "--unshare-pid"} 149 | ${lib.optionalString unshareNet "--unshare-net"} 150 | ${lib.optionalString unshareUts "--unshare-uts"} 151 | ${lib.optionalString unshareCgroup "--unshare-cgroup"} 152 | ${lib.optionalString dieWithParent "--die-with-parent"} 153 | --ro-bind /nix /nix 154 | # Our glibc will look for the cache in its own path in `/nix/store`. 155 | # As such, we need a cache to exist there, because pressure-vessel 156 | # depends on the existence of an ld cache. However, adding one 157 | # globally proved to be a bad idea (see #100655), the solution we 158 | # settled on being mounting one via bwrap. 159 | # Also, the cache needs to go to both 32 and 64 bit glibcs, for games 160 | # of both architectures to work. 161 | --tmpfs ${glibc}/etc \ 162 | --symlink /etc/ld.so.conf ${glibc}/etc/ld.so.conf \ 163 | --symlink /etc/ld.so.cache ${glibc}/etc/ld.so.cache \ 164 | --ro-bind ${glibc}/etc/rpc ${glibc}/etc/rpc \ 165 | --remount-ro ${glibc}/etc \ 166 | --tmpfs ${pkgsi686Linux.glibc}/etc \ 167 | --symlink /etc/ld.so.conf ${pkgsi686Linux.glibc}/etc/ld.so.conf \ 168 | --symlink /etc/ld.so.cache ${pkgsi686Linux.glibc}/etc/ld.so.cache \ 169 | --ro-bind ${pkgsi686Linux.glibc}/etc/rpc ${pkgsi686Linux.glibc}/etc/rpc \ 170 | --remount-ro ${pkgsi686Linux.glibc}/etc \ 171 | ${etcBindFlags} 172 | "''${ro_mounts[@]}" 173 | "''${symlinks[@]}" 174 | "''${auto_mounts[@]}" 175 | ${extraArgs} 176 | ${init runScript}/bin/${name}-init ${initArgs} 177 | ) 178 | exec "''${cmd[@]}" 179 | ''; 180 | 181 | bin = writeShellScriptBin name (bwrapCmd { initArgs = ''"$@"''; }); 182 | 183 | in runCommandLocal name { 184 | inherit meta; 185 | 186 | passthru = passthru // { 187 | env = runCommandLocal "${name}-shell-env" { 188 | shellHook = bwrapCmd {}; 189 | } '' 190 | echo >&2 "" 191 | echo >&2 "*** User chroot 'env' attributes are intended for interactive nix-shell sessions, not for building! ***" 192 | echo >&2 "" 193 | exit 1 194 | ''; 195 | }; 196 | } '' 197 | mkdir -p $out/bin 198 | ln -s ${bin}/bin/${name} $out/bin/${name} 199 | ${extraInstallCommands} 200 | '' 201 | -------------------------------------------------------------------------------- /pkgs/xilinx-ise/jtag-fw.nix: -------------------------------------------------------------------------------- 1 | { stdenv, callPackage }: 2 | 3 | let 4 | unwrapped = callPackage ./unwrapped.nix { }; 5 | in 6 | stdenv.mkDerivation { 7 | name = "xilinx-jtag-fw"; 8 | phases = [ "installPhase" ]; 9 | installPhase = '' 10 | mkdir -p $out/share 11 | cp ${unwrapped}/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/*.hex $out/share/ 12 | ''; 13 | 14 | outputHashMode = "recursive"; 15 | outputHashAlgo = "sha256"; 16 | outputHash = "sha256-27wbXFe/vDvMS09bwgTewzQgGGcvdReQLQnqex+v+Uo="; 17 | } 18 | -------------------------------------------------------------------------------- /pkgs/xilinx-ise/udev-rules.nix: -------------------------------------------------------------------------------- 1 | { stdenv, pkgs, callPackage }: 2 | 3 | let 4 | fw = callPackage ./jtag-fw.nix { }; 5 | in 6 | pkgs.writeTextFile { 7 | name = "xilinx-udev-rules"; 8 | destination = "/etc/udev/rules.d/10-xilinx.rules"; 9 | text = '' 10 | SUBSYSTEMS=="usb", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0008", MODE="0660", TAG+="uaccess", GROUP+="plugdev" 11 | SUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0007", RUN+="${pkgs.fxload}/sbin/fxload -v -t fx2 -I ${fw}/share/xusbdfwu.hex -D $tempnode" 12 | SUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0009", RUN+="${pkgs.fxload}/sbin/fxload -v -t fx2 -I ${fw}/share/xusb_xup.hex -D $tempnode" 13 | SUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="000d", RUN+="${pkgs.fxload}/sbin/fxload -v -t fx2 -I ${fw}/share/xusb_emb.hex -D $tempnode" 14 | SUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="000f", RUN+="${pkgs.fxload}/sbin/fxload -v -t fx2 -I ${fw}/share/xusb_xlp.hex -D $tempnode" 15 | SUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0013", RUN+="${pkgs.fxload}/sbin/fxload -v -t fx2 -I ${fw}/share/xusb_xp2.hex -D $tempnode" 16 | SUBSYSTEMS=="usb", ENV{DEVTYPE}=="usb_device", ACTION=="add", ATTRS{idVendor}=="03fd", ATTRS{idProduct}=="0015", RUN+="${pkgs.fxload}/sbin/fxload -v -t fx2 -I ${fw}/share/xusb_xse.hex -D $tempnode" 17 | ''; 18 | } 19 | -------------------------------------------------------------------------------- /pkgs/xilinx-ise/unwrapped.nix: -------------------------------------------------------------------------------- 1 | { stdenv, lib, pkgs, requireFile, callPackage }: 2 | 3 | let 4 | _7zz-patched = callPackage ../7zz { }; 5 | 6 | in stdenv.mkDerivation rec { 7 | pname = "xilinx-ise-unwrapped"; 8 | version = "14.7"; 9 | src = requireFile { 10 | name = "Xilinx_ISE_14.7_Win10_14.7_VM_0213_1.zip"; 11 | sha256 = "1f6c3302d3c9450ad7c7ce0ddeb3413b451f0468beb1f26cb0b168661df4e18e"; 12 | url = "https://www.xilinx.com/member/forms/download/xef.html?filename=Xilinx_ISE_14.7_Win10_14.7_VM_0213_1.zip"; 13 | }; 14 | nativeBuildInputs = [ pkgs.unzip _7zz-patched ]; 15 | buildCommand = '' 16 | unzip $src 17 | tar xvf ova/14.7_VM.ova 18 | rm ova/14.7_VM.ova 19 | 7zz e 14.7_VM-disk001.vmdk 0.img 20 | rm 14.7_VM-disk001.vmdk 21 | 7zz x -snld -o$out 0.img opt/Xilinx home/ise 22 | ''; 23 | } 24 | -------------------------------------------------------------------------------- /pkgs/xilinx-ise/wrappers.nix: -------------------------------------------------------------------------------- 1 | ({ 2 | graphical = [ 3 | { 4 | name = "Analyzer"; 5 | icon = "analyzer.ico"; 6 | exec = "analyzer"; 7 | } 8 | { 9 | name = "CompXlib"; 10 | icon = "compxlib.ico"; 11 | exec = "compxlibgui"; 12 | } 13 | { 14 | name = "Constraints Editor"; 15 | icon = "constraints_editor.ico"; 16 | exec = "constraints_editor"; 17 | } 18 | { 19 | name = "CORE Generator"; 20 | icon = "coregen.ico"; 21 | exec = "coregen"; 22 | } 23 | { 24 | name = "FPGA Editor"; 25 | icon = "fpga_editor.ico"; 26 | exec = "fpga_editor"; 27 | } 28 | { 29 | name = "iMPACT"; 30 | icon = "impact.ico"; 31 | exec = "impact"; 32 | } 33 | { 34 | name = "Inserter"; 35 | icon = "inserter.ico"; 36 | exec = "inserter"; 37 | } 38 | { 39 | name = "Project Navigator"; 40 | icon = "projnav.ico"; 41 | exec = "ise"; 42 | } 43 | { 44 | name = "Timing Analyzer"; 45 | icon = "timinganalyzer.ico"; 46 | exec = "timingan"; 47 | } 48 | { 49 | name = "XPower Analyzer"; 50 | icon = "xpa.ico"; 51 | exec = "xpa"; 52 | } 53 | ]; 54 | 55 | commandLine = [ 56 | "partgen" "netgen" "ngdbuild" "map" "drc" "par" "smartxplorer" "xpwr" 57 | "pin2ucf" "trce" "speedprint" "bitgen" "bsdlanno" "promgen" "ibiswriter" 58 | "cpldfit" "tsim" "taengine" "hprep6" "xflow" "ngcbuild" "compxlib" 59 | "edif2ngd" "xst" 60 | ]; 61 | }) 62 | --------------------------------------------------------------------------------