Comment by self_awareness

3 months ago

Tried to use Nim with VBCC to cross-compile to Amiga, but I failed. I think Nim does some pretty heavy assumptions about the C compiler that is used to compile the generated code.

Just in case you aren't in the loop, but there are gcc and llvm based Amiga cross compilers.

  • GCC cross-compiling for the Amiga is available from https://franke.ms/git/bebbo/amiga-gcc for a standalone toolchain, and https://github.com/BartmanAbyss/vscode-amiga-debug for one that requires VSCode.

    I'm not aware of any working LLVM solution? All I know is that LLVM supports MC680x0 as a backend, can spit out 68k-but-non-amiga-objects and some brave souls have trying to use vlink or mold to produce Amiga executables. Have you seen any working LLVM-based Amiga (680x0 in hunk format) cross-compilers in the wild?

  • Actually I wasn't able to do it also with Bebbo's GCC fork.

    Never used Nim before so I might be doing something wrong though.

    I wish retro Amiga had Rust support. I've briefly skimmed what would be necessary to do, based on the rust-mos (Rust for commodore-64 fork), but I'm too weak in LLVM internals to actually do it.

    • > Never used Nim before so I might be doing something wrong though.

      With Nim on weird targets you usually want:

      - OS target = any

      - Memory Management = ARC

      - malloc instead of default Nim allocator

      - turn off signal handler (if not POSIX)

      - disable threads (most of the time)

      Then look at how C is compiled and copy all compiler+linker flags to your Nim configuration. Here's an absolute minimal `config.nims` I used to compile Nim for C64 with LLVM-MOS[1] toolchain:

          import std/strutils
          
          --cc:clang
          --clang.exe:"mos-c64-clang"
          
          --os:any
          --cpu:avr
          --mm:arc
          
          --threads:off
          --define:usemalloc
          --define:noSignalHandler
          
          let args = [
            "-isystem $PWD/../mos-platform/c64/include",
            "-I$PWD/../mos-platform/c64/asminc",
            "-L$PWD/../mos-platform/c64/lib",
            "-mlto-zp=110",
            "-D__C64__",
          
            "-isystem $PWD/../mos-platform/commodore/include",
            "-I$PWD/../mos-platform/commodore/asminc",
            "-L$PWD/../mos-platform/commodore/lib",
            "-D__CBM__",
          
            "-isystem $PWD/../mos-platform/common/include",
            "-I$PWD/../mos-platform/common/asminc",
            "-L$PWD/../mos-platform/common/lib",
            "--target=mos",
            "-flto",
            "-Os",
            ].join(" ")
          
          switch("passC", args)
          switch("passL", args)
      

      Nim side was easy, because I have already compiled Nim to WASM at that point and the flags are similar. Hard part was figuring out the C compiler flags: e.g. cmake structure and why compiler complains about missing symbols, when they're not missing (answer: include/lib order is very important).

      [1] https://github.com/llvm-mos/llvm-mos