Skip to main content

Cross-version compatibility of LibraryLink libraries


I am looking for practical advice on the cross-version compatibility of LibraryLink libraries.


In particular, I would like to understand the significance of the WolframLibraryVersion define, which is normally returned from the WolframLibrary_getVersion function manually (meaning that one can in principle return whatever).


Under what circumstances will libraries compiled with an old version of Mathematica fail to load in a new version?


When will libraries compiled with a new Mathematica fail to load in an old Mathematica?


Does Wolfram provide any guarantees for binary compatibility? What about source compatibility?



Why is there a version value for WolframLibrary.h, but not for any of the ancillary headers like WolframSparseLibrary.h? Note that WolframLibraryVersion was not increased when new ancillary headers were added.


Particular concerns:




  • Changes in WolframLibraryVersion (e.g. it changed from 3 to 4 between 11.1 and 11.2)




  • New features introduced (e.g. the WolframRawArrayLibrary.h was introduced in 10.4)





  • Changes in external dependencies (e.g. on OS X, M10.4 uses libc++, while previous versions used the incompatible libstdc++)





Answer



We cannot guarantee binary compatibility across versions, especially if using C++. Given that MSFT didn't even attempt to have cross-version compatibility across Visual C++ version until VS2017 (with a special pragma to refuse to even try to link against different versions), there isn't much we can do about it. We do make every effort to maintain that compatibility.


Generally speaking, a new version of Mathematica can load old versions unless there is a C++ runtime incompatibility. Old version can load newer version as long as their is neither a C++ rumtime incompatibility or a source-level incompatibility (e.g., it is using a new interface). I'm not knowledgeble enough about the guts of LibraryLink to tell you why the library version was bumped or its significance--I would have that it is the API level. I'll ask some folk to take a look.


For the libstdc++ vs libc++ issue specifically, the resolution is easy. Build the library twice, once against libstdc++ and libc++, then load the correct version based on $VersionNumber at runtime. This is what we did for example with GitLink, so that can serve as a useful reference.


mlobjfile = FileNameJoin[{$InstallationDirectory,
"SystemFiles/Links/MathLink/DeveloperKit/MacOSX-x86-64",
"CompilerAdditions/mathlink.framework/Versions/4.25/mathlink"}];

compileOpts = StringReplace[compileOpts, "10.9"->"10.7"] <> " -Wl,\"" <> mlobjfile <> "\"";

This links against the the libstdc++-based version of MathLink, and it changes the -mmacosx-version-min from 10.9 to 10.7, which effectively changes the C++ runtime to link against.


This in principle generalizes as long as you keep your old M-'s around. Build duplicate libraries in older versions, copy them under a new name into your application, and load the correct one based on versions. You could theoretically do this with API-level incompatibilities using appropriate #ifdefs, but I this isn't something I've seen done.


In version 11.2, we (finally) transitioned away from VS2013 to VS2017. So you may find you need to build a new version of the shared library for Windows. In this case, you may need both an old M- and an old VS to do the build.


Comments

Popular posts from this blog

functions - Get leading series expansion term?

Given a function f[x] , I would like to have a function leadingSeries that returns just the leading term in the series around x=0 . For example: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x)] x and leadingSeries[(1/x + 2 + (1 - 1/x^3)/4)/(4 + x)] -(1/(16 x^3)) Is there such a function in Mathematica? Or maybe one can implement it efficiently? EDIT I finally went with the following implementation, based on Carl Woll 's answer: lds[ex_,x_]:=( (ex/.x->(x+O[x]^2))/.SeriesData[U_,Z_,L_List,Mi_,Ma_,De_]:>SeriesData[U,Z,{L[[1]]},Mi,Mi+1,De]//Quiet//Normal) The advantage is, that this one also properly works with functions whose leading term is a constant: lds[Exp[x],x] 1 Answer Update 1 Updated to eliminate SeriesData and to not return additional terms Perhaps you could use: leadingSeries[expr_, x_] := Normal[expr /. x->(x+O[x]^2) /. a_List :> Take[a, 1]] Then for your examples: leadingSeries[(1/x + 2)/(4 + 1/x^2 + x), x] leadingSeries[Exp[x], x] leadingSeries[(1/x + 2 + (1 - 1/x...

How to thread a list

I have data in format data = {{a1, a2}, {b1, b2}, {c1, c2}, {d1, d2}} Tableform: I want to thread it to : tdata = {{{a1, b1}, {a2, b2}}, {{a1, c1}, {a2, c2}}, {{a1, d1}, {a2, d2}}} Tableform: And I would like to do better then pseudofunction[n_] := Transpose[{data2[[1]], data2[[n]]}]; SetAttributes[pseudofunction, Listable]; Range[2, 4] // pseudofunction Here is my benchmark data, where data3 is normal sample of real data. data3 = Drop[ExcelWorkBook[[Column1 ;; Column4]], None, 1]; data2 = {a #, b #, c #, d #} & /@ Range[1, 10^5]; data = RandomReal[{0, 1}, {10^6, 4}]; Here is my benchmark code kptnw[list_] := Transpose[{Table[First@#, {Length@# - 1}], Rest@#}, {3, 1, 2}] &@list kptnw2[list_] := Transpose[{ConstantArray[First@#, Length@# - 1], Rest@#}, {3, 1, 2}] &@list OleksandrR[list_] := Flatten[Outer[List, List@First[list], Rest[list], 1], {{2}, {1, 4}}] paradox2[list_] := Partition[Riffle[list[[1]], #], 2] & /@ Drop[list, 1] RM[list_] := FoldList[Transpose[{First@li...

front end - keyboard shortcut to invoke Insert new matrix

I frequently need to type in some matrices, and the menu command Insert > Table/Matrix > New... allows matrices with lines drawn between columns and rows, which is very helpful. I would like to make a keyboard shortcut for it, but cannot find the relevant frontend token command (4209405) for it. Since the FullForm[] and InputForm[] of matrices with lines drawn between rows and columns is the same as those without lines, it's hard to do this via 3rd party system-wide text expanders (e.g. autohotkey or atext on mac). How does one assign a keyboard shortcut for the menu item Insert > Table/Matrix > New... , preferably using only mathematica? Thanks! Answer In the MenuSetup.tr (for linux located in the $InstallationDirectory/SystemFiles/FrontEnd/TextResources/X/ directory), I changed the line MenuItem["&New...", "CreateGridBoxDialog"] to read MenuItem["&New...", "CreateGridBoxDialog", MenuKey["m", Modifiers-...