Matlab: Removing dependency on OS env PATH variable for gcc

Hi

We have started experimenting with acados using the Matlab interface and we are in general happy with the setup. We have however bumped into a constraint which is causing us trouble.

When generating a Simulink s-function a number of c-files are compiled using the mex compilation setup and these are linked with a library containing the casadi_ext_fun. The compilation of this library does not use mex compilation, but is rather a system call directly to the compiler. For this to work it is required that the compiler used by mex is added to the OS PATH environment variable.

As we need to have another (incompatible) version of gcc in our OS PATH environment variable acados will use this incompatible gcc version to compile the cadasdi_ext_fun library and the linking will subsequently fail.

To fix this I have implemented the below change on top of the v0.1.8 commit. The change is to extract the path to the compiler mex uses and temporariy add it to the environment PATH variable in the current Matlab session.

Also Iā€™m not sure if similar changes are needed elsewhere in the code-base?

The below change works in our use-case, but is only tested using minGW on Windows. Question is if you agree with this fix and if so if you want me rebase a to latest master and make a pull request?

Simulink: gcc: No longer necessary to have gcc in OS environment variable path

Modified building of casadi_ext_fun library such that the gcc version configured for building mex files is used.
This avoids a linking error which happens when a version of gcc different than configured for mex building is in the OS environment PATH variable.

diff --git a/interfaces/acados_matlab_octave/ocp_generate_casadi_ext_fun.m b/interfaces/acados_matlab_octave/ocp_generate_casadi_ext_fun.m
index 14a8cb8c..c6a251d3 100644
--- a/interfaces/acados_matlab_octave/ocp_generate_casadi_ext_fun.m
+++ b/interfaces/acados_matlab_octave/ocp_generate_casadi_ext_fun.m
@@ -208,6 +208,9 @@ end
 
 ext_fun_compile_flags = opts_struct.ext_fun_compile_flags;
 
+%Store the current PATH environment variable value
+origEnvPath=getenv('PATH');
+
 if use_msvc
     % get env vars for MSVC
     msvc_env = fullfile(mexOpts.Location, 'VC\Auxiliary\Build\vcvars64.bat');
@@ -223,6 +226,13 @@ if use_msvc
     % build
     compile_command = sprintf('"%s" & %s', msvc_env, build_cmd);
 else % gcc
+    %Read the mex C compiler configuration and extract the location
+    cCompilerConfig = mex.getCompilerConfigurations('C');
+    pathToCompilerLocation = cCompilerConfig.Location;
+    %Modify the environment PATH varuable for this Matlab session such that 
+    %the mex C compiler takes priority ensuring calls to gcc uses the
+    %configured mex compiler
+    setenv('PATH', [fullfile(pathToCompilerLocation,'bin') ';' origEnvPath]);
     % set includes
     acados_include = ['-I' acados_folder];
     blasfeo_include = ['-I' fullfile(acados_folder, 'external' , 'blasfeo', 'include')];
@@ -236,11 +246,22 @@ else % gcc
                        ' ', strjoin(unique(c_files_path), ' '), ' -o ', out_lib];
 end
 
+
 compile_status = system(compile_command);
+
+%Store the PATH environment variable used during compile for error reporting
+envPath=getenv('PATH');
+
+%Reset the environment path variable to its original value
+%This is done before potentially raising an error to ensure that the path
+%environment variable is clean
+setenv('PATH',origEnvPath);
+
 if compile_status ~= 0
-    error('Compilation of model functions failed! %s %s\n%s\n\n', ...
+    error('Compilation of model functions failed! %s\n%s\n%s\n%s\n%s\n\n', ...
         'Please check the compile command above and the flags therein closely.',...
-        'Compile command was:', compile_command);
+        'Compile command was:', compile_command, ...
+        'Environment path was: ', envPath);
 end
 
 end


Hi,

Great to hear!

I think, the change you propose makes sense!

Probably this file should be changed similarly: https://github.com/acados/acados/blob/master/interfaces/acados_matlab_octave/sim_generate_casadi_ext_fun.m

This example tests both the integrator and OCP solver in Simulink: https://github.com/acados/acados/blob/master/examples/acados_matlab_octave/getting_started/simulink_example_advanced.m

Other than this, if you already have a solution for something like this, a PR is always welcome!

Ideally, you apply the change also in the other file and rebase onto the latest version.

We have CI tests for Simulink on Linux on Github Actions, which will run on the PR.
I think those should be sufficient to test the compatibility.

Best,
Jonathan

@FreyJo I have now had the time to make this branch ready, but I cannot push to the git-hub acados repo.

Can write access be granted or do you prefer that I make a fork?

Also I have made a matlab install script which automates Installation ā€” acados documentation along with a number of other steps which are needed to have a fully functioning install.

I plan to make a PR for that as well, but those changes might be slightly more controversial.

Yes, please fork the project and make a PR from there.
Also 2 seperate PRs for those things seem make sense.
I am not in the topic now, but will review the PRs soon!

1 Like