Skip to content

Commit

Permalink
Add lief to shrinkwrap and remove patchelf (#2)
Browse files Browse the repository at this point in the history
* Add nixpkgs-fmt

* All flake checks passing now

* Add pull request CI workflow

* Added lief instead of patchelf

* Removed coreutils

* Changed copyfile -> copy to preserve execute

* Added a script to push to cachix

* Removed patchelf
  • Loading branch information
fzakaria authored Dec 24, 2021
1 parent e633799 commit dbea132
Show file tree
Hide file tree
Showing 13 changed files with 131 additions and 115 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pull_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ jobs:
name: fzakaria
- run: nix flake check --print-build-logs
- run: nix build --print-build-logs
- run: nix run . -- --help
- run: nix run . -- --help
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
*/__pycache__
result
ruby_stamped
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
lint:
poetry run black --check .
poetry run isort -c .
poetry run flake8 .
black --check .
isort -c .
flake8 .

format:
poetry run black .
poetry run isort .
black .
isort .

typecheck:
poetry run mypy --show-error-codes --pretty .
mypy --show-error-codes --pretty .


all: lint typecheck
Expand Down
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,22 @@ In _glibc_ the cache is keyed by the _soname_ value on the shared object. That a

Unfortunately, _musl_ does not support this functionality and ongoing discussions of inclusing it can be followed on the [mailing list](https://www.openwall.com/lists/musl/2021/12/21/1).

## Development

You must have [Nix](https://nixos.org) installed for development.

This package uses [poetry2nix](https://github.com/nix-community/poetry2nix) to easily setup a development environment.

```console
> nix develop
```

A helping `Makefile` is provided to run all the _linters_ and _formatters_.

```console
> make lint
```

## Contributions

Thanks to [@trws](https://github.com/trws) for the inspiration and original version of this Python script.
29 changes: 12 additions & 17 deletions derivation.nix
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
{ stdenv, lib, poetry2nix, python39, patchelf, coreutils, poetryOverrides
, writeScriptBin, makeWrapper }:
let
app = poetry2nix.mkPoetryApplication {
projectDir = ./.;
python = python39;
buildInputs = [ patchelf ];
overrides = [ poetry2nix.defaultPoetryOverrides poetryOverrides ];
};
in stdenv.mkDerivation {
name = "shrinkwrap";
buildInputs = [ makeWrapper ];
phases = [ "installPhase" ];
installPhase = ''
mkdir $out
makeWrapper ${app}/bin/shrinkwrap $out/bin/shrinkwrap --prefix PATH : ${lib.makeBinPath [coreutils patchelf]}
'';
{ stdenv
, lib
, poetry2nix
, python39
, poetryOverrides
, writeScriptBin
, makeWrapper
}:
poetry2nix.mkPoetryApplication {
projectDir = ./.;
python = python39;
overrides = [ poetry2nix.defaultPoetryOverrides poetryOverrides ];
}
34 changes: 27 additions & 7 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,43 @@
inherit system;
overlays = [ poetry2nix.overlay (import ./overlay.nix) ];
};
in {
runCodeAnalysis = name: command:
pkgs.runCommand "shrinkwrap-${name}-check" { } ''
cd ${self}
${command}
mkdir $out
'';
in
{
packages = { shrinkwrap = pkgs.shrinkwrap; };


checks = {
pytest-check = pkgs.runCommand "shrinkwrap-check" { } ''
cd ${self}
${pkgs.shrinkwrap-env}/bin/pytest .
mkdir $out
'';
pytest-check = runCodeAnalysis "pytest" ''
${pkgs.shrinkwrap-env}/bin/pytest -p no:cacheprovider .
'';
black-check = runCodeAnalysis "black" ''
${pkgs.shrinkwrap-env}/bin/black --check .
'';
mypy-check = runCodeAnalysis "mypy" ''
${pkgs.shrinkwrap-env}/bin/mypy .
'';
isort-check = runCodeAnalysis "isort" ''
${pkgs.shrinkwrap-env}/bin/isort -c .
'';
flake8-check = runCodeAnalysis "flake8" ''
${pkgs.shrinkwrap-env}/bin/flake8 .
'';
nixpkgs-fmt-check = runCodeAnalysis "nixpkgs-fmt" ''
${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt --check .
'';
};

defaultPackage = pkgs.shrinkwrap;

devShell = pkgs.shrinkwrap-env.env.overrideAttrs (old: {
nativeBuildInputs = with pkgs;
old.nativeBuildInputs ++ [ pkgs.poetry ];
old.nativeBuildInputs ++ [ poetry nixpkgs-fmt nix-linter ];
});

});
Expand Down
6 changes: 3 additions & 3 deletions overlay.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ self: super: {
poetryOverrides = self: super: {
typing-extensions = super.typing-extensions.overridePythonAttrs
(old: { buildInputs = (old.buildInputs or [ ]) ++ [ self.flit-core ]; });

lief = super.lief.overridePythonAttrs (old: { dontUseCmakeConfigure = true; nativeBuildInputs = [ self.pkgs.cmake ]; });
};

shrinkwrap = self.callPackage ./derivation.nix { };

shrinkwrap-env = self.poetry2nix.mkPoetryEnv {
projectDir = ./.;
overrides = [ self.poetry2nix.defaultPoetryOverrides self.poetryOverrides ];
editablePackageSources = {
shrinkwrap = ./shrinkwrap;
};
editablePackageSources = { shrinkwrap = ./shrinkwrap; };
};

}
104 changes: 37 additions & 67 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,14 @@ license = "MIT"
python = "^3.9"
sh = "^1.14.2"
click = "^8.0.3"
lief = "^0.11.5"

[tool.poetry.dev-dependencies]
black = "^21.12b0"
flake8 = "^4.0.1"
mypy = "^0.930"
isort = "^5.10.1"
pytest = "^6.2.5"
pytest-flake8 = "^1.0.7"
pytest-black = "^0.3.12"
pytest-mypy = "^0.8.1"

[tool.poetry.scripts]
shrinkwrap = 'shrinkwrap.cli:shrinkwrap'
Expand All @@ -28,7 +26,7 @@ skip = [".git", "result"]
profile = "black"

[tool.pytest.ini_options]
addopts = "--black --flake8 --mypy"
addopts = ""

[build-system]
requires = ["poetry-core>=1.0.0"]
Expand Down
7 changes: 7 additions & 0 deletions scripts/upload-to-cache
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/usr/bin/env bash

nix-store -qR \
--include-outputs \
$(nix-store -qd $(nix build --json | jq -r '.[].outputs | to_entries[].value')) \
| grep '\.drv$' \
| cachix push fzakaria
27 changes: 17 additions & 10 deletions shrinkwrap/cli.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import os
import re
from shutil import copy
from typing import Optional

import click
from sh import Command, ErrorReturnCode, RunningCommand, cp, patchelf # type: ignore
import lief # type: ignore
from sh import Command, ErrorReturnCode # type: ignore


@click.command()
Expand All @@ -15,24 +17,29 @@ def shrinkwrap(file: str, output: Optional[str]):
output = os.path.basename(file) + "_stamped"

try:
interpreter: RunningCommand = patchelf("--print-interpreter", file)
interpreter = Command(interpreter.strip())
binary: lief.Binary = lief.parse(file)
if not binary.has_interpreter:
click.echo("no interpreter set on the binary")
exit(1)
interpreter = Command(binary.interpreter)
resolution = interpreter("--list", file)
needed = set((ent.strip() for ent in patchelf("--print-needed", file)))

needed = binary.libraries
# copy the file to the desired output location
cp(file, output)
copy(file, output)

# once a release is made for https://github.com/NixOS/patchelf/issues/359
# we can condense this to a single patchelf call
for line in resolution:
m = re.match(r"\s*([^ ]+) => ([^ ]+)", line)
if not m:
continue
soname, lib = m.group(1), m.group(2)
if soname in needed:
patchelf("--replace-needed", soname, lib, output)
else:
patchelf("--add-needed", lib, output)
binary.remove_library(soname)

binary.add_library(lib)

# dump the new binary file
binary.write(output)
except ErrorReturnCode as e:
print(f"shrinkwrap failed: {e.stderr}")
exit(1)
Expand Down
Empty file added tests/__init__.py
Empty file.
Loading

0 comments on commit dbea132

Please sign in to comment.