Strange Linker error - c++

I am using cl compiler and LINK to link the code. I am getting very strange linker in the following sample code.
//main.cpp
int main ()
{
Test();
}
void Test ()
{
}
//test.cpp
void Test3 ();
void Test2 ()
{
Test3 ();
}
When I compile main.cpp with test.cpp, then it gives me linker error that Test3 undefined which actually should not link. When I remove test.cpp from my makefile, then it compiles and links without any problem.
I am using skia library. Is it possible that this issue is due to skia library and some link option mismatch?
My compiler linker options are listed below:
Compiler options:
/c /W4 /nologo /WL /Gr /GF /GA /Gy /GR- /vmb /EHsc /D_UNICODE /DUNICODE /D_CRT_SECURE_NO_WARNINGS /D_CRT_NON_CONFORMING_SWPRINTFS /DWIN32 /D_WIN32 /MT /Z7 /O2 /GS- /Oi
Linker options:
LINK skia_core.lib skia_utils.lib skia_effects.lib skia_images.lib skia_opts.lib skia_opts_ssse3.lib skia_ports.lib skia_sfnt.lib skia_skgpu.lib /INCREMENTAL:NO /NOLOGO /OPT:REF /IGNORE:4098 /IGNORE:4089 /SUBSYSTEM:WINDOWS /FIXED:NO /NODEFAULTLIB:advapi32.lib /NODEFAULTLIB:user32.lib /NODEFAULTLIB:gdi32.lib /NODEFAULTLIB:shell32.lib /NODEFAULTLIB:comdlg32.lib /NODEFAULTLIB:version.lib /NODEFAULTLIB:mpr.lib /NODEFAULTLIB:rasapi32.lib /DEFAULTLIB:winmm.lib /NODEFAULTLIB:winspool.lib /NODEFAULTLIB:vfw32.lib /NODEFAULTLIB:secur32.lib /NODEFAULTLIB:oleacc.lib /NODEFAULTLIB:oledlg.lib /NODEFAULTLIB:sensapi.lib /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:wininet.lib /NODEFAULTLIB:wsock32.lib /NODEFAULTLIB:odbc32.lib /NODEFAULTLIB:odbccp32.lib /NODEFAULTLIB:htmlhelp.lib /NODEFAULTLIB:comctl32.lib /NODEFAULTLIB:libc.lib unicows.lib kernel32.lib user32.lib winspool.lib gdi32.lib Rpcrt4.lib netapi32.lib wininet.lib wsock32.lib odbc32.lib odbccp32.lib htmlhelp.lib comctl32.lib advapi32.lib shell32.lib comdlg32.lib version.lib mpr.lib rasapi32.lib winmm.lib vfw32.lib secur32.lib oleacc.lib oledlg.lib DbgHelp.lib shlwapi.lib mstask.lib taskschd.lib psapi.lib crypt32.lib /VERSION:1.0 skia_core.lib skia_utils.lib skia_effects.lib skia_images.lib skia_opts.lib skia_opts_ssse3.lib skia_ports.lib skia_sfnt.lib skia_skgpu.lib /MAP /DEBUG /OPT:REF /NODEFAULTLIB:LIBCMTD.LIB psapi.lib crypt32.lib usp10.lib Opengl32.lib Gdiplus.lib /RELEASE /OUT:test.exe
Linker error message:
LNK2019: unresolved external symbol "void __fastcall Test3(void)" (?Test3##YIXXZ) referenced in function "void __fastcall Test2(void)" (?Test2##YIXXZ)

Function Test3 is just declared but not defined. You need to write some code for it.
You expect the linker to detect that Test3 is not needed even if it is called from Test2, because Test2 is not ever called. You cannot take that for granted as it is not guaranteed in the standard.

Related

Visual Studio link error "CloseWindow already defined" only when raylib.lib is linked after user32.lib

I have a compiled static library of raylib : raylib.lib. I compiled this library myself with Librarian > General > Additional Dependencies: winmm.lib
This library has a C function like the following:
void CloseWindow(void);
And I also have my very basic C++ project that uses raylib:
// main.cpp
#include "raylib.h"
int main()
{
InitWindow(100, 100, "");
while (!WindowShouldClose())
{
BeginDrawing();
ClearBackground(RAYWHITE);
EndDrawing();
}
CloseWindow();
return 0;
}
Now, when I compile my project with Linker > Additional Dependencies set to:
raylib.lib; user32.lib; shell32.lib; gdi32.lib
It compiles and links without any warning.
But when I swap the order of raylib.lib and user32.lib:
user32.lib; raylib.lib; shell32.lib; gdi32.lib
Then I get a linker error:
Link:
D:\Visual Studio Community 2019\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\link.exe
/ERRORREPORT:QUEUE /OUT:"bin\MyProject.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:bin
user32.lib raylib.lib shell32.lib gdi32.lib winmm.lib /MANIFEST
/MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG:FULL
/PDB:"bin\MyProject.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /TLBID:1 /DYNAMICBASE
/NXCOMPAT /IMPLIB:"bin\MyProject.lib" /MACHINE:X64 obj\Release\MyProject\main.obj
raylib.lib(core.obj) : error LNK2005: CloseWindow already defined in user32.lib(USER32.dll) [D:\example\MyProject.vcxproj]
bin\MyProject.exe : fatal error LNK1169: one or more multiply defined symbols found [D:\example\MyProject.vcxproj]
So how is this possible that it's already defined? Why does the linking order matter?
UPDATE
When I compiled raylib with Librarian > General > Additional Dependencies: winmm.lib; user32.lib then I get this warning (when compiling the library):
Lib:
D:\Visual Studio Community 2019\VC\Tools\MSVC\14.29.30133\bin\HostX86\x64\Lib.exe /OUT:"bin\raylib.lib" winmm.lib user32.lib /NOLOGO /MACHINE:X64 obj\Release\raylib\core.obj
obj\Release\raylib\models.obj
obj\Release\raylib\raudio.obj
obj\Release\raylib\rglfw.obj
obj\Release\raylib\shapes.obj
obj\Release\raylib\text.obj
obj\Release\raylib\textures.obj
obj\Release\raylib\utils.obj
user32.lib(USER32.dll) : warning LNK4006: __NULL_IMPORT_DESCRIPTOR already defined in winmm.lib(WINMM.dll); second definition ignored [D:\example\raylib.vcxproj]
raudio.obj : warning LNK4006: PlaySound already defined in winmm.lib(WINMM.dll); second definition ignored [D:\example\raylib.vcxproj]
core.obj : warning LNK4006: CloseWindow already defined in user32.lib(USER32.dll); second definition ignored [D:\example\raylib.vcxproj]
core.obj : warning LNK4006: ShowCursor already defined in user32.lib(USER32.dll); second definition ignored [D:\example\raylib.vcxproj]
Having raylib compiled this way MyProject does not need to link with user32.lib and it works.
What is the best way to use raylib in this situation? Should I always compile raylib with it's dependencies (user32.lib etc.) and get those warnings or maybe I should link with them later when MyProject is compiled (then I need to make sure that raylib is linked before it's dependencies)?

C++17, Intel C++ compiler: what is the library needed to use filesystem header in windows 10 platform?

I just need to do some filesystem operation using #include <filesystem>, however, I get the below link error ... I guess I am missing a library in the xlink command. Below is the error message.
Please let me know your valuable comments.
test_accuracy.obj : error LNK2019: unresolved external symbol wmemcmp referenced in function "public: class std::filesystem::path & __cdecl std::filesystem::path::operator/=(class std::filesystem::path const &)" (??_0path#filesystem#std##QEAAAEAV012#AEBV012##Z)
Debug\test_accuracy.exe : fatal error LNK1120: 1 unresolved externals
Edit
Below you can see the compile and link commands. (thx)
icl -I"C:/Program Files (x86)/IntelSWTools/sw_dev_tools/compilers_and_libraries_2020.2.254/windows/compiler/include" -I/../boost_1_73_0 -Qstd=c++17 -Qdiag-error-limit:3 -O3 -MD -Fo:DEBUG/obj/test_accuracy.obj -c test_accuracy.cpp
xilink /OPT:REF /OPT:ICF /DEBUG:FASTLINK /TLBID:1 ole32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib -LIBPATH:Debug\lib -out:Debug/test_accuracy.exe DEBUG/obj/test_accuracy.obj
The missing symbol is part of the C runtime. Try adding vruntime.lib to your link line, or linking with the MSVC linker (link.exe) instead.
I raised the problem with Intel C++ Community here and it turns out to be a reproducible issue, and they suggested to update my VS 2019 Community Edition. I updated to 16.8.5 and it worked. So may be it is probably the right solution. (at least worked for me.)

Combining PCH, PDB, and Zi leads to puzzling C2859 compile error with VS2017

I have a project that doesn't currently use precompiled headers, but I'd like to make it do so, as I've demonstrated that it leads to real compilation speed improvements in the project.
I'd also like to use /Zi, so I can capitalize on the parallel build benefits associated with /Zf, which is implied by /Zi.
I'm using the VS2017 C++ compiler, but I'm using a build system that is not Visual Studio, so answers relating to configuring VS aren't helpful.
What I'm finding is that I can set up the build to use precompiled headers just fine, or I can set it up to use /Zi just fine, but I can't seem to form a proper series of invocations to do both. When I try to do what I think is correct, I end up with error C2958 stopping the build, and I don't see what I'm doing wrong.
I've built a toy project to demonstrate what I'm seeing. The pch.hpp header looks like this:
#pragma once
#include <vector>
And we make a short mainline in main.cpp:
int main() {
std::vector<int> xs = { 1, 2, 3 };
return xs.size();
}
Note that this is the complete file contents for main.cpp: I haven't omitted anything. I am intentionally not including pch.hpp here, because we are going to force inject it with /Fi later. The real project doesn't have include lines for a precompiled header in all the right places, and there would be thousands of files to update to do so. Note that the approach using /Fi does appear to work in the command lines below, and has the advantage that a forceincludes based mechanism can work with GCC style precompiled headers as well.
If we build things without /Zi, everything goes fine:
cl /Fobuild\pch.obj /TP /nologo /EHsc /errorReport:none /MD /O2 /Oy- /Zc:rvalueCast /Zc:strictStrings /volatile:iso /Zc:__cplusplus /permissive- /std:c++17 /Zc:inline /c pch.hpp /Yc /Fpbuild\pch.pch
pch.hpp
cl /Fobuild\main.obj /c main.cpp /TP /nologo /EHsc /errorReport:none /MD /O2 /Oy- /Zc:rvalueCast /Zc:strictStrings /volatile:iso /Zc:__cplusplus /permissive- /std:c++17 /Zc:inline /FIpch.hpp /Yupch.hpp /Fpbuild/pch.pch
main.cpp
We find the files we would expect to find under the build directory:
main.obj pch.obj pch.pch
However, if we try to use /Fi and /Fd to generate a per-file .pdb and control its name, it doesn't work at all:
We can compile the precompiled header that way OK:
cl /Fobuild\pch.obj /TP /nologo /EHsc /errorReport:none /MD /O2 /Oy- /Zc:rvalueCast /Zc:strictStrings /volatile:iso /Zc:__cplusplus /permissive- /std:c++17 /Zc:inline /c pch.hpp /Yc /Fpbuild\pch.pch /Zi /Fdbuild\pch.pch.pdb
And things look OK in the build directory so far:
pch.obj pch.pch pch.pch.pdb
But when we try to build the object file for main, it all falls apart:
cl /Fobuild\main.obj /c main.cpp /TP /nologo /EHsc /errorReport:none /MD /O2 /Oy- /Zc:rvalueCast /Zc:strictStrings /volatile:iso /Zc:__cplusplus /permissive- /std:c++17 /Zc:inline /FIpch.hpp /Yupch.hpp /Fpbuild/pch.pch /Zi /Fdbuild\main.obj.pdb
main.cpp
main.cpp: error C2859: Z:\data\acm\src\example\build\main.obj.pdb is not the pdb file that was used when this precompiled header was created, recreate the precompiled header.
This is a very puzzling error, because the error message suggests that main.obj.pdb is being treated as an input somehow, but in fact it is intended to be the name of the .pdb file generated as output, per the value of the /Fd flag for the build of main.obj.
Googling hasn't resulted in much useful guidance, with a lot of hints about reconfiguring VS settings, which isn't really useful in the case of a build driven by something else.
I've also verified that my trickery with the /Fi of pch.hpp isn't the issue. If I update main.cpp to #include pch.hpp and remove the /Fipch.hpp from the compile line for main.obj, the same C2859 error still occurs.
I realize there are a lot of flags to get right when using precompiled headers, among them the /Yc and /Yu and /Fp flags, but I think I've got those handled correctly.
Does anyone see where I've got things wrong?
Edit 1 - Demonstrating that /Fd can name different PDB files
In response to the comment below, it doesn't actually appear to be the case that all targets must share the /Fd argument. Here is an example without the use of precompiled headers that demonstrates that:
Here, I've needed to add common.cpp and create a main1.cpp and main2.cpp which both link it:
The common.hpp header looks like:
#pragma once
int common(int arg);
With a trivial implementation in common.cpp:
#include "common.hpp"
int common(int arg) {
return arg + 42;
}
Then introduce two different mainlines:
main1.cpp:
#include "common.hpp"
int main() {
std::vector<int> xs = { 1, 2, 3 };
return common(xs.size());
}
And main2.cpp:
#include "common.hpp"
int main() {
std::vector<int> xs = { 1, 2, 3, 4};
return common(xs.size());
}
Then compile all three object files. Note that we still have the /Fipch.hpp here to make the includes work right, but we aren't using any of the actual PCH machinery:
cl /Fobuild\common.obj /c common.cpp /TP /nologo /EHsc /errorReport:none /MD /O2 /Oy- /Zc:rvalueCast /Zc:strictStrings /volatile:iso /Zc:__cplusplus /permissive- /std:c++17 /Zc:inline /FIpch.hpp /Zi /Fdbuild\common.obj.pdb
cl /Fobuild\main1.obj /c main1.cpp /TP /nologo /EHsc /errorReport:none /MD /O2 /Oy- /Zc:rvalueCast /Zc:strictStrings /volatile:iso /Zc:__cplusplus /permissive- /std:c++17 /Zc:inline /FIpch.hpp /Zi /Fdbuild\main1.obj.pdb
cl /Fobuild\main2.obj /c main2.cpp /TP /nologo /EHsc /errorReport:none /MD /O2 /Oy- /Zc:rvalueCast /Zc:strictStrings /volatile:iso /Zc:__cplusplus /permissive- /std:c++17 /Zc:inline /FIpch.hpp /Zi /Fdbuild\main2.obj.pdb
And we find what we would expect in the build directory:
common.obj common.obj.pdb main1.obj main1.obj.pdb main2.obj main2.obj.pdb
Then we can go ahead and link:
link /nologo /DEBUG /INCREMENTAL:NO /LARGEADDRESSAWARE /OPT:REF /OUT:build\main1.exe /PDB:build\main1.pdb build\common.obj build\main1.obj
link /nologo /DEBUG /INCREMENTAL:NO /LARGEADDRESSAWARE /OPT:REF /OUT:build\main2.exe /PDB:build\main2.pdb build\common.obj build\main2.obj
And we find that we get both executables and PDB files for those executables in the build directory:
common.obj main1.exe main1.obj.pdb main2.exe main2.obj.pdb
common.obj.pdb main1.obj main1.pdb main2.obj main2.pdb
From the Microsoft documentation for C2859 and creating precompiled headers, the database used to store the debug information must be shared among all source modules using the precompiled header. Having all that shared debug information stored in one database greatly reduces the size of the object files and speeds up linking since the linker does not have to deal with all that repetition.
If you want all your compiled files to have their own copies of the debug information, use the /Z7 option instead.

visual studio source files building order

i have n number of cpp files in a project.'A' is the source file which will have main function,'B' is an another source file which contains function definition which will be used by 'A'.
A.cpp
#include "stdafx.h"
#include "b.h"
int main()
{
add(5,4);
return 0;
}
B.h
#include "stdafx.h"
void add(int a ,int b);
B.cpp
#include "stdafx.h"
void add(int a,int b)
{
cout<<(a+b);
}
but the build order is like a.cpp after b.cpp so the add function should be unresolved by linker.
how can i solve the build order problem?
Edit 1:my build file log:-
Build started 22-11-2014 15:57:11.
1>Project "C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\ConsoleApplication2.vcxproj" on node 2 (Build target(s)).
1>Link:
C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\link.exe /ERRORREPORT:PROMPT /OUT:"C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\Release\ConsoleApplication2.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:D:\Glut /LIBPATH:D:\OpenCV\opencv\build\x86\vc11\lib opencv_core246.lib opencv_features2d246.lib opencv_haartraining_engine.lib opencv_calib3d246.lib opencv_highgui246.lib opencv_imgproc246.lib opencv_legacy246.lib opencv_ml246.lib opencv_objdetect246.lib opencv_video246.lib glut32.lib asmlibrary.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG /PDB:"C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\Release\ConsoleApplication2.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT /IMPLIB:"C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\Release\ConsoleApplication2.lib" /MACHINE:X86 /SAFESEH Release\CLM.obj
Release\FCheck.obj
Release\FDet.obj
Release\IO.obj
Release\Patch.obj
Release\PAW.obj
Release\PDM.obj
Release\Tracker.obj
Release\updated_facetracker_v2.obj
Release\glm.obj
Release\glmimg.obj
Release\glmimg_devil.obj
Release\glmimg_jpg.obj
Release\glmimg_png.obj
Release\glmimg_sdl.obj
Release\glmimg_sim.obj
Release\glm_util.obj
Release\stdafx.obj
1>updated_facetracker_v2.obj : error LNK2001: unresolved external symbol "void __cdecl glmDraw(struct _GLMmodel *,unsigned int)" (?glmDraw##YAXPAU_GLMmodel##I#Z)
1>updated_facetracker_v2.obj : error LNK2001: unresolved external symbol "struct _GLMmodel * __cdecl glmReadOBJ(char *)" (?glmReadOBJ##YAPAU_GLMmodel##PAD#Z)
1>C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\Release\ConsoleApplication2.exe : fatal error LNK1120: 2 unresolved externals
1>Done Building Project "C:\Users\Admin\Documents\Visual Studio 2013\Projects\ConsoleApplication2\ConsoleApplication2\ConsoleApplication2.vcxproj" (Build target(s)) -- FAILED.
Build FAILED.
Time Elapsed 00:00:00.81
this is the original projects build file here glm.c is compiled built after the updated_facetracker_v2.cpp file and glm.c did not have any error."
Your linker fais, because B.cpp doesn't compile. The compiler fails to create an object for B.cpp. Since the object isn't there, the linker can't find it, and gives the error. There should be an error about B.cpp further up the error log.
Change B.cpp from:
#include "stdafx.h"
void add(int a,int b)
{
cout<<(a+b);
}
to:
#include "stdafx.h"
#include <iostreams>
void add(int a,int b)
{
std::cout<<(a+b) << std::endl;
}
Build order doesn't matter: The compiler takes each source file and creates an object file. The linker takes the object files and tries to link those to your target executable. The order your compiler generates the object files shouldn't matter.
Also, your main is faulty too:
change:
add(5+4);
to:
add(5, 4);
You are trying to link against add(int) while your function in B.cpp has the signature add(int, int) which is a different function according to the linker.

unresolved external symbol, but dumpbin says it's ok

I downloaded Crypto++ 5.62 and built it with default project settings. In my project I set up the path to cryptopp.lib and defined its name in "Additional Dependencies". Both Crypto++ and my project - VS 2008.
During building of my project I get:
main.obj : error LNK2001: unresolved external symbol
"class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const CryptoPP::DEFAULT_CHANNEL" (?DEFAULT_CHANNEL#CryptoPP##3V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##B)
main.obj : error LNK2001: unresolved external symbol
"bool (__cdecl* CryptoPP::g_pAssignIntToInteger)(class type_info const &,void *,void const *)" (?g_pAssignIntToInteger#CryptoPP##3P6A_NABVtype_info##PAXPBX#ZA)
dumpbin /all cryptopp.lib shows me in the public symbols section
19471C _imp_?DEFAULT_CHANNEL#CryptoPP##3V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##B
1D6F30 __imp_?g_pAssignIntToInteger#CryptoPP##3P6A_NABVtype_info##PAXPBX#ZA
What's wrong then? Why the linker can't find the symbols?
upd:
linker command line from my project settings
/OUT:"C:\Projects\crypto_hash\Debug\crypto_hash.exe" /NOLOGO /LIBPATH:"e:\libs\cryptopp\cryptopp562\cryptopp\Win32\DLL_Output\Debug" /MANIFEST /MANIFESTFILE:"Debug\crypto_hash.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\Projects\crypto_hash\Debug\crypto_hash.pdb" /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT cryptopp.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Try adding CRYPTOPP_IMPORTS to your project defines.
From config.h:
#ifdef CRYPTOPP_EXPORTS
# define CRYPTOPP_IS_DLL
# define CRYPTOPP_DLL __declspec(dllexport)
#elif defined(CRYPTOPP_IMPORTS)
# define CRYPTOPP_IS_DLL
# define CRYPTOPP_DLL __declspec(dllimport)
#else
# define CRYPTOPP_DLL
#endif
Or include Crypto++'s dll.h. It sets CRYPTOPP_IMPORTS:
#if !defined(CRYPTOPP_IMPORTS) && !defined(CRYPTOPP_EXPORTS) && !defined(CRYPTOPP_DEFAULT_NO_DLL)
# ifdef CRYPTOPP_CONFIG_H
# error To use the DLL version of Crypto++, this file must be included before any other Crypto++ header files.
# endif
# define CRYPTOPP_IMPORTS
#endif
If that does not work...
g_pAssignIntToInteger is from algparams.cpp:
$ grep -R g_pAssignIntToInteger *
algparam.cpp:PAssignIntToInteger g_pAssignIntToInteger = NULL;
algparam.h:CRYPTOPP_DLL extern PAssignIntToInteger g_pAssignIntToInteger;
algparam.h: if (!(g_pAssignIntToInteger != NULL && typeid(T) == typeid(int) && g_pAssignIntToInteger(valueType, pValue, &m_value)))
integer.cpp: if (!g_pAssignIntToInteger)
integer.cpp: g_pAssignIntToInteger = AssignIntToInteger;
Looking at the declaration in algparam.h:
// to allow the linker to discard Integer code if not needed.
typedef bool (CRYPTOPP_API * PAssignIntToInteger)(const std::type_info &valueType, void *pInteger, const void *pInt);
CRYPTOPP_DLL extern PAssignIntToInteger g_pAssignIntToInteger;
And the implementation in algparam.cpp:
#ifndef CRYPTOPP_IMPORTS
...
NAMESPACE_BEGIN(CryptoPP)
PAssignIntToInteger g_pAssignIntToInteger = NULL;
...
So you might need to change the implementation to ensure the code uses g_pAssignIntToInteger (to keep it from being discarded). Unfortunately, nothing comes to mind at the moment.
DEFAULT_CHANNEL is declared in cryptlib.h and has storage allocated in cryptolib.cpp:
$ grep -R DEFAULT_CHANNEL *
...
cryptlib.cpp:const std::string DEFAULT_CHANNEL;
...
cryptlib.h:extern CRYPTOPP_DLL const std::string DEFAULT_CHANNEL;
...
This might be a different problem since I'm not used to seeing issues with DEFAULT_CHANNEL. See how CRYPTOPP_IMPORTS works for you, and then ask a different question since this might be a different problem.