Open ShadowElf37 opened 3 years ago
I don't have an Intel Mac to test this on but I think it's safe to say this is an arm64 issue.
I think it is more likely that this is a clang
issue. Can you try --passC:-fno-integrated-as
to see if it solves the issue?
LLVM bug for reference: https://bugs.llvm.org/show_bug.cgi?id=16647
/Library/Developer/CommandLineTools/usr/bin/as: can't specifiy -Q with -arch arm64
clang: error: assembler command failed with exit code 1 (use -v to see invocation)
Error: execution of an external compiler program 'clang -Wa,-acdl=/Users/.../Nim/@mtemplate_test.nim.c.asm -g -fverbose-asm -masm=intel -c -w -ferror-limit=3 -fno-integrated-as -I/usr/local/bin/Nim/lib -I/Users/.../Nim -o /Users/.../Nim/@mtemplate_test.nim.c.o /Users/.../Nim/@mtemplate_test.nim.c' failed with exit code: 1
I guess there are multiple issues here.
It is also happening on my Intel Mac.
When GCC or Clang is used as backend compiler with --asm
option, Nim always call it with "-Wa,-acdl=$asmfile -g -fverbose-asm -masm=intel"
flags.
(Search produceAsm
or optProduceAsm
in compiler/extccomp.nim
)
-Wa,option
-acdl=$asmfile
as
in binutils that is called from GCC-masm=intel
gcc: error: unrecognized command-line option ‘-masm=intel’
on raspberry Pi.-Wa,-acdl=$asmfile
passes -acdl=$asmfile
to the assembler used by GCC or Clang.
If your clag uses integrated assembler or an assembler other than binutils, -acdl
option can cause error as they doesn't support it.
It seems GCC calls as
in binutils in most of system.
Clang uses LLVM’s integrated assembler on all targets where it is supported.
And it uses the system assembler instead of it with -fno-integrated-as
option.
https://clang.llvm.org/docs/Toolchain.html#assembler
Producing assembler code with -S
option might be easier because it works regardless of the assembler GCC/Clang uses.
But, -S
option stop compilation without calling assembler.
So if you want --asm
produces both assembler code and an executable, Nim has to call backend compiler twice, for producing an assembler code and for producing an object file.
I cannot find any options in LLVM's integrated assembler that can produce both an assembler code and an object file like -acdl
option in binutil's as.
There is another problem when LTO is enabled. When LTO is enabled, the flag to produce a assembly code needs to be set at link time. https://stackoverflow.com/questions/58635734/getting-assember-output-from-gcc-clang-in-lto-mode
I wrote workarounds using --passC
and --passL
options:
https://internet-of-tomohiro.netlify.app/nim/faq.en.html#nim-compiler-how-to-produce-assembler-codeqmark
Possible solutions:
--asm
option produces assembler code but doesn't produce an executable
-S
option to produce assembler code so that we can get it without knowing which assembler is usedcompiler/extccomp.nim
--asm
option must produces both assembler code and an executable
Run GCC or Clang twice for producing an assembler code and for producing an object file
More additional code to compiler/extccomp.nim
Or ask Clang developers to add options that can produce both an assembler code and an executable
I think 1 is better.
I don't think --asm
option doesn't need to produce an executable.
Full error
It didn't actually affect anything when I changed or removed the value during testing, but
-masm=intel
is an odd flag to have on arm64. Not sure if that's intentional.I confirmed
--asm
works on Windows.I don't have an Intel Mac to test this on but I think it's safe to say this is an arm64 issueConfirmed broken on x86 as well, although there may be deeper issues on arm64 (see comments).Possible solution
I am by no means qualified to say whether this is the correct solution, but I played around a bit with the command and got this working:
Unfortunately this doesn't also produce the .o file, which I believe is the intended behavior. Although, if you're passing
--asm
, it's probably because you don't care about the .o file that much.