Odin
Odin copied to clipboard
Cannot compile to target windows_i386
Context
Odin: dev-2024-01:5d94887e
OS: Windows 10 Professional (version: 22H2), build 19045.3693
CPU: Intel(R) Core(TM) i5-6300U CPU @ 2.40GHz
RAM: 7591 MiB
Expected Behavior
Odin successfully compile a Windows 32-bit executable.
Current Behavior
Linker complains about unresolved external symbol.
Steps to Reproduce
E:\test>type test.odin
package test
import "core:fmt"
main :: proc() { fmt.println("Hello Odin!") }
E:\test>odin build . -target:windows_i386
libcmt.lib(exe_main.obj) : error LNK2019: unresolved external symbol _main referenced in function "int __cdecl __scrt_common_main_seh(void)" (?__scrt_common_main_seh@@YAHXZ)
E:\test\test.exe : fatal error LNK1120: 1 unresolved externals
Seems like there is a bug in Windows entry point.
when ODIN_ARCH == .i386 || ODIN_NO_CRT {
@(link_name="mainCRTStartup", linkage="strong", require)
mainCRTStartup :: proc "stdcall" () -> i32 {
context = default_context()
#force_no_inline _startup_runtime()
intrinsics.__entry_point()
#force_no_inline _cleanup_runtime()
return 0
}
} else {
@(link_name="main", linkage="strong", require)
main :: proc "c" (argc: i32, argv: [^]cstring) -> i32 {
args__ = argv[:argc]
context = default_context()
#force_no_inline _startup_runtime()
intrinsics.__entry_point()
#force_no_inline _cleanup_runtime()
return 0
}
}
Seems like by default Odin doesn't define main
CRT entry point for 32-bit windows. I'm not sure why i386 was put in here, maybe someone else can explain why it is like that?
@Apis035 does it work if you manually go into that file and remove ODIN_ARCH == .i386
in the when
condition in core/runtime/entry_windows.odin:29
?
yes, it does work when ODIN_ARCH == .i386
is removed
compilation also works without modification to that file when compiling with -no-crt
Tried with -no-crt
as suggested, but the linker spits that __chkstk
is unresolved.
C:\test>type test.odin
package test
import "core:fmt"
main :: proc() { fmt.println("Hello Odin!") }
C:\test>odin build . -target:windows_i386 -no-crt
test.obj : error LNK2019: unresolved external symbol __chkstk referenced in function _reflect.is_enum
C:\test\test.exe : fatal error LNK1120: 1 unresolved externals
Am I missing something?
Removing ODIN_ARCH == .i386
from base/runtime/entry_windows.odin
as originally suggested (not using -no-crt
) compiles
But produces an executable that raises EXCEPTION_ACCESS_VIOLATION (0xC0000005)
In the __init_context
proc @ base/runtime/core.odin
line 676
: https://github.com/odin-lang/Odin/blob/09d7f1337bd8ddccc6b058c3f5752f6365beb31b/base/runtime/core.odin#L676
Which is mov ecx,dword ptr fs:[<__tls_array>]
where global_default_temp_allocator_data
is empty
Using the -default-to-nil-allocator
switch "gets around that" as it sets NO_DEFAULT_TEMP_ALLOCATOR
to true
But then obviously no allocator exists... And not much can be done then...
I suppose something gets completely messed up somewhere and the temp allocator is never created for the main thread... I spent the last 2 hours trying to figure this out but I'm not sure where to go with this now. It seems like this is way above my level, sorry :(