Linux Support

I know that the compiler right now only supports Windows, but I was wondering when you expect cross-platform usage to appear on the roadmap.

Right now I've forked the repo and it almost runs (the gb_thread_current_id function segfaults), but I'm not sure if it would be wise to continue working on cross-platform support right now.

Have the platform-specific portions of the compiler and/or standard library started to slow down in terms of giant, sweeping changes? If so, I'll continue working to get this language working on MacOS and Linux.
Hello zangent,

I want Linux and OS X support Soon™ however, it does mean I will need to make sure the compiler works on more platforms. This project is mostly me on my own and if I want to support other platforms sooner, I would likely need some help.

I think the Linux and OS X version should require the user to have clang installed and compile through that. (Eventually I would like to completely replace clang but that's a different story and requires some explanation as to why and how).

That being said, I'm not desperate for a *nix version yet as I more concerned with getting the core language developed and working without worrying about other OSes. But if you (or others) would like to get the compiler working on other platforms, please do so :D


- Bill
I would not be disappointed if someone got it working in Linux :-)
So, I have MacOS working as far as I can tell (Hello World), but Linux is proving difficult. It seems that between the symbols 'main' and '.__$startup_runtime', there is a segmentation fault from trying to access the memory address at 0x1.

Do you have any idea why it's doing that? I'm utterly baffled.

Here's the repo I'm working on.

I don't think it's necessarily a platform issue. Well, obviously it is because it only happens on Linux, but it is manifesting itself as more of a compiler bug (maybe?) rather than a platform layer issue.

I'm fairly familiar with Linux and MacOS, but when it gets to executable files and the like I am completely lost.

Thanks!

Edited by Zachary Pierson on
I could work around the segmentation fault by changing "gs" in line 4686
1
__asm__("mov %%gs:0x10,%0" : "=r"(thread_id));
to "fs"
1
__asm__("mov %%fs:0x10,%0" : "=r"(thread_id));
which looks like it was wrongly copied from this thread: https://hero.handmade.network/forums/code-discussion/t/831

But with this change I could not do something useful with the compiler, all I got was:
1
2
$> ./odin run code/test.odin 
build.c:155 | Link value: "/path/to/Odin/odin"
and it seems that no code is executed (but maybe I am doing something wrong here).
Are you building from Bill's source or mine?

Mine builds perfectly fine. The issue is in running the produced executable.

I think your issue may have something to do with the "run" command. I haven't tried that yet; I've been running it like this:

1
2
3
4
5
6
$> ./build.sh
#             [Warnings galore, but it compiles fine.]
$> ./odin build code/test.odin
#             [Info about what libraries are used. This is for a TODO]
$> ./code/test.bin
#             [Segmentation Fault]

Edited by Zachary Pierson on
If the compiled executable crashes, I probably have a runtime error going on. It could be caused by the generated LLVM code or somewhere in _preload.odin et al.

Thank you all for trying :D
Do you have any clue where the issue might reside? If so, I'll start poking around and see if I can track down the issue. I'm not too familiar with the process of compiling with LLVM as a backend, so I don't know where the problem could be.
1
2
$> ./test.bin 
hello, world!

Success!

I uncommented/deleted the line
1
store %..string zeroinitializer, %..string* %0
in "@main()" in "test.ll" and recompiled everything with
1
2
llc test.ll -filetype=obj
clang test.o -o test.bin
and that makes it executable.

Somehow this line is the culprit, I deleted this line in demo001 too and could run it afterwards.
It's even simpler than that. Just the act of linking it with clang is enough to make it to work.

1
2
3
4
./odin build code/test.odin
clang code/test.o -o code/test.bin
./code/test.bin
 > hello, world!


I'll just make it link with clang until I can figure out how to make ld function properly. Ld is better in this scenario, but clang and gcc use black magic to determine all of the needed linker flags, and that's just something I'm not in the business of making. Plus, this works fine!

Super big edit:

Changes are pushed, my fork now compiles on (hopefully still) Windows, MacOS, and Linux

Edited by Zachary Pierson on
Removing that line shouldn't be the cause of the problem unless there's something else is going on.

1
store %..string zeroinitializer, %..string* %0


All that line does is zero out that stack variable.

Edited by Ginger Bill on
That was what what caused the segfault, but it was a signal of a deeper issue.

The program wasn't being linked to the *entire* C runtime library. As it turns out, linking with ld on Linux is not an easy task. The fix was to call clang with the .o file and let it call the linker.

A more complete solution would be nice, but it's a giant can of worms that doesn't make sense to open right now, so the compiler just calls 'clang code/test.o -o code/test' and it seems to work.
<rant>
Wow. LLVM is starting to look less appealing by the day. This isn't the first problem I've encountered with it. LLVM IR is not well designed at all and is highly reliant on many its assumptions (e.g. C-like language, will use the entire LLVM ecosystem, etc.)

My biggest problem with LLVM IR's design is that it is an infinite amount of registers (SSA) but more importantly, infinite width registers. It because of the latter design choice that LLVM IR cannot be lowed to a lower level bytecode or assembly without another intermediate representation. This makes the compiler fundamentally slow.
</rant>

Now this may sound crazy but I hope to completely remove LLVM as the backend (or allow it as an option for users if they want it). Other than being crazy in design, LLVM takes over 80% of the total compilation time (even with no little optimizations) so even if you want an unoptimized build quickly, that's not going to happen.

I should probably write up this proposal and explain what is going to be needed to get this done but luckily, I need to head in this direction to get the compile time execution system working.


P.S. I do understand many of the design decision for LLVM IR and compromises they have had to do but I still don't like it :P
I know nothing about it, so I'm curious what others' thoughts are on Firm
<myrant>I have used LLVM before a lot, and I like it a lot :)</rant>

But you need to remember that LLVM was made primarily for clang (initially it was for Java, but that didn't go anywhere). So obviously it has bunch C like assumptions. That is a well known fact.

And yes, compiler is slow. That's why its so good. It definitely could be made faster, but then it won't be so good and people won't like it.

If you want to switch to different codegen, I can recommend looking into QBE: https://c9x.me/compile/
It's not as good as LLVM, but it gets there 90% or so. It is used in suckless C compiler: http://git.suckless.org/scc/

Edited by Mārtiņš Možeiko on