/
buildRustPlatform.nix
113 lines (90 loc) · 3.05 KB
/
buildRustPlatform.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
{ mkRocDerivation
, lib
, rustPlatform # from nix not roc...
, llvmPackages_16 # TODO: keep in sync with roc repo
, runCommand
, languageFilters
}:
let
llvmPkgs = llvmPackages_16;
fs = lib.fileset;
in
{ mainFile ? "./main.roc"
, pname
, version
, rustBuildOverrides ? { }
, ...
}@args:
let
cleanedArgs = removeAttrs args [ "mainFile" "rustBuildOverrides" "pname" "version" "src" ];
# TODO: allow just setting name
rustBuildName = "${pname}-${version}-compile-rust";
cBuildName = "${pname}-${version}-compile-c-host";
# rustSrc = let basePath = fs.fromSource args.src; in
# # fs.intersection basePath
# (languageFilters.rustFilter args.src);
# TODO: probably move the rust build itself to diff file...
rustBuildArgs = cleanedArgs // {
src = fs.toSource {
root = args.src; # TODO: would this get sad if the passed in src is the output of a derivation?
fileset = languageFilters.rustFilter args.src;
};
name = rustBuildName;
cargoBuildFlags = [
"--lib"
];
doCheck = false; #TODO: look into not doing this for now....
};
mergedRustArgs = lib.attrsets.recursiveUpdate rustBuildArgs (rustBuildOverrides);
rustBuiltLib = rustPlatform.buildRustPackage mergedRustArgs;
cHostDest = "c_host.o";
compiledC =
llvmPkgs.stdenv.mkDerivation
{
name = cBuildName;
src = fs.toSource {
root = args.src; # TODO: would this get sad if the passed in src is the output of a derivation?
fileset = languageFilters.cFilter args.src;
};
buildPhase = ''
runHook preBuild
# $CC is clang since we are using llvmPkgs.stdenv
# TODO: look into what is -fPIC -c doing....
$CC host.c -o ${cHostDest} -fPIC -c
mkdir -p $out
cp ${cHostDest} $out
runHook postBuild
'';
};
# TODO: need to make a mapping for system to output o file name
# see https://github.com/JRMurr/roc/blob/531af182899835a9298efd758b927e5ba3e2f64a/crates/compiler/build/src/link.rs#L57
# TLDR linux-arm64.o | macos-arm64.o | linux-x64.o | linux-x64.o
# should only really do all of them if making a package for external use
# if only being used in a nix build we can keep it to just the system we are building for
host_dest = "linux-x64.o";
# TODO: expose this somehow so users can override
rocCode = fs.toSource {
root = args.src; # TODO: would this get sad if the passed in src is the output of a derivation?
fileset = languageFilters.rocFilter args.src;
};
linkedCode = llvmPkgs.stdenv.mkDerivation
rec {
name = "${pname}-${version}";
srcs = [
rustBuiltLib
compiledC
];
sourceRoot = ".";
buildPhase = ''
$LD -r -L ${rustBuildName}/lib ${cBuildName}/${cHostDest} -lhost -o ${host_dest}
mkdir -p $out
cp ${host_dest} $out/${host_dest}
cp -r ${rocCode}/. $out
'';
};
in
runCommand "join-roc-code-with-compiled-platform" { } ''
mkdir -p $out
cp ${linkedCode}/${host_dest} $out/${host_dest}
cp -r ${rocCode}/. $out
''