Search code examples
c++matlabcurlmingw32

mex - use .a instead of .lib file with curl in matlab


I've got a Matlab S-Function (I created this one with cURL some weeks ago). This is just an example, but it will be enough to make my point clear.

In this example I am using cURL to make a HTTP-Request in order to get data and output that data into Matlab Simulink.

Originally I compiled this code on Mac OSX, which worked fine after struggling a little bit with the mex-command already. Now I have to do the same again, but for a Windows System.

I am able to compile the libcurl.a file for Windows with mingw32 but when trying to compile the mexfile with mex file.cpp -L. -llibcurl or mex file.cpp -L. -llibcurl -I.curl (curl being the include folder, I adjusted the #include statement accordingly) I only get the error that Matlab can't find libcurl.lib and so far I didn't find settings to make mex use the .a suffix.

I don't know too much about C++ Code compilation, so please don't be too harsh, but did I miss something important (like building the .lib itself (which I also didn't find any info on, just precombiled files that didn't work as well)).

Also this Matlab User suggesting that changing the suffix would help, nope, it didn't. On OSX the compilation was pretty straightforward linking the binary, etc. (see Readme of GitHub Repo for info on how I did it there) but it seems as if I can't wrap my head around doing the same exact thing on Windows.

System: Windows 10 64-bit & Windows 7 64-bit (tried both)

Error Message: Can't access it right now, will probably update that tomorrow, I basically got two different depending on what command I was using to compile.

  1. was the standard (which most likely occured because of me simply not linking the header file unintentionally)

    test.c:(.text+0xe1): undefined reference to curl_global_init' test.c:(.text+0xe6): undefined reference to curl_easy_init' test.c:(.text+0x10c): undefined reference to curl_easy_setopt' test.c:(.text+0x12e): undefined reference to curl_easy_setopt' test.c:(.text+0x150): undefined reference to curl_easy_setopt' test.c:(.text+0x17e): undefined reference to curl_easy_cleanup' test.c:(.text+0x1b3): undefined reference to curl_easy_cleanup' test.c:(.text+0x1db): undefined reference to curl_easy_setopt' test.c:(.text+0x1e7): undefined reference to curl_easy_perform' test.c:(.text+0x1ff): undefined reference to curl_easy_cleanup'

  2. one was the mentioned no such file or directory: 'libcurl.a.lib'

NOTE that the first error message is not mine, i c&p'd it to give an example

So the primary question in here is: Is there a way to create a libcurl.lib file on Windows, and if yes, how do I do it with Mingw32 or another compiler?

Thank y'all already:)


Solution

  • Ok, so since no one new an answer I did some more research thanks to @drescherjm pointing me towards Visual Studio, I was able to build the project on windows.

    Prerequisites:

    1. Microsoft Visual Studio 2017 (Community) - For .lib compilation
    2. Microsoft Visual Studio 2015 (Community) - For mex compilation inside MatLab

    After installing VS 2017 I followed this article. If you don't know german, the following part is for you:

    I. Open your CMD and execute

    "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat" (for 32-Bit Systems)

    OR

    "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" (for 64-bit Systems).

    The 64/32-Bit difference between the .bat-files tricked me at first, leading to another error, so watch out that you choose the correct file.

    II. After that cd to your cURL-folder (curl_download_folder\winbuild). (Which you downloaded inbefore from the official page). And execute this command: nmake /f Makefile.vc mode=static VC=12

    This compiles all the files you need to run cURL inside MatLab and to integrate it into any other program as well.

    There should be some folders with files in them inside curl_download_folder\builds now. Namely:

    1. libcurl-vc12-x64-release-static-ipv6-ssl
    2. libcurl-vc12-x64-release-static-ipv6-ssl-obj-curl
    3. libcurl-vc12-x64-release-static-ipv6-ssl-obj-lib

    III. Copy the whole \builds folder to your MatLab working directory that contains the .cpp file you want to compile.

    III(/2). If you didn't do that so far, set your compiler to Microsoft Visual C++ 2015 Professional with mex -setup cpp or mex -setup c++

    IV. Compile your S-Function (sfunc.cpp) with this command:

    mex sfunc.cpp -lbuilds\libcurl-vc12-x64-release-static-ipv6-sspi-winssl\include\ -Lbuilds\libcurl-vc12-x64-release-static-ipv6-sspi-winssl\lib\ -llibcurl_a.lib -DCURL_STATICLIB
    

    V. Voilà, your .mexw64-file should compile correctly. (The -D flag is super important in this case. \builds folders, you need them all!)

    Thanks for your help, everyone.

    Edit: If you're on a 32-bit system, simply replace every x64 in my answer with x86.