How do I codesign a compiled C++ shared library on macOS using MATLAB R2024b?

Is there an example workflow that describes how to codesign and notarize a compiled C++ shared library on macOS using MATLAB R2024b? 

 Accepted Answer

MATLAB Compiler SDK R2024b provides two ways to deploy MATLAB functions within C++ applications - the mwarray API and the MATLAB Data API. In MATLAB R2024b, code signing a C++ shared library is only possible via the MATLAB Data API.
More information about the two different deployment options can be found at the C++ Shared Library Integration documentation page.
Regarding code signing a C++ shared library using MATLAB Data API in MATLAB R2024b, please refer to the steps below:
  1. Start out with an example MATLAB function as shown:
    function out = createHelloWorld out = 'hello Mac!';
  2. Using the MATLAB command window, build the C++ SDK target using compiler.build function and the "matlab-data" interface option:
    >> br = compiler.build.cppSharedLibrary('createHelloWorld.m', 'Interface', 'matlab-data', 'Verbose', true)
    More information can be found on the compiler.build.cppSharedLibrary documentation page.
  3. The above command creates a new folder in your current working directory. In that folder, within the "v2" folder, you will find a CTF file named "libcreateHelloWorld.ctf". For the purposes on this example, please copy that CTF into your working directory alongside the ".m" file.
  4. In the same folder as your MATLAB file, create a file named "helloworldSample_mda.cpp" with the following contents:
    /*================================================================= * * helloworldSample * Sample driver code that uses the generic interface and * MATLAB Data API to call a C++ shared library created using * MATLAB Compiler SDK. * Refer to the MATLAB Compiler SDK documentation for more * information. * *=================================================================*/ // Include the header file required to use the generic // interface for the C++ shared library generated by the // MATLAB Compiler SDK. #include "MatlabCppSharedLib.hpp" #include <iostream> namespace mc = matlab::cpplib; namespace md = matlab::data; std::shared_ptr<mc::MATLABApplication> setup() { auto mode = mc::MATLABApplicationMode::IN_PROCESS; // Specify MATLAB startup options std::vector<std::u16string> options = {}; std::shared_ptr<mc::MATLABApplication> matlabApplication = mc::initMATLABApplication(mode, options); return matlabApplication; } int mainFunc(std::shared_ptr<mc::MATLABApplication> app, const int argc, const char * argv[]) { md::ArrayFactory factory; try { auto lib = mc::initMATLABLibrary(app, u"libcreateHelloWorld.ctf"); std::vector<md::Array> inputs{}; auto result = lib->feval(u"createHelloWorld", 1, inputs); // Print the result if (!result.empty()) { const md::CharArray& charArray = result[0]; std::string output = charArray.toAscii(); std::cout << "createHelloWorld output: " << output << std::endl; } else { std::cout << "No output returned from createHelloWorld." << std::endl; } } catch (const std::exception & exc) { std::cerr << exc.what() << std::endl; return -1; } return 0; } // The main routine. On the Mac, the main thread runs the system code, and // user code must be processed by a secondary thread. On other platforms, // the main thread runs both the system code and the user code. int main(const int argc, const char * argv[]) { int ret = 0; try { auto matlabApplication = setup(); ret = mc::runMain(mainFunc, std::move(matlabApplication), argc, argv); // Calling reset() on matlabApplication allows the user to control // when it is destroyed, which automatically cleans up its resources. // Here, the object would go out of scope and be destroyed at the end // of the block anyway, even if reset() were not called. // Whether the matlabApplication object is explicitly or implicitly // destroyed, initMATLABApplication() cannot be called again within // the same process. matlabApplication.reset(); } catch (const std::exception & exc) { std::cerr << exc.what() << std::endl; return -1; } return ret; }
  5. Next, in MATLAB execute the following via the command window: 
    >> mbuild helloworldSample_mda.cpp
    On a Mac, this creates the folder "helloworldSample_mda.app".  You can run this .app now (without signing or notarization) but you cannot share it yet.
  6. Now, in a macOS terminal execute the following:
    % open helloworldSample_mda.app/Contents/MacOS/prelaunch
     This should launch a separate terminal window and you should see the phrase "hello Mac!". 
  7. Next, we need to sign the underlying binaries and the ".app" itself. To do so, execute the following commands in a macOS terminal:
    % codesign --verbose=4 --options=runtime -s "Developer ID Application: DEVELOPER NAME (TEAM NAME)" --strict --entitlements entitlements.plist helloworldSample_mda.app/Contents/MacOS/applauncher % codesign --verbose=4 --options=runtime -s "Developer ID Application: DEVELOPER NAME (TEAM NAME)" --strict --entitlements entitlements.plist helloworldSample_mda.app/Contents/MacOS/helloworldSample_mda % codesign --verbose=4 --options=runtime -s "Developer ID Application: DEVELOPER NAME (TEAM NAME)" --strict --entitlements entitlements.plist helloworldSample_mda.app/Contents/MacOS/prelaunch % codesign --verbose=4 --options=runtime -s "Developer ID Application: DEVELOPER NAME (TEAM NAME)" --strict --entitlements entitlements.plist helloworldSample_mda.app/
    If you get a message "<item>: is already signed", then you can unsign that binary with "codesign --remove-signature <item>". 
  8. Once you have completed the codesigning step, you need to zip the signed application:
    % ditto -c -k --keepParent helloworldSample_mda.app/ helloworldSample_mda_app.zip
  9. Finally, you need to notarize the application as shown:
    % xcrun notarytool submit helloworldSample_mda_app.zip --apple-id YOUR_APPLE_ID --team-id TEAM_NAME --password abcd-efgh-ijkl-mnop
  10.  After notarization is complete and accepted, you should be able to send that zip file AND the CTF file to a colleague who has a Mac and has the R2024b MATLAB Runtime installed. From there, you can incorporate your .app and CTF into other installers if you wish, being careful to correctly sign and notarize the installers and their contents appropriately.

More Answers (0)

Categories

Products

Release

R2024b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!