nim-lang / Nim

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula. Its design focuses on efficiency, expressiveness, and elegance (in that order of priority).
https://nim-lang.org
Other
16.28k stars 1.46k forks source link

[low priority] Display warning/error when `importcpp` used in `cc` mode #12002

Open awr1 opened 4 years ago

awr1 commented 4 years ago

{.emit: """/*TYPESECTION*/
class Foo {
public:
  Foo(): x(5) {}
  Foo(float x_): x(x_) {}
  float x;
};
""".}

type Foo {.importcpp: "Foo", nodecl.} = object
  x: cfloat

This runs correctly in cpp mode, but doesn't in cc mode, which is to be expected, but the error is not straightforward:

Hint: used config file '/home/awr/Git/nim/config/nim.cfg' [Conf]
Hint: used config file '/home/awr/Git/nim/config/config.nims' [Conf]
Hint: system [Processing]
Hint: widestrs [Processing]
Hint: io [Processing]
Hint: cpp [Processing]
/home/awr/Development/nimtests/cpp.nim(11, 6) Hint: 'Foo' is declared but not used [XDeclaredButNotUsed]
Hint:  [Link]
/usr/bin/ld: /home/awr/.cache/nim/cpp_d/cpp.nim.cpp.o: in function `PreMain()':
cpp.nim.cpp:(.text+0x45): undefined reference to `systemDatInit000()'
/usr/bin/ld: cpp.nim.cpp:(.text+0x56): undefined reference to `systemInit000()'
/usr/bin/ld: /home/awr/Development/nimtests/cpp: hidden symbol `_Z13systemInit000v' isn't defined
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status
Error: execution of an external program failed: 'g++   -o /home/awr/Development/nimtests/cpp  /home/awr/.cache/nim/cpp_d/stdlib_system.nim.c.o /home/awr/.cache/nim/cpp_d/cpp.nim.cpp.o    -ldl'

Also I find it curious is why g++ is getting shelled-out even though it should be calling the C compiler.

timotheecour commented 4 years ago

Also I find it curious is why g++ is getting shelled-out even though it should be calling the C compiler.

while i was working on #12144 I noticed why this is the case:

if c.config.cmd == cmdCompileToC:
    let m = s.getModule()
    incl(m.flags, sfCompileToCpp)
  incl c.config.globalOptions, optMixedMode

however the logic seems buggy currently and might explain undefined reference tosystemDatInit000()` : see my note in https://github.com/nim-lang/Nim/pull/12144#issuecomment-528656549 hopefully it explains what's going on.

To make this all work (including supporting exportcpp with nim c), the correct fix would involve making sure all the cgen.requiresExternC calls are made after all calls to processImportCpp in a given module, so that sfCompileToCpp takes effect consistently for all declarations in that module