How to compile to stand-alone executable using StaticCompiler in Windows?

Here are some further attempts: I have tried to generate a LLVM IR from a simple C-program (the way (B) Brehnin Keller suggested in the issues of StaticTools
https://github.com/brenhinkeller/StaticTools.jl/issues/20).

I used a simple C program “put.c” that writes an “A” to stdout:

#include <stdio.h>

int main(void) {
   printf("A");
}

Using clang -emit-llvm -S put.c -o put.ll I got the following LLVM IR:

@.str = private unnamed_addr constant [2 x i8] c"A\00", align 1

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
  %1 = call i32 (ptr, ...) @printf(ptr noundef @.str)
  ret i32 0
}

declare dso_local i32 @printf(ptr noundef, ...) #1

attributes #0 = { noinline nounwind optnone uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 2}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"uwtable", i32 2}
!3 = !{i32 1, !"MaxTLSAlign", i32 65536}
!4 = !{!"clang version 17.0.4 (https://github.com/llvm/llvm-project.git 309d55140c46384b6de7a7573206cbeba3f7077f)"}

I put this in a Base.llvmcall() of Julia with some slight adaptions: The constant c"A\00" did not work, Julia came up with some syntax error.
Also with the type ptr an error occurred . So I used i8* instead. The adapted LLVM IR for Julia is the following:

function t()
Base.llvmcall(("""	

; Function Attrs: noinline nounwind optnone uwtable
define dso_local i32 @main() #0 {
%a = alloca i64
store i64 65, i64* %a
  %1 = call i32 (i64*, ...) @printf(i64* noundef %a)
  ret i32 0
}

declare dso_local i32 @printf(i64* noundef, ...) #1

attributes #0 = { noinline nounwind optnone uwtable "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }
attributes #1 = { "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" }

!llvm.module.flags = !{!0, !1, !2, !3}
!llvm.ident = !{!4}

!0 = !{i32 1, !"wchar_size", i32 2}
!1 = !{i32 8, !"PIC Level", i32 2}
!2 = !{i32 7, !"uwtable", i32 2}
!3 = !{i32 1, !"MaxTLSAlign", i32 65536}
!4 = !{!"clang version 17.0.4 (https://github.com/llvm/llvm-project.git 309d55140c46384b6de7a7573206cbeba3f7077f)"}
               """, "main"), Int32, Nothing, Nothing)
end

Then I applied

using StaticTools, StaticCompiler
compile_executable(t,(),"./")

resulting in an object file t.o. After linking with gcc an executable is generated.

gcc wrapper.c t.o -o t.exe

However, the executalbe t.exe did not give an output. The returned error code is “False”.

When applying clang for linking, I got
"t.o unknown file type"

When compiling a function like
t() = getchar()
the generated executable works (expecting an input). Only outputting to stdout or to a file does not work and results in an error. To me, this suggests, that the LLVM IR might be wrong.
Do you have any suggestions how to make the executable could print a string, or how the LLVM IR should look like?

1 Like