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