After successfully building Pdfium as per Google's docs, I created a new C++ console app with VS2022 and tried to embed .lib
resulting from Pdfium build but, it results in several unresolved symbols which, I guess, should be included in standard C++. As an example, here is two of the unresolved symbols:
fx_string.obj: error LNK2001: unresolved external symbol "void __cdecl std::Cr::__libcpp_verbose_abort(char const *,...)"
fpdf_parser_utility.obj : error LNK2001: unresolved external symbol "public: class std::Cr::basic_ostream<char,struct std::Cr::char_traits<char> > & __cdecl std::Cr::basic_ostream<char,struct std::Cr::char_traits<char> >::write(char const *,__int64)"
Steps taken:
- build Pdfium following docs steps using below
args.gn
:use_goma = false is_debug = false pdf_use_skia = false pdf_enable_xfa = false pdf_enable_v8 = false pdf_is_standalone = false is_component_build = false pdf_is_complete_lib = true
- Created a simple C++ console app with following content (copied from Getting started):
#include <iostream> #include "../PDFium/public/fpdfview.h" int main() { std::cout << "PDFium test!\n"; FPDF_LIBRARY_CONFIG config{}; config.version = 2; config.m_pUserFontPaths = NULL; config.m_pIsolate = NULL; config.m_v8EmbedderSlot = 0; FPDF_InitLibraryWithConfig(&config); FPDF_DestroyLibrary(); return 0; }
- Copied Pdfium's public folder and resulting
.lib
file into a separate folder of the project, added necessary fields for linker and set C++ language spec tostdc++20
; below, the corresponding tags in.vcxproj
<!-- other tags --> <ClCompile> <!-- other tags --> <LanguageStandard>stdcpp20</LanguageStandard> <LanguageStandard_C>stdc11</LanguageStandard_C> </ClCompile> <!-- other tags --> <Link> <SubSystem>Console</SubSystem> <GenerateDebugInformation>true</GenerateDebugInformation> <AdditionalLibraryDirectories>$(SolutionDir)PDFium\x64</AdditionalLibraryDirectories> <AdditionalDependencies>PDFium.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link>
(Unsuccessful) Tests did
- Tried to compile PDFium with and without
pdf_is_complete_lib = true
, and thus, linking also single.obj
s, andv8
andxfa
support - Tried to compile with Microsoft's
clang-cl
instead ofMSBuild
(the one provided by Visual Studio's Native Development pack) - Tried to compile with depot tools's
clang-cl
(currently, version16.0.0
) - Tried several options found here and there on SO and on internet
Any help is appreciated. Thanks in advance.
After days of failures and (vain) research, I finally found the solution, posted here for future reference.
TL;DR;
Depending on flags set in
args.gn
, Pdfium will need at least the following to successfully build and start the Getting Started example:is_component_build = false
and, thuspdf_is_complete_lib = true
,.obj
files built fromlibc++
andwinmm.lib
is_component_build = true
and, thuspdf_is_complete_lib = false
, all.dll
resulting from compilation, i.e.:absl.dll
icuuc.dll
libc++.dll
partition_alloc.dll
pdfium.dll
zlib.dll
Read also the important note below which tries to explain the difference between the two flags.
Long description
As per docs, once
.ninja
files has been generated as result ofgn args <out_dir>
, it can be seen which.obj
,.lib
and.dll
files are needed to buildpdfium_unitests.exe
. Comparing those with the ones used to generatepdfium.lib
(orpdfium.dll
depending on flags, see below), it can be spotted the required libraries.With
is_component_build = false
andpdf_is_complete_lib = true
:ninja -C <out_dir>
; this also builds libc++;pdfium.lib
vianinja -C <out_dir> pdfium
(will only execute a link step)libc++.lib
using depot tool's lld-link which will contain all.obj
files from compilation of libc++:pdfium.lib
, all libc++'s.obj
files inC:\out_dir\obj\buildtools\third_party\libc++\libc++
(or,libc++.lib
from previous step),winmm.lib
in your project; e.g.:With
is_component_build = true
andpdf_is_complete_lib = false
:ninja -C <out_dir> pdfium
; will compile all the necessary.dll
s along with.pdb
and.lib
files and put them inout_dir
pdfium.lib
in your project and copy emitted.dll
s in output directory; assuming emitted files are inC:\pdfium\result
, project's.vcxproj
will look like this: Note: the files you'll need are listed in tl;dr; section.Note 2: used
robocopy
because is more efficient thanxcopy
. Also, check on exit code is needed because of the value returned byrobocopy
Important note
pdf_is_complete_lib
andis_component_build
will set, respectively,/MT
and/MD
flags during compilation.Although might not seem a problem, MSBuild will complain if the two types are mixed and thus, you'll need either to recompile Pdfium or change the way your code is generated via Project Properties > C/C++ > Code Generation > Runtime Library.
For more information see Google docs, Microsoft docs on flags and linker warning and, eventually, this SO question which can help in choose the code generation that most suits your needs.