experiment with buildGo2, a potential replacement for buildGo
This commit is contained in:
parent
8141fbfccf
commit
d666e85223
12 changed files with 319 additions and 0 deletions
6
go/buildgo2/asm/add.S
Normal file
6
go/buildgo2/asm/add.S
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
TEXT ·Add(SB),$0-24
|
||||||
|
MOVQ x+0(FP), BX
|
||||||
|
MOVQ y+8(FP), BP
|
||||||
|
ADDQ BP, BX
|
||||||
|
MOVQ BX, ret+16(FP)
|
||||||
|
RET
|
3
go/buildgo2/asm/buildgo2.go
Normal file
3
go/buildgo2/asm/buildgo2.go
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
package asm
|
||||||
|
|
||||||
|
func Add(x, y int64) int64
|
7
go/buildgo2/asm/default.nix
Normal file
7
go/buildgo2/asm/default.nix
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{ depot, ... }:
|
||||||
|
|
||||||
|
depot.third_party.buildGo2.package {
|
||||||
|
name = "asm";
|
||||||
|
path = "hg.lukegb.com/lukegb/depot/go/buildgo2/asm";
|
||||||
|
srcs = [ ./buildgo2.go ./add.S ];
|
||||||
|
}
|
6
go/buildgo2/cgo/cgo.c
Normal file
6
go/buildgo2/cgo/cgo.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "_cgo_export.h"
|
||||||
|
|
||||||
|
int64_t add(int64_t x, int64_t y) {
|
||||||
|
return AddInternal(x + y, 0);
|
||||||
|
}
|
14
go/buildgo2/cgo/cgo.go
Normal file
14
go/buildgo2/cgo/cgo.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package cgo
|
||||||
|
|
||||||
|
// #include "cgo.h"
|
||||||
|
import "C"
|
||||||
|
|
||||||
|
func Add(x, y int64) int64 {
|
||||||
|
return int64(C.add(C.int64_t(x), C.int64_t(y)))
|
||||||
|
}
|
||||||
|
|
||||||
|
//export AddInternal
|
||||||
|
func AddInternal(x, y int64) int64 {
|
||||||
|
|
||||||
|
return x + y
|
||||||
|
}
|
4
go/buildgo2/cgo/cgo.h
Normal file
4
go/buildgo2/cgo/cgo.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
int64_t add(int64_t x, int64_t y);
|
8
go/buildgo2/cgo/default.nix
Normal file
8
go/buildgo2/cgo/default.nix
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{ depot, ... }:
|
||||||
|
|
||||||
|
depot.third_party.buildGo2.package {
|
||||||
|
name = "cgo";
|
||||||
|
path = "hg.lukegb.com/lukegb/depot/go/buildgo2/cgo";
|
||||||
|
srcs = [ ./cgo.go ./cgo.h ./cgo.c ];
|
||||||
|
cgo = true;
|
||||||
|
}
|
13
go/buildgo2/default.nix
Normal file
13
go/buildgo2/default.nix
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{ depot, ... }@args:
|
||||||
|
|
||||||
|
let
|
||||||
|
asm = import ./asm args;
|
||||||
|
cgo = import ./cgo args;
|
||||||
|
in
|
||||||
|
depot.third_party.buildGo2.program {
|
||||||
|
name = "buildgo2";
|
||||||
|
srcs = [ ./main.go ];
|
||||||
|
deps = [ asm ];
|
||||||
|
} // {
|
||||||
|
inherit asm cgo;
|
||||||
|
}
|
14
go/buildgo2/main.go
Normal file
14
go/buildgo2/main.go
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"hg.lukegb.com/lukegb/depot/go/buildgo2/asm"
|
||||||
|
//"hg.lukegb.com/lukegb/depot/go/buildgo2/cgo"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("hi")
|
||||||
|
fmt.Printf("asm: 2 + 3 = %d\n", asm.Add(2, 3))
|
||||||
|
//fmt.Printf("cgo: 2 + 3 = %d\n", cgo.Add(2, 3))
|
||||||
|
}
|
|
@ -15,4 +15,6 @@ args: {
|
||||||
access = import ./access args;
|
access = import ./access args;
|
||||||
vault = import ./vault args;
|
vault = import ./vault args;
|
||||||
tumblrandom = import ./tumblrandom args;
|
tumblrandom = import ./tumblrandom args;
|
||||||
|
|
||||||
|
buildgo2 = import ./buildgo2 args;
|
||||||
}
|
}
|
||||||
|
|
1
third_party/default.nix
vendored
1
third_party/default.nix
vendored
|
@ -125,6 +125,7 @@ rec {
|
||||||
|
|
||||||
bat_syntaxes = tvlDepot.third_party.bat_syntaxes;
|
bat_syntaxes = tvlDepot.third_party.bat_syntaxes;
|
||||||
cheddar = tvlDepot.tools.cheddar;
|
cheddar = tvlDepot.tools.cheddar;
|
||||||
|
buildGo2 = tvlDepot.nix.buildGo2;
|
||||||
naersk = nixpkgs.callPackage naerskSrc {};
|
naersk = nixpkgs.callPackage naerskSrc {};
|
||||||
|
|
||||||
crate2nix = import "${crate2nixSrc}" { pkgs = ch.depot.pkgs; };
|
crate2nix = import "${crate2nixSrc}" { pkgs = ch.depot.pkgs; };
|
||||||
|
|
241
third_party/tvl/nix/buildGo2/default.nix
vendored
Normal file
241
third_party/tvl/nix/buildGo2/default.nix
vendored
Normal file
|
@ -0,0 +1,241 @@
|
||||||
|
# Copyright 2019 Google LLC.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
# buildGo provides Nix functions to build Go packages in the style of Bazel's
|
||||||
|
# rules_go.
|
||||||
|
|
||||||
|
{ pkgs ? import <nixpkgs> { }
|
||||||
|
, ...
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
inherit (pkgs) lib;
|
||||||
|
|
||||||
|
go = pkgs.go;
|
||||||
|
goStdlib = buildStdlib { inherit go; };
|
||||||
|
|
||||||
|
splitSources = srcs: let
|
||||||
|
# exts: { typeName = [ extension ] };
|
||||||
|
exts = {
|
||||||
|
go = [ ".go" ];
|
||||||
|
asm = [ ".s" ".S" ];
|
||||||
|
headers = [ ".h" ".hh" ".hpp" ".hxx" ".inc" ];
|
||||||
|
c = [ ".c" ];
|
||||||
|
cxx = [ ".cc" ".cxx" ".cpp" ];
|
||||||
|
objc = [ ".m" ".mm" ];
|
||||||
|
};
|
||||||
|
# [ extension ] -> { extension = true; }
|
||||||
|
extListToAttrs = exts: builtins.listToAttrs (builtins.map (v: lib.attrsets.nameValuePair v true) exts);
|
||||||
|
# exts': { typeName = { extension = true; } };
|
||||||
|
exts' = builtins.mapAttrs (_: extListToAttrs) exts;
|
||||||
|
|
||||||
|
allExts = lib.lists.flatten (builtins.attrValues exts);
|
||||||
|
allExts' = extListToAttrs allExts;
|
||||||
|
|
||||||
|
matchesExts = exts: src: let
|
||||||
|
srcExtList = builtins.match ".*([.][^.]+)$" (toString src);
|
||||||
|
srcExt = builtins.elemAt srcExtList 0;
|
||||||
|
in
|
||||||
|
srcExtList != null && exts ? "${srcExt}";
|
||||||
|
splitByExt = exts: builtins.filter (matchesExts exts) srcs;
|
||||||
|
|
||||||
|
leftovers = builtins.filter (src: !(matchesExts allExts' src)) srcs;
|
||||||
|
in assert (lib.assertMsg (builtins.length leftovers == 0) "uncategorisable files: ${toString leftovers}"); builtins.mapAttrs (name: value: splitByExt value) exts';
|
||||||
|
|
||||||
|
importconfig = { name, deps }: let
|
||||||
|
# Go through every dep and generate a packagefile importpath=${output}.
|
||||||
|
depPackagefiles = map (dep: if dep ? importpath then "packagefile ${dep.importpath}=${dep}/pkg.a" else "") deps;
|
||||||
|
in ''
|
||||||
|
# nix buildGo ${name}
|
||||||
|
${builtins.concatStringsSep "\n" depPackagefiles}
|
||||||
|
'';
|
||||||
|
|
||||||
|
buildStdlib = { go }: pkgs.stdenv.mkDerivation {
|
||||||
|
pname = "go-stdlib";
|
||||||
|
inherit (go) version;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ go ];
|
||||||
|
|
||||||
|
unpackPhase = ''
|
||||||
|
HOME=$NIX_BUILD_TOP/home
|
||||||
|
mkdir $HOME
|
||||||
|
|
||||||
|
goroot="$(go env GOROOT)"
|
||||||
|
cp -R "$goroot/src" "$goroot/pkg" .
|
||||||
|
'';
|
||||||
|
dontConfigure = true;
|
||||||
|
buildPhase = ''
|
||||||
|
chmod -R +w .
|
||||||
|
GODEBUG=installgoroot=all GOROOT=$NIX_BUILD_TOP go install -v --trimpath std
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir $out
|
||||||
|
cp -r pkg/*_*/* $out
|
||||||
|
|
||||||
|
find $out -name '*.a' | while read -r ARCHIVE_FULL; do
|
||||||
|
ARCHIVE="''${ARCHIVE_FULL#"$out/"}"
|
||||||
|
PACKAGE="''${ARCHIVE%.a}"
|
||||||
|
echo "packagefile $PACKAGE=$ARCHIVE_FULL"
|
||||||
|
done > $out/importcfg
|
||||||
|
'';
|
||||||
|
dontFixup = true;
|
||||||
|
|
||||||
|
passthru.go = go;
|
||||||
|
};
|
||||||
|
|
||||||
|
package = {
|
||||||
|
name,
|
||||||
|
path,
|
||||||
|
srcs,
|
||||||
|
deps ? [],
|
||||||
|
cgo ? false,
|
||||||
|
cgodeps ? [],
|
||||||
|
go ? goStdlib.go,
|
||||||
|
stdlib ? goStdlib,
|
||||||
|
}@args: assert stdlib != null -> stdlib.go == go; let
|
||||||
|
importcfg = importconfig { inherit name deps; stdlib = go; };
|
||||||
|
|
||||||
|
srcs' = splitSources srcs;
|
||||||
|
stdenv = if cgo then pkgs.stdenv else pkgs.stdenvNoCC;
|
||||||
|
|
||||||
|
cgoSrcs = srcs'.c ++ srcs'.cxx ++ srcs'.objc;
|
||||||
|
noCgoNoC = lib.assertMsg (builtins.length cgoSrcs == 0) "cgo source files present, but cgo not set to true: ${toString cgoSrcs}";
|
||||||
|
|
||||||
|
baseNameOnly = map (f: baseNameOf (toString f));
|
||||||
|
in assert !cgo -> noCgoNoC; stdenv.mkDerivation rec {
|
||||||
|
inherit name;
|
||||||
|
__structuredAttrs = true;
|
||||||
|
|
||||||
|
buildInputs = cgodeps;
|
||||||
|
nativeBuildInputs = [ go ] ++ (if cgo then [ pkgs.pkg-config ] else []);
|
||||||
|
|
||||||
|
passthru = {
|
||||||
|
importpath = path;
|
||||||
|
inherit importcfg stdlib;
|
||||||
|
cgo = cgo || lib.lists.any (x: x.cgo) deps;
|
||||||
|
};
|
||||||
|
|
||||||
|
importcfg = importconfig { inherit name deps; };
|
||||||
|
allSrcs = srcs;
|
||||||
|
goSrcs = baseNameOnly srcs'.go;
|
||||||
|
asmSrcs = baseNameOnly srcs'.asm;
|
||||||
|
cSrcs = baseNameOnly srcs'.c;
|
||||||
|
cxxSrcs = baseNameOnly srcs'.cxx;
|
||||||
|
objcSrcs = baseNameOnly srcs'.objc;
|
||||||
|
|
||||||
|
unpackPhase = ''
|
||||||
|
mkdir src
|
||||||
|
${builtins.concatStringsSep "\n" (map (f: ''
|
||||||
|
cp "${f}" "src/${baseNameOf (toString f)}"
|
||||||
|
'') srcs)}
|
||||||
|
cd src
|
||||||
|
'';
|
||||||
|
configurePhase = ''
|
||||||
|
echo "$importcfg" > $NIX_BUILD_TOP/importcfg
|
||||||
|
${if stdlib != null then ''
|
||||||
|
cat ${stdlib}/importcfg >> $NIX_BUILD_TOP/importcfg
|
||||||
|
'' else ""}
|
||||||
|
for dep in deps; do
|
||||||
|
if [[ ! -f "$dep/importcfg" ]]; then continue; fi
|
||||||
|
cat $dep/importcfg >> $NIX_BUILD_TOP/importcfg
|
||||||
|
done
|
||||||
|
'';
|
||||||
|
buildPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
completeFlag="${if cgo then "" else "-complete"}"
|
||||||
|
outputFlag="-o $out/pkg.a"
|
||||||
|
if [ ''${#asmSrcs[@]} -gt 0 ]; then
|
||||||
|
completeFlag=""
|
||||||
|
mkdir $NIX_BUILD_TOP/pack $NIX_BUILD_TOP/include
|
||||||
|
outputFlag="-symabis $NIX_BUILD_TOP/goasm.abi -o $out/pkg.a -asmhdr $NIX_BUILD_TOP/include/go_asm.h"
|
||||||
|
|
||||||
|
touch $NIX_BUILD_TOP/include/go_asm.h
|
||||||
|
|
||||||
|
ASMCMD="go tool asm -trimpath $NIX_BUILD_TOP/src -I $NIX_BUILD_TOP/include -I $(go env GOROOT)/pkg/include -D GOOS=$(go env GOOS) -D GOOS_$(go env GOOS) -D GOARCH=$(go env GOARCH) -D GOARCH_$(go env GOARCH) -p ${path}"
|
||||||
|
$ASMCMD -gensymabis -o $NIX_BUILD_TOP/goasm.abi "''${asmSrcs[@]}"
|
||||||
|
fi
|
||||||
|
${if cgo then ''
|
||||||
|
mkdir $NIX_BUILD_TOP/cgo $NIX_BUILD_TOP/cgo_built
|
||||||
|
go tool cgo -objdir $NIX_BUILD_TOP/cgo -trimpath $NIX_BUILD_TOP/src -importpath "${path}" -- "''${goSrcs[@]}"
|
||||||
|
for f in "''${cSrcs[@]}"; do
|
||||||
|
$CC -I$NIX_BUILD_TOP/cgo -I. -c "$f" -o "$NIX_BUILD_TOP/cgo_built/''${f}.o"
|
||||||
|
done
|
||||||
|
for f in "''${cxxSrcs[@]}"; do
|
||||||
|
$CXX -I$NIX_BUILD_TOP/cgo -I. -c "$f" -o "$NIX_BUILD_TOP/cgo_built/''${f}.o"
|
||||||
|
done
|
||||||
|
for f in "''${objcSrcs[@]}"; do
|
||||||
|
$OBJC -I$NIX_BUILD_TOP/cgo -I. -c "$f" -o "$NIX_BUILD_TOP/cgo_built/''${f}.o"
|
||||||
|
done
|
||||||
|
pushd $NIX_BUILD_TOP/cgo &>/dev/null
|
||||||
|
for f in *.cgo2.c _cgo_export.c _cgo_main.c; do
|
||||||
|
$CC -I$NIX_BUILD_TOP/src -c "$f" -o ''${f}.o
|
||||||
|
done
|
||||||
|
$CC -o _cgo_.o _cgo_main.c.o _cgo_export.c.o $NIX_BUILD_TOP/cgo_built/*.o *.cgo2.c.o
|
||||||
|
popd &>/dev/null
|
||||||
|
go tool cgo -dynpackage "${name}" -dynimport $NIX_BUILD_TOP/cgo/_cgo_.o -dynout $NIX_BUILD_TOP/cgo/_cgo_imports.go
|
||||||
|
shopt -s nullglob
|
||||||
|
goSrcs=($NIX_BUILD_TOP/cgo/*.go)
|
||||||
|
'' else ""}
|
||||||
|
go tool compile $completeFlag -importcfg $NIX_BUILD_TOP/importcfg -trimpath $NIX_BUILD_TOP/src -pack -p "${path}" $outputFlag "''${goSrcs[@]}"
|
||||||
|
if [ ''${#asmSrcs[@]} -gt 0 ]; then
|
||||||
|
$ASMCMD -o $NIX_BUILD_TOP/pack/goasm.o "''${asmSrcs[@]}"
|
||||||
|
go tool pack r $out/pkg.a $NIX_BUILD_TOP/pack/*.o
|
||||||
|
fi
|
||||||
|
${if cgo then ''
|
||||||
|
go tool pack r $out/pkg.a $NIX_BUILD_TOP/cgo/*.cgo2.c.o $NIX_BUILD_TOP/cgo/_cgo_export.c.o $NIX_BUILD_TOP/cgo_built/*.o
|
||||||
|
'' else ""}
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
program = {
|
||||||
|
name,
|
||||||
|
deps ? [],
|
||||||
|
...
|
||||||
|
}@args: let
|
||||||
|
pkg = package (args // {
|
||||||
|
name = "${name}-lib";
|
||||||
|
path = "main";
|
||||||
|
});
|
||||||
|
cgo = pkg.cgo;
|
||||||
|
stdenv = if cgo then pkgs.stdenv else pkgs.stdenvNoCC;
|
||||||
|
in stdenv.mkDerivation rec {
|
||||||
|
inherit name;
|
||||||
|
__structuredAttrs = true;
|
||||||
|
|
||||||
|
nativeBuildInputs = [ go ];
|
||||||
|
|
||||||
|
lib = pkg;
|
||||||
|
inherit (pkg) importcfg stdlib;
|
||||||
|
|
||||||
|
dontUnpack = true;
|
||||||
|
configurePhase = ''
|
||||||
|
echo "$importcfg" > importcfg
|
||||||
|
${if stdlib != null then ''
|
||||||
|
cat ${stdlib}/importcfg >> importcfg
|
||||||
|
'' else ""}
|
||||||
|
'';
|
||||||
|
buildPhase = ''
|
||||||
|
mkdir out
|
||||||
|
go tool link -importcfg importcfg -tmpdir "$TMPDIR" -o "out/bin" -s -w $lib/pkg.a
|
||||||
|
'';
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
cp out/bin "$out/bin/${name}"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
external = {
|
||||||
|
src,
|
||||||
|
path,
|
||||||
|
deps ? [ ],
|
||||||
|
tags ? [ ],
|
||||||
|
cgo ? false,
|
||||||
|
cgodeps ? [ ],
|
||||||
|
cgocflags ? [ ],
|
||||||
|
cgoldflags ? [ ],
|
||||||
|
}: {};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
#inherit program package proto external;
|
||||||
|
inherit goStdlib package program external;
|
||||||
|
}
|
Loading…
Reference in a new issue