Using libxml2 in Island project

island

(Ram Poe) #1

I want to use libxml2 in my Island project(Win32). I have managed to prepare a libxml2.fx file using HeaderImporter and referenced it in my project.

Now I want to access name of the xmlNode but I’m not sure how to do that. This is my code

import libxml
import Swift
let xmlDoc = xmlReadFile("C:\\test.xml", nil, 0)

let rootNode = xmlDocGetRootElement(xmlDoc)!

// How do I access rootNode->name?

xmlFreeDoc(xmlDoc)

rootNode is an UnsafePointer<xmlNode>. How do I dereference it?


(Carlo Kok) #2

*rootNode should return the dereferenced value
so (*rootNode).fieldname


(Ram Poe) #3

I’m trying to statically link libxml2 to my project but ran into some trouble. I have built libxml2 as a static library.
This is my libxml.json file

{
  "TargetString": "i686-pc-windows-msvc",
  "Version": "2.9.5",
  "SDKVersionString": "libxml2-win32-2.9.5",
  "Imports": [
    {
      "Name": "libxml2",
      "ForcedNamespace": "libxml",
      "Files": [ "libxml/HTMLtree.h", "libxml/HTMLparser.h", "libxml/xpath.h", "libxml/xpathInternals.h", "libxml/xmlerror.h" ],
      "IndirectFiles": [ "libxml/*.h" ],
      "DepLibs": [ "libxml2_a.lib", "kernel32.lib", "Ws2_32.lib", "zlib.lib", "ucrt.lib" ]
   }
  ],
  "Platform": "Windows"
}

And this is the HeaderImport command I ran

HeaderImporter.exe import --json "C:\Users\X\Documents\Visual Studio 2015\Projects\SilverIsland\libxml2\libxml.json" --libpath="C:\Users\X\Documents\Visual Studio 2015\Projects\SilverIsland\libxml2\lib" -x "C:\Program Files (x86)\RemObjects Software\Elements\Island\Reference Libraries\Windows\i386" -i "C:\Users\X\Documents\Visual Studio 2015\Projects\SilverIsland\libxml2\include" -i "C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt" -i "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" -o "C:\Users\X\Documents\Visual Studio 2015\Projects\SilverIsland\libxml2\lib"

Now when I build the project I get these errors

C:\Program Files (x86)\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets(84,5): error : C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: duplicate symbol: ___stdio_common_vsprintf in (import) and in (import)
C:\Program Files (x86)\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets(84,5): error : C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: duplicate symbol: _free in (import) and in (import)
C:\Program Files (x86)\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets(84,5): error : C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: duplicate symbol: _malloc in (import) and in (import)
C:\Program Files (x86)\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets(84,5): error : C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: duplicate symbol: _realloc in (import) and in (import)
C:\Program Files (x86)\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets(84,5): error : C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: duplicate symbol: __errno in (import) and in (import)
C:\Program Files (x86)\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets(84,5): error : C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: duplicate symbol: _getenv in (import) and in (import)
C:\Program Files (x86)\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets(84,5): error : C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: duplicate symbol: _exit in (import) and in (import)
C:\Program Files (x86)\MSBuild\RemObjects Software\Elements\RemObjects.Elements.Island.Windows.targets(84,5): error : C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: duplicate symbol: _strtoul in (import) and in (import)
Done building project "SilverIsland.elements" -- FAILED.

I did a little digging and it seems that malloc, free, getenv, etc. are exported by both ucrt.lib(C Run-time Library) and Island.lib. Hence the duplicate symbol error. So is there any solution to this?


(Carlo Kok) #4

I would try to compile without ucrt.lib; if the list of missing functions is reasonable, implement those.


(Ram Poe) #5

As in compile libxml2 without the dependence on the C standard library?


(Ram Poe) #6

I tried building the project after removing ucrt.lib from the libxml.json file. Now I get a bunch of undefined symbol errors. I added those symbols as ImportDefs to the libxml.json file but then new ones show up. The whole list of missing symbols doesn’t show up in the error output. It says

C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe: error: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors)

Any way for me to pass the /ERRORLIMIT flag to lld?


(Carlo Kok) #7

from the cmdline, in your project dir, do something like:

C:\Program Files (x86)\RemObjects Software\Elements\Bin\lld.exe -flavor link @obj\Debug\Windows\linkercmd /errorlimit 1000000

(Ram Poe) #9

Thanks, I’ve added all the required functions under ImportDefs. Most of the errors have gone away but one persists.

If I add an entry for _strncmp, I get

duplicate symbol: _strncmp in (import) and in (import)

And if I remove it I get

undefined symbol: __imp__strncmp

(marc hoffman) #10

Btw, we also have native, high-level and Cross-platform XML APIs in Elements RTL, with XmlDocument.


(Ram Poe) #11

Yes, I did look at that but I wanted to use Xpath.


(marc hoffman) #12

Gotcha. We probably should look at adding support for that, in the future.


(Carlo Kok) #13

@wolfram The problem is that you can’t really ‘import’ them like that. How many functions are we talking about here?

You’d have to implement them element sside to amke it compatible (This is an unfortunate issue with native linkers). If it’s a reasonable amount we can probably add them to IslandRTL to make things easier.


(Ram Poe) #14

I see. There’s about 50 functions

 _CIfmod
 _except1
 ___acrt_iob_func
 ___stdio_common_vfprintf
 ___stdio_common_vsprintf_s
 ___stdio_common_vsscanf
 __beginthread
 __close
 __dclass
 __dsign
 __dup
 __endthread
 __fileno
 __getcwd
 __isnan
 __lseeki64
 __open
 __read
 __stat64i32
 __wfopen
 __wopen
 __write
 __wstat64i32
 _calloc
 _close
 _dup
 _fclose
 _ferror
 _fflush
 _fileno
 _fopen
 _fputc
 _fread
 _fwrite
 _getcwd
 _memchr
 _open
 _read
 _strcat_s
 _strchr
 _strcpy_s
 _strerror
 _strncmp
 _strncpy
 _strncpy_s
 _strstr
 _strtol
 _toupper
 _wcstombs
 _write
 _libm_sse2_log10_precise
 _libm_sse2_pow_precise

(Carlo Kok) #15

Ouch. That’s a bit much…


(Carlo Kok) #16

Most of these are pretty easy to cover though, the only ones I wouldn’t know how to do is:

 _CIfmod
 _except1
 ___acrt_iob_func
 ___stdio_common_vfprintf
 ___stdio_common_vsprintf_s
 ___stdio_common_vsscanf

 _libm_sse2_log10_precise
 _libm_sse2_pow_precise

(Ram Poe) #17

I think I have resolved this issue.

I created a ucrtbase.lib file sans the duplicate symbols from Island.lib. This still left me with the strncmp error. So I patched libxml with an implementation of strncmp.

It works now. Probably not worth the hassle though.