Odin icon indicating copy to clipboard operation
Odin copied to clipboard

Cannot compile to target windows_i386

Open Apis035 opened this issue 1 year ago • 6 comments

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

Apis035 avatar Jan 13 '24 03:01 Apis035

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?

flysand7 avatar Jan 13 '24 09:01 flysand7

@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?

flysand7 avatar Jan 13 '24 09:01 flysand7

yes, it does work when ODIN_ARCH == .i386 is removed

Apis035 avatar Jan 13 '24 11:01 Apis035

compilation also works without modification to that file when compiling with -no-crt

Apis035 avatar Jan 13 '24 11:01 Apis035

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?

PogoRollo avatar Mar 24 '24 00:03 PogoRollo

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 :(

PogoRollo avatar Mar 24 '24 02:03 PogoRollo