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
.libfile 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.objs, andv8andxfasupport - Tried to compile with Microsoft's
clang-clinstead 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 = falseand, thuspdf_is_complete_lib = true,.objfiles built fromlibc++andwinmm.libis_component_build = trueand, thuspdf_is_complete_lib = false, all.dllresulting from compilation, i.e.:absl.dllicuuc.dlllibc++.dllpartition_alloc.dllpdfium.dllzlib.dllRead also the important note below which tries to explain the difference between the two flags.
Long description
As per docs, once
.ninjafiles has been generated as result ofgn args <out_dir>, it can be seen which.obj,.liband.dllfiles are needed to buildpdfium_unitests.exe. Comparing those with the ones used to generatepdfium.lib(orpdfium.dlldepending on flags, see below), it can be spotted the required libraries.With
is_component_build = falseandpdf_is_complete_lib = true:ninja -C <out_dir>; this also builds libc++;pdfium.libvianinja -C <out_dir> pdfium(will only execute a link step)libc++.libusing depot tool's lld-link which will contain all.objfiles from compilation of libc++:pdfium.lib, all libc++'s.objfiles inC:\out_dir\obj\buildtools\third_party\libc++\libc++(or,libc++.libfrom previous step),winmm.libin your project; e.g.:With
is_component_build = trueandpdf_is_complete_lib = false:ninja -C <out_dir> pdfium; will compile all the necessary.dlls along with.pdband.libfiles and put them inout_dirpdfium.libin your project and copy emitted.dlls in output directory; assuming emitted files are inC:\pdfium\result, project's.vcxprojwill look like this: Note: the files you'll need are listed in tl;dr; section.Note 2: used
robocopybecause is more efficient thanxcopy. Also, check on exit code is needed because of the value returned byrobocopyImportant note
pdf_is_complete_libandis_component_buildwill set, respectively,/MTand/MDflags 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.