How to generate MEX files from C code generated by matlab coder, without using the matalb coder

I have matlab coder installed, and I have found the
codegen [-options] [files]
command useful for generating MEX files and improving performance. I have put my code on github, but other users do not have matlab coder installed, so they cannot use the above sytax to generate MEX files for their OS.
During creation of the MEX file, as an intermediate step, matlab produces lots of .c and .h files, in multiple folders. Given that the
mex [options ...] file [files ...]
command in matlab does not require the matlab coder, I would like to use it to produce MEX code based on these .c and .h files. This process should then be repeatable for users who do not have matlab coder installed, thus generating MEX files for their OS and matlab version. But I am not sure which c files I should be pointing to, if I should also be pointing to the .h files, if these files need to be modified, etc.
But I cannot find any instructions on how to do this - any help would be much appreciated - thanks.

 Accepted Answer

Hi Andrew,
I understand that you are trying to generate mex files from the C code generated by the MATLAB Coder.
The C files generated by matlab coder heavily depends on the functions and definitions defined in header files located in
fullfile(matlabroot,'extern','include')
Quick tip: Copy all the source and header files inside the codegen folder to the current directory.
Please follow the below steps to generate mex files:
  1. Identify the main file (it is not necessarily main.c), in your case it is named as <Name of the function generated using codegen>.c
  2. Ensure all the source and header files are in one directory.
  3. Make that directory as the current directory.
  4. Please add mexFunction to the .c file from step 1 and refer to this example and C Matrix api while writing mexFunction.
  5. Run the mex command by including path to current folder and predefined header folder or any other folder containing header files by using -I (captial - i) argument.
Example:
% CodeGenFunc is the name of the mex function generated using codegen and
% the corressponding code resided in CodeGenFunc.c
% Copy all the .c and .h files generated during codegen to the current
% dirctory and run
mex('CodeGenFunc.c','-I\', '-I\<path to the folder containing predefined headerfiles>' );
Hope this helps!

3 Comments

Thank you very much for your reply Ramtej. It's definitely a step forward, thank you. But it still doesn't quite work - likely I'm doing something stupid.
I tried your suggestion with the following toy problem:
function z = a_plus_2(a)
z = a+get_2(rand()*0.0001);
end
Which is chosen intentionally to use a built-in Matlab routine.
I then ran the matlab coder command to produce C files as before:
codegen a_plus_2 -args coder.typeof(1.0) -config:lib
Then moved all of the files into one folder, and modified a_plus_2.c so that it included a MEX function, like this:
/*
* Academic License - for use in teaching, academic research, and meeting
* course requirements at degree granting institutions only. Not for
* government, commercial, or other organizational use.
*
* a_plus_2.c
*
* Code generation for function 'a_plus_2'
*
*/
/* Include files */
#include "mex.h"
#include "a_plus_2.h"
#include "a_plus_2_data.h"
#include "a_plus_2_initialize.h"
#include "rand.h"
/* Function Definitions */
double a_plus_2(double a)
{
double y;
if (!isInitialized_a_plus_2) {
a_plus_2_initialize();
}
y = b_rand() * 0.0001;
y = 2.0 + y * b_rand();
return a + y;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (nrhs != 1) {
mexErrMsgIdAndTxt("sum:nrhs", "One input arguments required.");
}
if (nlhs != 1) {
mexErrMsgIdAndTxt("sum:nlhs", "One output argument required.");
}
double a = mxGetScalar(prhs[0]);
double result = a_plus_2(a);
plhs[0] = mxCreateDoubleScalar(result);
}
/* End of code generation (a_plus_2.c) */
But unfortunately, when I run
mex('a_plus_2.c','-I\','-I/home/andrew/matlab/extern/include')
I get the following error:
Building with 'gcc'.
Error using mex
/usr/bin/ld:
/tmp/mex_3322531951607987_2710214/a_plus_2.o: in
function `a_plus_2':
a_plus_2.c:(.text+0xf): undefined reference to
`isInitialized_a_plus_2'
/usr/bin/ld: a_plus_2.c:(.text+0x1e): undefined
reference to `b_rand'
/usr/bin/ld: a_plus_2.c:(.text+0x28): undefined
reference to `b_rand'
/usr/bin/ld: a_plus_2.c:(.text+0x59): undefined
reference to `a_plus_2_initialize'
collect2: error: ld returned 1 exit status
I don't understand this as (with my limited knowledge of C) it looks ike the undefined references are being included in the header files at the top?
Hi Andrew,
I tried an alternative workaround and it worked. I assume you are using a linux machine
%toy function used
function z = ToyFunction(a)
z = a+rand(1)*5;
end
Please follow the steps below:
  • Run the matlab coder command to produce C files as before:
codegen ToyFunction -args coder.typeof(1.0) -config:lib
  • Go to the folder: codegen/lib/ToyFunction ( You can find interface and examples subfolders here ).
  • Add mexFunction to the ToyFunction.c same as before.
  • Do not copy files from the interface folder ( all the necessary declarations and definitions are already present in the current folder ).
  • Run the below command ( include all the .c files ).
mex('*.c','-I/','-I/home/andrew/matlab/extern/include');
Note: Be careful with the backslash and forwardslash here
This works, thank you!
Also, I found with this example, replacing your final command with
mex *.c -output alt_name
works, and stops matlab from just naming it something random, in this case naming the MEX file alt_name.

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB Coder in Help Center and File Exchange

Products

Release

R2021b

Asked:

on 3 Aug 2023

Edited:

on 24 Aug 2023

Community Treasure Hunt

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

Start Hunting!