I’m learning about LLVM and found the video Lauding a Language is Very Mid by Sheafification of G on YouTube, and I’m trying to reproduce initially the “Compiling our example” section.
This LLVM IR code is in square.ll:
define i64 @main(i64 %argc, ptr %argv) {
%has_int = icmp eq i64 %argc, 2
br i1 %has_int, label %compute_square, label %error
error:
call i32 @puts(ptr @error.msg)
ret i64 1
compute_square:
; char **x.offset = &argv[1]
; char * x.ptr = *x.offset
%x.offset = getelementptr ptr, ptr %argv, i64 1
%x.ptr = load ptr, ptr %x.offset
%x = call i64 @strtoull(ptr %x.ptr, ptr null, i32 10)
%x.sqr = mul i64 %x, %x
call i32 (ptr, ...) @printf(ptr @print.i64, i64 %x.sqr)
ret i64 0
}
@error.msg = private constant [21 x i8] c"Expected an integer.\00"
@print.i64 = private constant [6 x i8] c"%llu\0A\00"
declare i64 @strtoull(ptr, ptr, i32)
declare i32 @puts(ptr)
declare i32 @printf(ptr, ...)
I started with a temporary shell, in which I could get to the object code:
$ nix-shell -p llvm lld
[nix-shell]$ opt -O3 square.ll -S -o square.opt.ll
[nix-shell]$ llc -O3 square.opt.ll -filetype=obj -o square.o
[nix-shell]$ ls
square.ll square.o square.opt.ll
But then, G uses the linker and points to the c runtime:
gg@ubuntu:~$ ld.lld square.o /lib/x86_64-linux-gnu/crt1.o -L /lib/x86_64-linux-gnu/ -lc -o square.out
Of course, this file isn’t there in NixOs, so I created this shell.nix to find it:
$ cat shell.nix
with import <nixpkgs> {};
mkShell {
NIX_LD_LIBRARY_PATH = lib.makeLibraryPath [
stdenv.cc.cc
openssl
];
packages = with pkgs; [
bat
libllvm
llvmPackages.bintools
];
NIX_LD = lib.fileContents "${stdenv.cc}/nix-support/dynamic-linker";
FOO_VAR = stdenv.cc;
}
$ nix-shell
[nix-shell:~]$ echo $NIX_LD
/nix/store/wb6rhpznjfczwlwx23zmdrrw74bayxw4-glibc-2.42-47/lib/ld-linux-x86-64.so.2
[nix-shell:~]$ ld.lld square.o /nix/store/wb6rhpznjfczwlwx23zmdrrw74bayxw4-glibc-2.42-47/lib/crt1.o -lc -o square.o
As you can see, I got it to work by copying the directory where $NIX_LD is located to point to crt1.o. Also -lc in this shell took care of the location of -L /lib/x86_64-linux-gnu/ by itself apparently.
How can I get the actual path to crt1.o into my shell.nix? Can this shell be further improved?