9
$\begingroup$

I am running Mathematica on a Windows 10 machine and I would like to develop a package for public distribution. Most of the package will be Mathematica code, but some timing-critical parts should be in a more low-level compiled language. C is well-suited and I have some decent command of it.

The fastest and most straightforward way to include C code in Mathematica is to load library functions via LibraryLink. However, creating a library for LibraryLink requires a slightly-finicky process of calling CreateLibrary from within Mathematica. So my problem is this:

I have a Windows 10 machine. I want to create libraries that work on Linux and Mac OS X machines. If I were just compiling C code outside of Mathematica, I could do it in a Linux virtual machine. But I do not own a Mac and I'm not sure whether running Mac OS X in a virtual machine in order to compile a library is feasible.

But the problem is compounded by Mathematica: Since the library creation (CreateLibrary[]) happens from within Mathematica, I appear to be stuck. It is not enough just to run another OS in a virtual machine in order to compile to that target; now it appears that I must also have 3 separate Mathematica licenses!

I have scoured the documentation and the internet and have found no solution, nor even acknowledgement, of this problem. Is there something I am missing? How is one supposed to develop Mathematica packages that use LibraryLink code, while keeping them portable?

$\endgroup$
4
$\begingroup$

As I understand, your aim is to compile a LibraryLink library for platform Y when you only have a Mathematica license for platform X.

I don't know much about cross-compiling, so I won't comment on that. But I noticed that it seems to be possible to compile LibraryLink libraries without having access to Mathematica itself. This is how I just did this on OS X:

First I looked at the command that CreateLibrary runs:

In[3]:= CreateLibrary[{"demo.c"}, "demo", 
 "ShellCommandFunction" -> Print, "ShellOutputFunction" -> Print]

During evaluation of In[3]:= 
/usr/bin/clang -dynamiclib -o "/Users/szhorvat/Library/Mathematica/SystemFiles/LibraryResources/MacOSX-x86-64/Working-hawkeye-33552-2711507904-1/demo.dylib" -m64 -fPIC -O2 -mmacosx-version-min=10.9 -framework Foundation  -I"/Applications/Mathematica 11.app/Contents/SystemFiles/IncludeFiles/C" -I"/Applications/Mathematica 11.app/Contents/SystemFiles/Links/MathLink/DeveloperKit/MacOSX-x86-64/CompilerAdditions" "/Users/szhorvat/Desktop/test/demo.c"  -F"/Applications/Mathematica 11.app/Contents/SystemFiles/Links/MathLink/DeveloperKit/MacOSX-x86-64/CompilerAdditions"  -framework "mathlink" -lc++ 2>&1

During evaluation of In[3]:= 

Out[3]= "/Users/szhorvat/Library/Mathematica/SystemFiles/LibraryResources/MacOSX-x86-64/demo.dylib"

Notice that the things you need to compile a library are:

  • LibraryLink headers
  • MathLink headers
  • MathLink libraries

If you do not use any MathLink functions in your library, you will not need the latter two, and you can compile the library without needing access to Mathematica. I just tried doing this on OS X, using the following command modelled after the one used by CreateLibrary:

clang -dynamiclib -o demo.dylib -m64 -fPIC -O2 -mmacosx-version-min=10.9 -I"/Applications/Mathematica 11.app/Contents/SystemFiles/IncludeFiles/C" demo.c

I tested the resulting library to make sure it works fine.


Thus what you need is going to be:

  • Access to a computer with the target operating system (but you won't need Mathematica)

  • The LibraryLink header files. These are not OS-specific.

If you are going to use MathLink, you will also need:

  • MathLink headers

  • MathLink library binaries for the target OS

The MathLink license is more permissive than the Mathematica license. I suggest you read it carefully and see if you are allowed to use and distribute the MathLink libraries on any OS with your existing Mathematica license. If you think that the answer is yes, write to Wolfram support and ask them to send you the libraries.


Other things to pay attention to:

At one point OS X switched from using libstdc++ to libc++ as the default C++ standard library. Matematica uses libstdc++ up to 10.3 and libc++ starting with 10.4. Your LibraryLink library must be linked against the correct one to be compatible with a given version of Mathematica. There are also separate MathLink libraries for the two versions. All this is relevant only on OS X.

$\endgroup$
  • $\begingroup$ I was curious if perhaps the compile could be done outside of Mathematica, thanks for the info. I don't think I need MathLink...I have an algorithm that consists mostly of low-level array accesses, it doesn't do anything too mathematically-heavy. If I am using plain old C, do I need to worry much about the C++ library issue? In any case, I'm working with Mathematica 11.0 and I don't (to my knowledge!) have access to previous versions, so I probably won't be concerned about making things backwards-compatible before that point. $\endgroup$ – Ben Niehoff Jan 15 '17 at 16:50
  • $\begingroup$ @BenNiehoff Yes, you can compile without Mathematica. You need MathLink not for complex math, but for transferring non-trivial data between C and Mathematica. Plain LibraryLink supports arbitrary dimensional numerical arrays and strings. That's about it. If you need something else such as symbols, ragged arrays, return multiple results in one step, etc. then you need MathLink (or you need to figure out a way to encode your data into standard LibraryLink structures—I do this sometimes for better performance). $\endgroup$ – Szabolcs Jan 15 '17 at 17:01
  • $\begingroup$ The C++ library issue shouldn't be relevant if you don't use C++ and don't use MathLink. It's also not relevant if you only want compatibility with 11+. $\endgroup$ – Szabolcs Jan 15 '17 at 17:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.