HaxeFoundation / hxcpp

Runtime files for c++ backend for haxe
Other
298 stars 191 forks source link

error LNK2019: unresolved external symbol: `struct hx::TLSData<struct hx::StackContext,1>hx::tlsStackContext`, ` __imp_MessageBoxA referenced in function "void __cdecl hx::CriticalErrorHandler` #963

Open GavinRay97 opened 3 years ago

GavinRay97 commented 3 years ago

Tried to download Haxe to experiment and see what the story was like for using it to author libraries which expose C ABIs + interop with C/C++:

C:\Users\rayga\tmp\haxe\cpp>haxe --version
4.3.0-rc.1+3cb7fe4

Compiled the following file:

class Example {
    static function main():Void {
        trace("hello world");
    }
}

To C++ using:

-main Example
-cpp cpp/
-D static_link
-D HXCPP_VERBOSE=1
-D HXCPP_M64
# Also tried:
# -D mingw
# -D MINGW_ROOT=<mingw root path>

And then to test this, I wanted to try to it out by calling:

// cl.exe test.cpp -I"C:/HaxeToolkit/haxe/lib/hxcpp/4,2,1/include"
// clang-cl.exe test.cpp -I"C:/HaxeToolkit/haxe/lib/hxcpp/4,2,1/include"
#include <iostream>
#include "./HxcppConfig-19.h"

#pragma comment(lib, "libExample.lib")
#include "./include/Example.h"

extern "C" const char *hxRunLibrary();
extern "C" void hxcpp_set_top_of_stack();

int main() {
  using namespace std;

  hxcpp_set_top_of_stack();
  const char *err = hxRunLibrary();
    if (err) {
        cout << "Error: " << err << endl;
        return -1;
    }

  cout << "Making new Example from Haxe" << endl;
  auto example = new Example_obj();

  cout << "Calling Example.main()" << endl;
  example->main();

  cout << "Finished" << endl;
  return 0;
}

But on compilation, this gives ☹️

test-ce60cd.obj : error LNK2019: unresolved external symbol
"struct hx::TLSData<struct hx::StackContext,1> hx::tlsStackContext"
(?tlsStackContext@hx@@3U?$TLSData@UStackContext@hx@@$00@1@A)
referenced in function "public: static void * __cdecl hx::Object::operator new(unsigned __int64,bool,char const *)" (??2Object@hx@@SAPEAX_K_NPEBD@Z)

libExample.lib(b976ba10_Debug.obj) : error LNK2019: unresolved external symbol
__imp_MessageBoxA
referenced in function "void __cdecl hx::CriticalErrorHandler(class String,bool)" (?CriticalErrorHandler@hx@@YAXVString@@_N@Z)

test.exe : fatal error LNK1120: 2 unresolved externals
clang-cl: error: linker command failed with exit code 1120 (use -v to see invocation)
GavinRay97 commented 3 years ago

This is the same when compiling with GCC 11/MINGW, the errors are ver-batim identical to the ones in this issue. Which unfortunately never had a resolution posted 😢

c:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.0.1/../../../../x86_64-w64-mingw32/bin/ld.exe:
    C:\Users\rayga\AppData\Local\Temp\ccZJoPcK.o:test.cpp:
(.rdata$.refptr._ZN2hx15tlsStackContextE[.refptr._ZN2hx15tlsStackContextE]+0x0): undefined reference to `hx::tlsStackContext`

c:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.0.1/../../../../x86_64-w64-mingw32/bin/ld.exe:
     C:\Users\rayga\AppData\Local\Temp\ccZJoPcK.o:test.cpp:
(.rdata$.refptr._ZN2hx7gMarkIDE[.refptr._ZN2hx7gMarkIDE]+0x0): undefined reference to `hx::gMarkID`

c:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.0.1/../../../../x86_64-w64-mingw32/bin/ld.exe: 
    C:\Users\rayga\AppData\Local\Temp\ccZJoPcK.o:test.cpp:
(.rdata$.refptr._ZN2hx20gMarkIDWithContainerE[.refptr._ZN2hx20gMarkIDWithContainerE]+0x0): undefined reference to `hx::gMarkIDWithContainer`

c:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.0.1/../../../../x86_64-w64-mingw32/bin/ld.exe: 
    C:\Users\rayga\AppData\Local\Temp\ccZJoPcK.o:test.cpp:
(.rdata$.refptr._ZN2hx15gImmixStartFlagE[.refptr._ZN2hx15gImmixStartFlagE]+0x0): undefined reference to `hx::gImmixStartFlag`
haxiomic commented 3 years ago

To answer this a little – you don't want to include the hxcpp generated header files directly, so the error is caused by #include "./include/Example.h". This isn't an issue in hxcpp, but there's an argument to be made that documentation could improve because this is a common error

To use generated hxcpp code externally, you need to tell hxcpp specifically to generate a header suitable to be used this way – this is what @:nativeGen is for: test/extern-lib/api/HaxeApi.hx. Which enables you to expose simple classes

hughsando commented 3 years ago

The MessageBox error can be fixed by linking your application against the standard windows library User32.lib, like with your pragma link.

It looks like struct TLSData in include/hx/Tls.h might be missing a "HXCPP_EXTERN_CLASS_ATTRIBUTES" define inserted before its declaration, and same for 'DECLARE_FAST_TLS_DATA(StackContext, tlsStackContext);' in Immix.cpp