LTO和虚拟析构函数古怪c ++

时间:2013-10-25 15:29:54

标签: c++ optimization gcc virtual-destructor lto

在使用GCC 4.8.1编译/链接LTO时,我遇到了问题。我得到了DLL中符号的未定义引用,即使它们似乎存在。奇怪的是,如果没有启用LTO,它将成功编译和链接。当有一个尚未在派生类中定义的虚析构函数时,LTO似乎很难。

  • 删除DECLSPEC使其可以编译并使用LTO。
  • 依赖步行者显示符号在那里。链接时间优化器似乎无法找到它们。
  • 在派生类Test中声明任何类型的析构函数使其有效。
  • 删除LTO优化也使其成功运行,我想知道为什么这是一个问题。

Test是一个共享库,指向共享库的主链接。

Test.h

#include <string>

#ifdef SOURCE
    #define DECL __declspec(dllexport)
    #warning Exporting!
#else 
    #define DECL __declspec(dllimport)
    #warning Importing!
#endif

class DECL TestBase
{
public:
    TestBase(const std::string testing);
    virtual ~TestBase();

    std::string getTesting();

private:
    std::string _testing;
};

class DECL Test : public TestBase
{
public:
    Test(const std::string testing);
    //~Test(); //removing causes a linker error with LTO! Fine without LTO.
};

Test.cpp的

#include "Test.h"

TestBase::TestBase(const std::string testing)
{
    _testing = testing;
}

TestBase::~TestBase()
{
}

std::string TestBase::getTesting()
{
    return _testing;
}

Test::Test(const std::string testing) :
    TestBase(testing)
{
}

/*Test::~Test() //removing causes a linker error with LTO! Fine without LTO.
{
}*/

Main.cpp的

#include "Test.h"
#include <iostream>

int main()
{
    Test test("testing!");

    std::cout << test.getTesting() << std::endl;

    return 0;
}

请原谅我凌乱的makefile ..

CC=g++
LD=g++

LIBCFLAGS= -O3 -march=pentium4 -mfpmath=sse -flto -fuse-linker-plugin 
LIBEXTRA= -c -DSOURCE
LIBLDFLAGS= ${LIBCFLAGS} -shared
LIBSOURCES=Test.cpp
LIBRARY=Test.dll

EXECFLAGS= -O3 -march=pentium4 -mfpmath=sse -flto -fuse-linker-plugin
EXTRA= -c
EXELDFLAGS= ${EXECFLAGS} -L. -lTest
SOURCES=Main.cpp
EXECUTABLE=main

LIBOBJECTS=$(LIBSOURCES:.cpp=.o)
OBJECTS=$(SOURCES:.cpp=.o)

all: $(SOURCES) $(LIBRARY) $(EXECUTABLE)

$(LIBRARY): $(LIBOBJECTS) 
    $(LD) $(LIBLDFLAGS) $(LIBOBJECTS) -o $@

$(EXECUTABLE): $(OBJECTS) 
    $(LD) $(EXELDFLAGS) $(OBJECTS) -o $@

$(OBJECTS): CFLAGS := $(EXECFLAGS) $(EXTRA)
$(LIBOBJECTS): CFLAGS := $(LIBCFLAGS) $(LIBEXTRA)

.cpp.o:
    @echo "...  Making: $@"
    $(CC) $(CFLAGS) $< -o $@

clean:
    - del /f /q *.o
    - del /f /q *.dll
    - del /f /q *.exe

0 个答案:

没有答案