-1

I am trying to use xerces-c-3.2.2 on Windows 10 from the sample in xerces-c-3.2.2\samples\src\SAXPrint, the sample used as a Visual Studio 2019 project.

Before, I used xerces-c_2_8_0 successfully with xerces-c-src_2_8_0\samples\SAX2Print as a Visual Studio 2019 project with Visual Studio configurations (not CMake). When trying the same with xerces-c-3.2.2 and the according sample, I get the 'error MSB6006: "CL.exe" exited with code 2'.

Note: I have built xerces-c-3.2.2 myself, as there are no binaries for it available. After the build of xerces-c-3.2.2, I get the files xerces-c_3.exp, xerces-c_3.lib, and xerces-c_3_2.dll in C:\Xerces\xerces-c-3.2.2\src\Release, and the include files are in C:\Xerces\xerces-c-3.2.2\xerces-c-3.2.2\src.

On https://developercommunity.visualstudio.com/content/problem/405001/error-msb6006-clexe-exited-with-code-2.html, it was suggested to use Clang as a compiler, as the mentioned "MSB6006" error should be a compiler bug that has not been fixed by Microsoft yet. For using Clang, one has to use CMake in the current version of Visual Studio (I would prefer CMake anyway, for other reasons), and I could not figure out how to setup the project with CMake correctly. The problem is how to tell CMake about the Xerces library files (with xerces-c-3.2.2, there seems to be the only one library file xerces-c_3.lib).

So my top-level CMakeLists.txt (without linking) is:

cmake_minimum_required (VERSION 3.8)

project ("SAXPrint")

include_directories("C:\\Xerces\\xerces-c-3.2.2\\xerces-c-3.2.2\\src")

add_subdirectory ("SAXPrint")

The CMakeLists.txt in the subdirectory is

cmake_minimum_required (VERSION 3.8)

add_executable(SAXPrint "SAXPrint.cpp" "SAXPrint.hpp")

(Yes, I know I should use the absolute paths as arguments to CMake, but that should not be the point here.)

To inform CMake about the xerces library file, I tried

link_directories("C:\\Xerces\\xerces-c-3.2.2\\xerces-c-3.2.2\\src\\Release")

in top-level CMakeLists.txt and I tried

target_link_libraries(SAXPrint "C:\\Xerces\\xerces-c-3.2.2\\xerces-c-3.2.2\\src\\Release")

(this last one does not seem to be accepted, as Visual Studio then keeps displaying the message "generate CMake cache to refresh") and I have read something about the CMake "find_library" command that I did not understand.

The error message I get is

Error   LNK2019 unresolved external symbol "__declspec(dllimport) public: static char const * const xercesc_3_2::XMLUni::fgXercescDefaultLocale" (__imp_?fgXercescDefaultLocale@XMLUni@xercesc_3_2@@2QBDB) referenced in function main  C:\Users\stefan\source\repos\SAXPrint   C:\Users\stefan\source\repos\SAXPrint.cpp.obj   1   

So any comment how to use the Xerces library file is really welcome, but even better would be if someone had a whole sample CMake project that works with Xerces Version 3 and Visual Studio 2019. I would prefer a CMake project, as this seems to be a better choice for what I would like to accomplish. Thanks.

  • Here is an example https://gitlab.kitware.com/yrHeTaTeJlb/cmake/blob/master/Tests/FindXercesC/Test/CMakeLists.txt (I haven't tried it myself but it seems to be using the modern style of CMake, i.e. by using imported targets). See also https://cmake.org/cmake/help/latest/module/FindXercesC.html – Erik Sjölund Sep 01 '19 at 14:30
  • Just a clarification regarding the example in my previous comment: The target `test_xercesc_tgt` is using the modern style of CMake, i.e. by using imported targets but the other target `test_xercesc_var` is using the old style. – Erik Sjölund Sep 01 '19 at 14:38
  • Thanks for the link. But find_package supposes the package to be installed? I just have some directories with headers and the lib files, and I do not want to presuppose any package installation of xerces. – Stefan Springer Sep 02 '19 at 05:01
  • I tried (with xerces-c_2_8_0 this time because I know it runs with appropriate VS configs): `find_library(XercesLibrary NAMES xerces-c PATHS "C:\\Xerces\\xerces-c_2_8_0-x86_64-windows-vc_8_0\\lib") if(NOT XercesLibrary) message(FATAL_ERROR "Failed to find the Xerces library!") endif()` But I get the error message "Failed to find the Xerces library!". – Stefan Springer Sep 02 '19 at 05:33
  • See also https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html It helps `find_package()` finding libraries that are installed in non-standard locations. Sometimes it even supports finding libraries from build directories (that have not been installed). I guess finding libraries from build directories would only make sense if you plan to build your application statically. – Erik Sjölund Sep 05 '19 at 10:20

1 Answers1

0

I found a working solution for the simple "SAXPrint" example, and it is actually really simple if you do not try to use to add whole directories or try to let CMake find installed libaries of some kind:

Top-level CMakeLists.txt:

cmake_minimum_required (VERSION 3.8)
project(SAXPrint)
add_subdirectory ("SAXPrint")

CMakeLists.txt in subdirectory "SAXPrint" with the sample source files:

cmake_minimum_required (VERSION 3.8)
include_directories("C:\\Xerces\\xerces-c-3.2.2\\xerces-c-3.2.2\\src")
add_executable(SAXPrint "SAXPrintHandlers.cpp" "SAXPrint.cpp")
target_link_libraries(SAXPrint "C:\\Xerces\\xerces-c-3.2.2\\xerces-c-3.2.2\\src\\Release\\xerces-c_3.lib")

(Yes, one should avoid absolute paths in the CMakeLists.txt, but this is separate issue and should be easily solved e.g. by giving the path to Xerces as an argument to CMake.)

So I just give the absolute path to the one library file of Xerces 3 as an argument in target_link_libraries. I guess, if I use another library file I just add another path (so I add e.g. many library files for Xerces 2 that uses many of them)? But what about dependencies of those libraries? Maybe this solution is not really how it is expected to be used, I guess CMake has to know about dependencies and just giving a list of library files does not solve it in the general case?

Please note that in my case Xerces is not "installed" in any way, it is (and for my means should) just be a directory containing the needed files in some subdirectories without e.g. any environment variables pointing to it. So I guess find_package is not something I could use, what about find_library?

Or if I just continue to use target_link_libraries (which actually should use the result of e.g. find_package as I understand it) in what order should the library files be listed so dependencies are respected?