Linker error and obfuscated name: Part II

I reproduced your example, and it looks like we are forgetting to export RTTI with dllexport in Itanium. We only export the vtable. This is what each compiler exports for ex_xml_exception.obj:

$ dumpbin -directives ex_xml_exception.clang.obj | grep -export:_ZT | c++filt --no-strip-underscore
-export:virtual thunk to ex_xml_exception::~ex_xml_exception()
-export:virtual thunk to ex_xml_exception::~ex_xml_exception()
-export:vtable for ex_xml_exception,data

$ dumpbin -directives ex_xml_exception.gcc.obj | grep -export:_ZT | c++filt --no-strip-underscore

-export:typeinfo for ex_exception,data
-export:typeinfo for ex_xml_exception,data
-export:construction vtable for ex_exception-in-ex_xml_exception,data
-export:VTT for ex_xml_exception,data
-export:vtable for ex_xml_exception,data
-export:virtual thunk to ex_xml_exception::~ex_xml_exception()
-export:virtual thunk to ex_xml_exception::~ex_xml_exception()

In your previous example where the whole class wasn’t exported, I think we might be doing the wrong thing when the key function is dllimport / dllexport. We think that it will provide exported symbols for vtables and RTTI but it doesn’t. This is something we didn’t run into because the MSVC ABI doesn’t have key functions.

Hm, GCC never tries to import RTTI, so maybe it makes sense that we never export it. Anyway, there’s a bug here. Maybe David knows what’s up.

Hm, GCC never tries to import RTTI, so maybe it makes sense that we
never export it. Anyway, there's a bug here. Maybe David knows what's up.

I appreciate that you are looking at this problem. One way or another, either exporting/importing individual member functions or exporting/importing a class as a whole, clang on Windows targeting gcc needs to work so that functionality in a DLL can be used by another module.

Hm, GCC never tries to import RTTI, so maybe it makes sense that we
never export it. Anyway, there's a bug here. Maybe David knows what's up.

I tried this simple example:

// ex_aclass.hpp

#ifndef EX_ACLASS_HPP
#define EX_ACLASS_HPP
#if defined(BLD_EX_EXAMPLE)
    #define EX_DECL __attribute__((__dllexport__))
#else
  #define EX_DECL __attribute__((__dllimport__))
#endif
class EX_DECL ex_aclass
{
public:
     int a_function(long);
};
#endif // EX_ACLASS_HPP

// ex_aclass.cpp

#define BLD_EX_EXAMPLE
#include "ex_aclass.hpp"
int ex_aclass::a_function(long amt)
  {
  return(amt > 1000000 ? 10 : 20);
  }

// Compile ex_aclass

clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o "ex_aclass.obj" "ex_aclass.cpp"

// Link to ex_ac dll

clang++.exe -o "ex_ac.dll" -Wl,-soname -Wl,ex_ac.dll -shared -Wl,--start-group "ex_aclass.obj" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32

// ex_use_aclass.cpp

#include "ex_aclass.hpp"
int main(int argc,char * argv)
  {
  ex_aclass aclass;
  int ret(aclass.a_function(10000));
  return ret;
  }

// Compile ex_use_aclass

clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline -Wall -g -march=i686 -m32 -o "ex_use_aclass.obj" "ex_use_aclass.cpp"

// Link ex_use_ac executable

clang++.exe -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o "ex_use_ac.exe" -Wl,--start-group "ex_use_aclass.obj" "ex_ac.dll" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32

All of this worked with no problems.

So the basic ability to access functionality in a class in a DLL from outside that DLL works fine using clang on Windows. It is something specific in my original example below that is causing linking problems, whether I export entire classes or whether I export individual member functions. Just thought I would let you know. Needless to say I need to solve my original problem because that code mimics the design of a very small portion of the Boost serialization library and is the cause why the Boost serialization library will not build with clang on Windows targeting gcc.

Prior to the change in the LLVM mailing lists, carried out on 08/04, I was able to post messages to the mailing list directly through the gmane gmane.comp.compilers.clang.devel newsgroup interface. After the change to the mailing lists any message I send via the gmane interface is lost.

Can this be fixed somehow ?

It is a convenience, which I appreciate, to use gmane rather than posting to the mailing list address.

Hm, GCC never tries to import RTTI, so maybe it makes sense that we
never export it. Anyway, there's a bug here. Maybe David knows what's up.

I tried this simple example:

// ex_aclass.hpp

#ifndef EX_ACLASS_HPP
#define EX_ACLASS_HPP
#if defined(BLD_EX_EXAMPLE)
        #define EX_DECL __attribute__((__dllexport__))
#else
        #define EX_DECL __attribute__((__dllimport__))
#endif
class EX_DECL ex_aclass
{
public:
    int a_function(long);
};
#endif // EX_ACLASS_HPP

// ex_aclass.cpp

#define BLD_EX_EXAMPLE
#include "ex_aclass.hpp"
int ex_aclass::a_function(long amt)
        {
        return(amt > 1000000 ? 10 : 20);
        }

// Compile ex_aclass

clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline -Wall
-g -march=i686 -m32 -o "ex_aclass.obj" "ex_aclass.cpp"

// Link to ex_ac dll

clang++.exe -o "ex_ac.dll" -Wl,-soname -Wl,ex_ac.dll -shared
-Wl,--start-group "ex_aclass.obj" -Wl,-Bstatic -Wl,-Bdynamic
-Wl,--end-group -g -march=i686 -m32

// ex_use_aclass.cpp

#include "ex_aclass.hpp"
int main(int argc,char * argv)
        {
        ex_aclass aclass;
        int ret(aclass.a_function(10000));
        return ret;
        }

// Compile ex_use_aclass

clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline -Wall
-g -march=i686 -m32 -o "ex_use_aclass.obj" "ex_use_aclass.cpp"

// Link ex_use_ac executable

clang++.exe -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o "ex_use_ac.exe"
-Wl,--start-group "ex_use_aclass.obj" "ex_ac.dll" -Wl,-Bstatic
-Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32

All of this worked with no problems.

So the basic ability to access functionality in a class in a DLL from
outside that DLL works fine using clang on Windows. It is something
specific in my original example below that is causing linking problems,
whether I export entire classes or whether I export individual member
functions. Just thought I would let you know. Needless to say I need to
solve my original problem because that code mimics the design of a very
small portion of the Boost serialization library and is the cause why the
Boost serialization library will not build with clang on Windows targeting
gcc.

Should be fixed in r244266.

        Hm, GCC never tries to import RTTI, so maybe it makes sense that we
        never export it. Anyway, there's a bug here. Maybe David knows
        what's up.

    I tried this simple example:

    // ex_aclass.hpp

    #ifndef EX_ACLASS_HPP
    #define EX_ACLASS_HPP
    #if defined(BLD_EX_EXAMPLE)
             #define EX_DECL __attribute__((__dllexport__))
    #else
             #define EX_DECL __attribute__((__dllimport__))
    #endif
    class EX_DECL ex_aclass
    {
    public:
         int a_function(long);
    };
    #endif // EX_ACLASS_HPP

    // ex_aclass.cpp

    #define BLD_EX_EXAMPLE
    #include "ex_aclass.hpp"
    int ex_aclass::a_function(long amt)
             {
             return(amt > 1000000 ? 10 : 20);
             }

    // Compile ex_aclass

    clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline
    -Wall -g -march=i686 -m32 -o "ex_aclass.obj" "ex_aclass.cpp"

    // Link to ex_ac dll

    clang++.exe -o "ex_ac.dll" -Wl,-soname -Wl,ex_ac.dll -shared
    -Wl,--start-group "ex_aclass.obj" -Wl,-Bstatic -Wl,-Bdynamic
    -Wl,--end-group -g -march=i686 -m32

    // ex_use_aclass.cpp

    #include "ex_aclass.hpp"
    int main(int argc,char * argv)
             {
             ex_aclass aclass;
             int ret(aclass.a_function(10000));
             return ret;
             }

    // Compile ex_use_aclass

    clang++.exe -c -x c++ -D__MINGW_FORCE_SYS_INTRINS -O0 -g -fno-inline
    -Wall -g -march=i686 -m32 -o "ex_use_aclass.obj" "ex_use_aclass.cpp"

    // Link ex_use_ac executable

    clang++.exe -Wl,-R -Wl,"." -Wl,-rpath-link -Wl,"." -o
    "ex_use_ac.exe" -Wl,--start-group "ex_use_aclass.obj" "ex_ac.dll"
    -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32

    All of this worked with no problems.

    So the basic ability to access functionality in a class in a DLL
    from outside that DLL works fine using clang on Windows. It is
    something specific in my original example below that is causing
    linking problems, whether I export entire classes or whether I
    export individual member functions. Just thought I would let you
    know. Needless to say I need to solve my original problem because
    that code mimics the design of a very small portion of the Boost
    serialization library and is the cause why the Boost serialization
    library will not build with clang on Windows targeting gcc.

Should be fixed in r244266.

I got the latest llvm/clang and rebuilt clang. Now for my simple example above, which previously built without any errors, I get when just linking the shared library:

clang++.exe -o "ex_ac" -Wl,-soname -Wl,ex_ac.dll -shared -Wl,--start-group "ex_aclass.obj" -Wl,-Bstatic -Wl,-Bdynamic -Wl,--end-group -g -march=i686 -m32

C:\Utilities\mingw-w64\i686-5.1.0-posix-dwarf-rt_v4-rev0\mingw32\i686-w64-mingw32\lib/libmingw32.a(lib32_libmingw32_a-pseudo-reloc.o):pseudo-reloc.c:(.text+0x1d6): undefined reference to `__chkstk_ms'
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)

I do not know if r244266 is responsible for this but the latest clang on Windows targeting gcc has an even more serious problem now when trying to build a dll. In fac every attempt to link a shared library now gets this error regarding 'undefined reference to `__chkstk_ms'.

You'll probably need to contact gmane and ask them to update the email
addresses they use. http://gmane.org/contact.php

- Hans