PDA

View Full Version : Linker errors when building DLL dependent on static lib(Crypto++)



DPbIH
18th December 2014, 16:48
All

Here is a preface - I have a C++ + Qt application, it consists of several projects and we are using MSVC 2012 to build it. Now, I'm implementing build scripts to start deploying build server. So, I started creating Qt .pro files for each and every project we have.

**Now the problem** - we use Crypto++ library(http://www.cryptopp.com/) which we build from source code and the output is static lib, and we have DLL which depends on cryptlib.lib.

I wrote .pro file for Cryptlib and I'm able to build it using qmake/jom


QT -= core gui
QMAKE_CFLAGS += /Zc:wchar_t

TEMPLATE = lib
TARGET = cryptlib

Release:DESTDIR = ./Release
Debug:DESTDIR = ./Debug

CONFIG += staticlib precompile_header
DEFINES += _USING_V110_SDK71_ WINVER=0x0501 WIN32 _WINDOWS _MBCS
DEFINES -= UNICODE

PRECOMPILED_HEADER = pch.h
DEPENDPATH += .

include(CryptoPP.pri)@

I wrote .pro file for my DLL - it compiles fine, *but I'm getting linker errors on linkage phase*. The most interesting thing is that when I build cryptlib with MSVC2012 and *then* build DLL with qmake - then it link OK.

What could be wrong? I checked all proj settings in MSVC projects and applied in my pro files. I checked names mangling in both libs built with MSVC and QT - mangled names look the same. Now I got stuck


@# ----------------------------------------------------
# This file is generated by the Qt Visual Studio Add-in.
# ------------------------------------------------------

QT -= gui core
QMAKE_CFLAGS += /Zc:wchar_t

TEMPLATE = lib
TARGET = PSGLicensing

Release:DESTDIR = ./Release
Debug:DESTDIR = ./Debug

CONFIG += dll
DEFINES += _AFXDLL _USING_V110_SDK71_ WIN32 _WINDOWS _WINDLL _USRDLL DLL_LIBRARY PSGLICENSING_DLL_BUILD _MBCS _VC80_UPGRADE=0x0710
DEFINES -= UNICODE

PRECOMPILED_HEADER = stdafx.h
DEPENDPATH += .

win32:CONFIG(release, debug|release): LIBS += -L$$_PRO_FILE_PWD_/../CryptoPP/Release/ -lcryptlib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$_PRO_FILE_PWD_/../CryptoPP/Debug/ -lcryptlib

INCLUDEPATH += $$_PRO_FILE_PWD_/../CryptoPP/
DEPENDPATH += $$_PRO_FILE_PWD_/../CryptoPP/

win32:CONFIG(release, debug|release): PRE_TARGETDEPS += $$_PRO_FILE_PWD_/../CryptoPP/Release/cryptlib.lib
else:win32:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$_PRO_FILE_PWD_/../CryptoPP/Debug/cryptlib.lib

include(PSGLicensing.pri)@


In MSVC2012 we have following settings for

**CryptLib**


*Compiler:* /Yu"pch.h" /GS /GL /analyze- /W3 /Gy- /Zc:wchar_t /Zi /Gm- /O2 /Ob2 /Fd"Release\vc110.pdb" /fp:precise /Zp1 /D "_USING_V110_SDK71_" /D "NDEBUG" /D "_WINDOWS" /D "USE_PRECOMPILED_HEADERS" /D "WIN32" /D "WINVER=0x0501" /D "_VC80_UPGRADE=0x0710" /errorReport:prompt /GF- /WX- /Zc:forScope /arch:SSE /Gd /Oy /Oi /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\cryptlib.pch"

*Linker:* /OUT:"SecretPath\CryptoPP\Release\cryptlib.lib" /LTCG /NOLOGO

and here are settings for **DLL**


*Compiler*: /Yu"stdafx.h" /GS /analyze- /W3 /Zc:wchar_t /I"SecretPath\PSGLicensing\IncludeExp" /Zi /Gm- /O2 /Fd"Release\vc110.pdb" /fp:precise /D "_USING_V110_SDK71_" /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "_USRDLL" /D "PSGLICENSING_DLL_BUILD" /D "_VC80_UPGRADE=0x0710" /D "_WINDLL" /D "_MBCS" /D "_AFXDLL" /errorReport:prompt /WX- /Zc:forScope /Gd /Oy- /MD /Fa"Release\" /EHsc /nologo /Fo"Release\" /Fp"Release\PSGLicensing.pch"

*Linker:* /OUT:"SecretPah\PSGLicensing\Release\PSGLicensing.dll" /MANIFEST /PDB:"SecretPath\PSGLicensing\Release\PSGLicensing.pdb" /DYNAMICBASE:NO "..\CryptoPP\Release\cryptlib.lib" "SecretPath\CryptoPP\Release\cryptlib.lib" /DEF:".\PSGLicensing.def" /IMPLIB:"SecretPath\PSGLicensing\Release\PSGLicensing.lib" /DEBUG /DLL /MACHINE:X86 /OPT:REF /SAFESEH /INCREMENTAL:NO /PGD:"SecretPath\PSGLicensing\Release\PSGLicensing.pgd" /SUBSYSTEM:WINDOWS",5.01" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Release\PSGLicensing.dll.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1

Here is jom output


@ C:\Qt\Qt5.2.1\Tools\QtCreator\bin\jom.exe -f Makefile.Release
link /NOLOGO /DYNAMICBASE /NXCOMPAT /INCREMENTAL:NO /DLL /MANIFEST /MANIFESTFILE:Release\PSGLicensing.dll.embed.manife st /OUT:Release\PSGLicensing.dll @C:\Users\ANDRIY~1.GLO\AppData\Local\Temp\PSGLicen sing.dll.6212.16.jom
Creating library Release\PSGLicensing.lib and object Release\PSGLicensing.exp
GenerateRandomBlock.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CryptoPP::CFB_CipherTemplate<class CryptoPP::AbstractPolicyHolder<class CryptoPP::CFB_CipherAbstractPolicy,class CryptoPP::CFB_ModePolicy> >::ProcessData(unsigned char *,unsigned char const *,unsigned int)" (?ProcessData@?$CFB_CipherTemplate@V?$AbstractPoli cyHolder@VCFB_CipherAbstractPolicy@CryptoPP@@VCFB_ ModePolicy@2@@CryptoPP@@@CryptoPP@@UAEXPAEPBEI@Z)
GenerateRandomBlock.obj : error LNK2001: unresolved external symbol "public: virtual void __thiscall CryptoPP::CFB_CipherTemplate<class CryptoPP::AbstractPolicyHolder<class CryptoPP::CFB_CipherAbstractPolicy,class CryptoPP::CFB_ModePolicy> >::Resynchronize(unsigned char const *,int)" (?Resynchronize@?$CFB_CipherTemplate@V?$AbstractPo licyHolder@VCFB_CipherAbstractPolicy@CryptoPP@@VCF B_ModePolicy@2@@CryptoPP@@@CryptoPP@@UAEXPBEH@Z)
GenerateRandomBlock.obj : error LNK2001: unresolved external symbol "protected: virtual void __thiscall CryptoPP::CFB_CipherTemplate<class CryptoPP::AbstractPolicyHolder<class CryptoPP::CFB_CipherAbstractPolicy,class CryptoPP::CFB_ModePolicy> >::UncheckedSetKey(unsigned char const *,unsigned int,class CryptoPP::NameValuePairs const &)" (?UncheckedSetKey@?$CFB_CipherTemplate@V?$Abstract PolicyHolder@VCFB_CipherAbstractPolicy@CryptoPP@@V CFB_ModePolicy@2@@CryptoPP@@@CryptoPP@@MAEXPBEIABV NameValuePairs@2@@Z)

...

Release\PSGLicensing.dll : fatal error LNK1120: 16 unresolved externals
@

d_stranz
18th December 2014, 19:59
public: virtual void __thiscall CryptoPP::CFB_CipherTemplate<class CryptoPP::AbstractPolicyHolder<class ...

This template is in the DLL you are wrapping CryptLib with? The error is telling you that it doesn't have the __declspec( dllimport ) or __declspec( dllexport ) declaration needed to export a method from a DLL (the __thiscall is the tipoff). Quite possibly one of the classes you use to construct the concrete template instantiation doesn't have the right declaration.

DPbIH
19th December 2014, 09:47
Somehow, I got it solved. Here is the version of .pro file for CryptLib with which built library is linkable.


QT -= core gui
QMAKE_CFLAGS += /Zc:wchar_t /GL

TEMPLATE = lib
TARGET = cryptlib

Release:DESTDIR = ./Release
Debug:DESTDIR = ./Debug

CONFIG += staticlib
DEFINES += _USING_V110_SDK71_ WINVER=0x0501 WIN32 _WINDOWS _MBCS USE_PRECOMPILED_HEADERS
DEFINES -= UNICODE

DEPENDPATH += .

include(CryptoPP.pri)

So, all I did is added **USE_PRECOMPILED_HEADERS** to DEFINES and removed **PRECOMPILED_HEADER_FILE = pch.h**. I do not know how it actually helped, but it helped.