Building Cling Interpreter with libxml2 external library

Hello, I am trying to build a custom cling interpreter with libxml2 already loaded using the cling Interpreter source file attached below. I build my cling Interpreter using the command below:

 g++ -c -o cling.o -Iinclude -I/usr/include/libxml2 cling.cpp  
 g++ -o clingD cling.o -lLLVMSupport  -lclangASTMatchers  -lclangFrontendTool  -lclingUserInterface  -lclangARCMigrate  -lclangStaticAnalyzerFrontend  -lclangStaticAnalyzerCheckers -lclangStaticAnalyzerCore  -lclangCrossTU  -lclangIndex  -lclangFormat -lclangToolingInclusions  -lclangToolingCore  -lclingMetaProcessor  -lclingInterpreter  -lclingUtils  -lclangCodeGen  -lclangRewriteFrontend  -lclangFrontend  -lclangDriver  -lLLVMOption  -lclangSerialization  -lLLVMCoverage  -lLLVMLTO  -lLLVMExtensions  -lclangParse  -lclangSema  -lclangAnalysis  -lclangASTMatchers  -lclangEdit  -lclangAST  -lclangRewrite  -lclangLex  -lclangBasic  -lLLVMOrcJIT  -lLLVMPasses  -lLLVMCoroutines  -lLLVMObjCARCOpts  -lLLVMExecutionEngine  -lLLVMJITLink  -lLLVMOrcTargetProcess  -lLLVMOrcShared  -lLLVMRuntimeDyld  -lLLVMNVPTXCodeGen -lLLVMipo  -lLLVMFrontendOpenMP  -lLLVMIRReader  -lLLVMAsmParser  -lLLVMInstrumentation  -lLLVMLinker  -lLLVMVectorize  -lLLVMNVPTXDesc  -lLLVMNVPTXInfo  -lLLVMX86CodeGen  -lLLVMAsmPrinter  -lLLVMDebugInfoDWARF  -lLLVMDebugInfoMSF  -lLLVMGlobalISel  -lLLVMSelectionDAG  -lLLVMCodeGen  -lLLVMBitWriter  -lLLVMScalarOpts  -lLLVMAggressiveInstCombine  -lLLVMInstCombine  -lLLVMTransformUtils  -lLLVMTarget  -lLLVMAnalysis  -lLLVMObject  -lLLVMBitReader  -lLLVMTextAPI  -lLLVMProfileData  -lLLVMCFGuard  -lLLVMCore  -lLLVMRemarks  -lLLVMBitstreamReader  -lLLVMX86AsmParser  -lLLVMMCParser  -lLLVMX86Desc  -lLLVMX86Disassembler  -lLLVMMCDisassembler  -lLLVMMC  -lLLVMBinaryFormat  -lLLVMDebugInfoCodeView  -lLLVMX86Info  -lLLVMSupport  -lrt  -ldl  -lm -lxml2 /usr/lib64/libz.so  /usr/lib64/libtinfo.so  -lLLVMDemangle

If i try and run the attached script using the compile executable, it fails with the attached error.

input_line_4:1:10: fatal error: 'libxml/parser.h' file not found
#include <libxml/parser.h>
         ^~~~~~~~~~~~~~~~~
input_line_5:1:10: fatal error: 'libxml/tree.h' file not found
#include <libxml/tree.h>

Please see attached files
script.cxx (374 Bytes)
cling.cpp (6.1 KB)

Hi @cw2636,

thank you for your question. I will ask @vvassilev to take a look here.

Cheers,
Marta

Maybe the we should use -I/usr/include/ instead of -I/usr/include/libxml2.

It didn’t work.
In cling if i do this



****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ .I  /usr/include/libxml2
[cling]$ .L xml2
[clin]$ .x cling_bin/script.cxx
This is a test 6

It works without no error.

Could you please provide a more detailed example of how it should work?

Let us take a basic c++ application below which uses libxml2 library to read an xml file.

#include <stdio.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <iostream>
/**
* example1Func:
* @filename: a filename or an URL
*
* Parse the resource and free the resulting tree
*/
static void
example1Func(const char *filename) {
        xmlDocPtr doc; /* the resulting document tree */

        doc = xmlReadFile(filename, NULL, 0);
        if (doc == NULL) {
                fprintf(stderr, "Failed to parse %s\n", filename);
                return;
        }

        std::cout << "Xml has been read" << std::endl;
        xmlFreeDoc(doc);
}

int main(int argc, char **argv) {
        if (argc != 2)
                return(1);

        /*
        * this initialize the library and check potential ABI mismatches
        * between the version it was compiled for and the actual shared
        * library used.
        */
        LIBXML_TEST_VERSION

                example1Func(argv[1]);

        /*
        * Cleanup function for the XML library.
        */
        xmlCleanupParser();
        /*
        * this is to debug memory for regression tests
        */
        xmlMemoryDump();
        return(0);
}

In c++ i can compile this file with the libxml2 library and generate the executable using the following commands:

 g++ -c -o testxml.o -I/usr/include/libxml2 testxml.cpp
g++ -o xml.exe testxml.o -lxml2

Executing this file with a test xml file runs with no error.

./xml.exe test.xml
Xml has been read

I am trying to do something similar to this with cling. I wanted to generate a cling Interpreter executable with some shared or external libraries embedded into it. This interprete when used to interprete c++ code, will know where to find the source files of those libraries and call appropriate functions.

@SapphireShade Please refer to this also

@vvassilev Why if i add these line of code to the cling interpreter source file

Interp.AddIncludePath("/usr/include/libxml2");
Interp.loadFile("/lib64/libxml2.so");

It works, but if we compile and link it on command line wont work?

I misread the original command. You compile the cling with gcc and you pass an include path to gcc. Now cling is a compiler that lives in your binary and you should pass the include path to it. That is why this works.

if you add #pragma cling add_include_path("/usr/include/libxml2") before you include the libxml headers it might work.

Probably it’d be more helpful if you describe the problem you are trying to solve first.

Let’s say i want to omit using

Interp.AddIncludePath("/usr/include/libxml2");
Interp.loadFile("/lib64/libxml2.so");

to link and compile libxml2 with cling. What is the best approach. Please specify with code?

I did: #pragma cling add_include_path("/usr/include/libxml2")