-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Windows 11 bug: Instead of .exe file StaticCompiler.jl creates two files: hello.ll and wrapper.c #158
Comments
I find the same behaviour on Windows 10. StaticCompiler.jl on Windows would be incredibly useful for me. I am not competent to help with compiling, alas. |
The code causing the problem is here, \c should be /c: |
I made the change (on my machine) as @bluebug suggests, and this causes an error (which actually means progress): I assume clang is a C compiler. Do I already have clang installed with Julia and/or StaticCompiler.jl and I need to do something to make CMD know about it, or is clang not a part of the installation, and I have to install clang myself? |
I'm using clang.exe from preinstalled llvm and add "C:\Program Files\LLVM\bin" into windows paths. clang --version
clang version 17.0.6
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin maybe you can find clang.exe from the path "C:\Users\yourname\.julia\artifacts" |
The problem is in the function It is kind of a typo that was unfortunately integrated. |
The clang.exe in the artifacts does not work for Windows, as pointed out in JuliaPackaging/Yggdrasil#8015 |
Hi @Thomas008. First, thank you for developping StaticCompiler, that's a very important work. From JuliaPackaging/Yggdrasil#8015, I get the impression you have a workaround, using a local clang installation. If that is the case, a "how to" (starting from installing clang) would be very valuable. Do you get an executable from releases.llvm.org ? Do we need to install LLVM or just Clang...? |
Hi @PhilippeMaincon However, we want to have repaired the clang in the artifact of the package |
Hello, can i ask, this is not solved yet? I have absolutely same problems on Windows and dont understand what do ;( |
One problem is that on Windows the clang in the artifact of Clang_jll does not work yet. You have to install a clang that works on Windows on your own. Do you have clang? |
We made it! (c)
after it: Pkg.add("StaticCompiler") and may be also StaticTools and: using StaticCompiler, StaticTools will generate u exe near 100kb. Thank u a lot to everyone who made it possible! Can anybody say, how can i compile .jl file? Anthony |
Congratulations!
I don't know, what you mean. In the example you described, you compile the function hello() (that is implemented within some jl-file). |
Belated test(√ passed):
windows 11
julia 1.10.5
StaticCompiler v0.7.2
=============
clang version 18.1.4
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: D:\llvm18\bin using StaticCompiler, StaticTools
hello() = println(c"Hello, world!")
paths = ENV["PATH"] * ";D:\\llvm18\\bin"
withenv("PATH"=>paths) do
compile_executable(hello, (), "./")
end
"E:\\codes\\test\\hello.exe" Additional test(× not passed):
using StaticCompiler, StaticTools
using Clang
hello() = println(c"Hello, world!")
paths = ENV["PATH"] * ";" * Clang.LLVM_DIR * "tools"
withenv("PATH"=>paths) do
compile_executable(hello, (), "./")
end
ERROR: failed process: Process(`clang -Wno-override-module ./wrapper.c ./hello.ll -o ./hello.exe`, ProcessExited(3221225781)) [3221225781] some guesses:
|
Hello! Thank u a lot. my_str="Hello" I ve tested tens of variants with C-like string, memory aloc functions with no luck - Julia is arguing me with symbol outrange error LNK2019: reference to an unresolved external symbol ijl_apply_generic in function julia_println_1162. thank u a lot! |
you should take a look at StaticTools, c"Hello" => StaticTools.@c_str("Hello") => StaticTools.StaticString("Hello"), so you can use StaticTools.@c_str(my_str) or StaticTools.StaticString(my_str). help?> StaticTools.@c_str
@c_str -> StaticString
Construct a StaticString, such as c"Foo".
A StaticString should generally behave like a base Julia String, but is explicitly null-terminated,
mutable, and standalone-StaticCompiler safe (does not require libjulia).
Examples
========
julia> c"Hello there!"
c"Hello there!"
julia> c"foo" == "foo"
true
help?> StaticTools.StaticString
StaticString{N}
A stringy type which should generally behave like a base Julia String, but is explicitly null-terminated,
mutable, and standalone-StaticCompiler safe (does not require libjulia).
Can be constructed with the c"..." string macro.
Unlike base Julia Strings, slicing does not create a copy, but rather a view. You are responsible for
ensuring that any such views are null-terminated if you wish to pass them to any functions (including
most system IO) that expect null-termination.
Indexing a StaticString out of bounds does not throw a BoundsError; much as if @inbounds were enabled,
indexing a StaticString incurs a strict promise by the programmer that the specified index is inbounds.
Breaking this promise will result in segfaults or memory corruption.
Examples
========
julia> s = c"Hello world!"
c"Hello world!"
julia> s[8:12] = c"there"; s
c"Hello there!"
julia> s[1:5]
StringView: "Hello"
julia> s[1:5] == "Hello"
true
julia> StaticString(s[1:5])
c"Hello"
─────────────────────────────────────────────────────────────────────────────────────────────────────────
StaticString{N}(undef)
Construct an uninitialized N-byte StaticString
StaticString(data::NTuple{N,UInt8})
Construct a StaticString containing the N bytes specified by data. To yield a valid string, data must be
null-terminated, i.e., end in 0x00.
StaticString(s::AbstractStaticString)
Construct a StaticString containing the same data as the input string s.
Examples
========
julia> data = (0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x21, 0x00);
julia> s = StaticString(data)
c"Hello world!"
julia> StaticString(s[1:5])
c"Hello" But this is irrelevant to this topic, so this topic should be closed. |
Sorry for offtop, but still no luck ;( |
according to my limited knowledge:
Limitations
GC-tracked allocations and global variables do not work with compile_executable or compile_shlib. This has some interesting consequences, including that all functions within the function you want to compile must either be inlined or return only native types (otherwise Julia would have to allocate a place to put the results, which will fail).
Since error handling relies on libjulia, you can only throw errors from standalone-compiled (compile_executable / compile_shlib) code if an explicit overload has been defined for that particular error with @device_override (see [quirks.jl](https://github.com/tshort/StaticCompiler.jl/blob/master/src/quirks.jl)).
Type instability. Type unstable code cannot currently be statically compiled via this package.
Doesn't work on Windows (but works in WSL on Windows 10+). PRs welcome.
function hello()
c_hello = c"hello "
c_name = c"world"
c_greet = c_hello * c_name
println(c_greet)
end
hello (generic function with 1 method)
julia>
julia> compile_executable(hello, (), "./")
"E:\\codes\\test\\hello.exe" |
The steps mentioned by @bluebug
suggest to me that there is a strong need for two important things:
|
Hello, thank u very mouch for answering! with respect, Anthony |
one test passed, and more info you can find in doc: https://brenhinkeller.github.io/StaticTools.jl/dev/ using StaticCompiler, StaticTools
function add(a, b)
a + b
end
# 1. use StaticTools.printf to replace println, doc: https://brenhinkeller.github.io/StaticTools.jl/dev/#StaticTools.printf-Tuple{MallocString}
# 2. return 0 => pretend to be a C program
function hello()
c_hello = c"hello"
c_name = c"world"
printf(c"%s", c_hello)
printf(c" %s!\n", c_name)
a = 5
b = 6
c = add(a, b)
printf(c"%d\n", c)
return 0
end
compile_executable(hello, (), "./") |
some hack about Clang test and passed, so maybe StaticCompiler can work with Clang/Clang_jll using correct env 😄
[40e3b903] Clang v0.18.3
[81625895] StaticCompiler v0.7.2
[86c06d3c] StaticTools v0.8.10
⌅ [0ee61d77] Clang_jll v15.0.7+10
using StaticCompiler, StaticTools
function add(a, b)
a + b
end
# 1. use StaticTools.printf to replace println, doc: https://brenhinkeller.github.io/StaticTools.jl/dev/#StaticTools.printf-Tuple{MallocString}
# 2. return 0 => pretend to be a C program
function hello()
c_hello = c"hello"
c_name = c"world"
printf(c"%s", c_hello)
printf(c" %s!\n", c_name)
a = 5
b = 6
c = add(a, b)
printf(c"%d\n", c)
return 0
end
using Clang_jll
clang_lib = normpath(joinpath(Clang_jll.PATH[], "..\\bin"))
paths = ENV["PATH"] * ";" * clang_lib * ";" * Clang_jll.PATH[]
withenv("PATH" => paths) do
clang() do clang_exe
compile_executable(hello, (), "./")
end
end
|
Thank u very mouch, now it's fully works!! With respect, Anthony |
Final conclusion, Clang_jll.clang() set paths into env but lost path of clang dlls causing clang.exe crash, so I patch local StaticCompiler.jl and the hello test passed without hack. # file StaticCompiler.jl
...
import Clang_jll # to get some paths from Clang_jll
...
function generate_executable(funcs::Union{Array,Tuple}, path=tempname(), name=fix_name(first(first(funcs))), filename=name;
demangle = true,
cflags = ``,
target::StaticTarget=StaticTarget(),
llvm_to_clang::Bool = Sys.iswindows(),
kwargs...
)
...
if llvm_to_clang # (required on Windows)
# Use clang (llc) to generate an executable from the LLVM IR
cclang = if Sys.iswindows()
exec_path *= ".exe"
# add clang paths into PATH env, so that clang.exe can load dlls from the paths
clang_dlls = normpath(joinpath(Clang_jll.PATH[], "..\\bin"))
clang_libs = Clang_jll.LIBPATH[]
clang_exe = Clang_jll.clang_path
PATH = clang_dlls * ";" * clang_libs * ";" * ENV["PATH"]
setenv(`$clang_exe`,"PATH"=>PATH)
elseif Sys.isapple()
`clang`
else
clang()
end
run(`$cclang -Wno-override-module $wrapper_path $obj_or_ir_path -o $exec_path`)
... |
I tried those workarounds, but get these error: |
@Thomas008 we can find the llvm libs in julia bin path, and libclang libs in Clang.jl bin path. The main reason is that julia> using Clang_jll
julia> clang_lib = normpath(joinpath(Clang_jll.PATH[], "..\\bin"))
"C:\\Users\\***\\.julia\\artifacts\\7d2877da43b3fef993c8488c267bb543f27414f8\\bin"
julia> readdir(clang_lib)
2-element Vector{String}:
"libclang-cpp.dll"
"libclang.dll"
julia> readdir(Sys.BINDIR)
59-element Vector{String}:
......
"libLLVM-15jl.dll"
......
"libstdc++-6.dll"
......
julia> c = Clang_jll.clang();
julia> split(c.env[1],";")
59-element Vector{SubString{String}}:
"PATH=C:\\Users\\***\\AppData\\Local\\julias\\julia-1.10\\bin"
"C:\\Users\\***\\AppData\\Local\\julias\\julia-1.10\\bin\\..\\lib\\julia"
"C:\\Users\\***\\AppData\\Local\\julias\\julia-1.10\\bin\\..\\lib"
"C:\\Users\\***\\AppData\\Local\\julias\\julia-1.10\\bin"
......
julia> split(ENV["PATH"],";")
55-element Vector{SubString{String}}:
...... the fatest patch without touch Clang_jll, just add Clang.jl bin path to cmd env PATH in file StaticCompiler.jl: # file StaticCompiler.jl
...
+ import Clang_jll # to get some paths from Clang_jll
...
function generate_executable(funcs::Union{Array,Tuple}, path=tempname(), name=fix_name(first(first(funcs))), filename=name;
demangle = true,
cflags = ``,
target::StaticTarget=StaticTarget(),
llvm_to_clang::Bool = Sys.iswindows(),
kwargs...
)
...
if llvm_to_clang # (required on Windows)
# Use clang (llc) to generate an executable from the LLVM IR
cclang = if Sys.iswindows()
exec_path *= ".exe"
- `clang`
+ # add clang paths into PATH env, so that clang.exe can load dlls from the paths
+ clang_lib = normpath(joinpath(Clang_jll.PATH[], "..\\bin"))
+ paths = clang_lib * ";" * Clang_jll.PATH[] * ";" * ENV["PATH"]
+ withenv(clang, "PATH" => paths)
elseif Sys.isapple()
`clang`
else
clang()
end
run(`$cclang -Wno-override-module $wrapper_path $obj_or_ir_path -o $exec_path`)
... |
I typed intsructions from readme:
using StaticCompiler, StaticTools
hello() = println(c"Hello, world!")
compile_executable(hello, (), "c:/binary")
The text was updated successfully, but these errors were encountered: