Compilation Problems for generated code for SimScape Model

11 views (last 30 days)
Hello! I basically have a similar problem as was asked before but never has been answered (although I have some extra errors): https://de.mathworks.com/matlabcentral/answers/231601-how-can-i-solve-simscape-c-code-linker-problems
I am trying to compile generated code from SimScape (Matlab2015b) and receive the following errors. Any hint on what could be the cause? Missing files maybe? I included all the .c files generated and the packages exported during code-generation. For testing I also generated a working S-Function of the SimScape Model (in 2015b still possible) and tried to recompile it and received the same errors.
Creating library Test60_sf.lib and object Test60_sf.exp
Test60_sf.obj : error LNK2019: unresolved external symbol pm_default_allocator referenced in function local_sim_data_destroy
Test60_3107f5dc_1.obj : error LNK2001: unresolved external symbol pm_default_allocator
Test60_sf.obj : error LNK2019: unresolved external symbol nesl_get_registry referenced in function nesl_lease_simulator
Test60_sf.obj : error LNK2019: unresolved external symbol neu_create_diagnostic_tree_printer referenced in function rtw_diagnostics_msg
Test60_sf.obj : error LNK2019: unresolved external symbol neu_create_diagnostic_manager referenced in function rtw_create_diagnostics
Test60_3107f5dc_1.obj : error LNK2019: unresolved external symbol ne_dae_create referenced in function Test60_3107f5dc_1_dae
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_F referenced in function ds_f
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_DF_0_1 referenced in function ds_dxf
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_DF_1_1 referenced in function ds_dxf
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_ZC_0 referenced in function ds_mode
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_ZC_1 referenced in function ds_mode
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_ZC_2 referenced in function ds_mode
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_ZC_3 referenced in function ds_mode
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_MODE_3 referenced in function ds_mode
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_MODE_2 referenced in function ds_mode
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_MODE_1 referenced in function ds_mode
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_MODE_0 referenced in function ds_mode
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_cleanup referenced in function release_reference
Test60_3107f5dc_1_ds.obj : error LNK2019: unresolved external symbol tlu2_eq_setup referenced in function Test60_3107f5dc_1_dae_ds
Test60_3107f5dc_1_gateway.obj : error LNK2019: unresolved external symbol nesl_register_simulator_group referenced in function Test60_3107f5dc_1_gateway
Test60_3107f5dc_1_gateway.obj : error LNK2019: unresolved external symbol mc_get_csparse_linear_algebra referenced in function Test60_3107f5dc_1_gateway
Test60_sf.mexw64 : fatal error LNK1120: 20 unresolved externals
Thank you!
Matlab2015b, SDK7.1
  1 Comment
Simon Silge
Simon Silge on 9 Jul 2018
For example pm_default_allocator is a header file (pm_default_allocator.h) that was exported as package for the generated code, and included for the compilation. Nontheless the error
Test60_sf.obj : error LNK2019: unresolved external symbol pm_default_allocator referenced in function local_sim_data_destroy
appears.

Sign in to comment.

Answers (3)

Simon Silge
Simon Silge on 31 Jul 2018
Maybe someone one day will need this so I add some more info:
I was contrary to the information found here in some threads able to generate an S-Function from C-Code generated from a SimScape model without a lot of work (only finding out how was a lot of work, and doing it the first time, but actually you do not need to know to code or anything)...so I was able to generate a SimScape Model's S-Function with an extra step of first doing the C-Code. I do not know why SimScape S-Functions are not supported anymore, but this is the "work around".
And additionally I was even able to use this compiled S-Function in an older Version of Matlab (2018 to 2015b).
What do you need: Prepare your SimScape Model, generate C-Code, use the S-Function Builder to create an S-Function from it by connecting the inputs and outputs of C-Code and S-Function, linking all the correct files and paths (most difficult part), call the _step() and _initialize() functions of the C-code at the right point of the S-function. Here more detailed:
1. All outputs and inputs have to be transferred to Simulink Signals, not SimScape
2. Use local fixed time step solver for Simscape Model and same timestep for the solver settings of the Simulink Solver (under Configuration Parameters)
3. Build C-Code for the model (I used grt.tlc as target)
Now comes the "tricky" part if you want to create an S-Function from the C-Code. You need:
4. S-Function Builder
5. Choose Sample Mode Discrete and sample time same as in the model
6. Create the desired inputs and outputs under "Data Properties"
7. "Libraries" --> left side (Library/Object/Source Files): Here all the C-files in the generated code folder have to be mentioned (each one in a new line), maybe rt_logging.c and rt_logging.h have to be copied from your root Matlab folder (if you had Matlab-logging activated) to your generated C-Code folder and rt_logging.c added to the Libraries list. Also you have to define the folders where neccessary libraries and header files lie (you can find that out by looking at the .mk file in your folder, another way might be compiling use PackNGo, extract the ZIP with all the packages and add all the folders and subfolders (did not try this)). How to define these search paths you can find in the documentation of the SFunction Builder Block (INC_PATH, LIB_PATH) And add the neccesary libraries (also in the .mk file defined). In my case in the 2015b version the libraries were e.g. -
ssc_sli_rtwsfcn_vcx64.lib
ssc_core_rtwsfcn_vcx64.lib
ne_rtwsfcn_vcx64.lib
mc_rtwsfcn_vcx64.lib
ex_rtwsfcn_vcx64.lib
pm_rtwsfcn_vcx64.lib
and their paths are (include with LIB_PATH):
"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\simscape\engine\sli\lib\win64"
"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\simscape\engine\core\lib\win64"
"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\network_engine\lib\win64"
"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\network_engine\lib\win64"
"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\math\core\lib\win64"
"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\external\library\lib\win64"
"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\foundation\core\lib\win64"
As said also include all the "Include" paths where it will search for header files (.h files). In this Step 7 is where you will get most problems and nearly every problem will be because of a missing or wrong path, a missing library or c-file.
8. "Libraries" --> right side add #include "MyModel.h" with the Name of your Model
9. Depending on your version the SFunction Builder has a "Start" section where you copy:
MyModel_initialize();
(replace with your model name). If you don't have that section, you will have to paste it by hand in the created SFunction files afterwards und recompile the S-Function with mex and again all the neccessary c files and paths.
10. Here you connect the inputs and outputs of the S-Function you defined under "Data Properties" with the ones of the C-Coded Model. The Model has always for Inputs a "_U" after your modelname, following the name of the Input you had in the Model you coded, e.g:
MyModel_U.Input1
For Outputs it is "_Y". First connect all inputs, then call the MyModel_step() function (again replace with your Model Name), then connect all the outputs.
MyModel_U.In1 = u0[0];
MyModel_step();
y0[0] = MyModel_Y.Out1;
11. Build! Probably you will get some error about missing links or files or unresolved external symbols --> search for the missing files or the files that use the routines not found (unresolved in your Matlab Root or your Generated C-Code folder, add the paths with INC_PATH or LIB_PATH --> Try again ... Every error I had was due to missing / false paths included or missing .c or .lib files. Also there is one error which you can ignore becuase the reason for it lies in the other errors shown (missing links/paths/files ...):
LINK : warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs; use /NODEFAULTLIB:library
I hope it helps someone!
  1 Comment
Yougzz
Yougzz on 9 Oct 2019
I have a quetsion about your example : What did you choose as Simulink solver ?
Because you can't choose discrete solver if you use PS-S converter and S-PS converter beacuse they introduce continuous states ?
I'm trying to generate code from a simscape model but I need to use a discrete solver for the global Simulink model and I can't because of these blocs.

Sign in to comment.


Simon Silge
Simon Silge on 16 Jul 2018
Okay I have now finally managed to solve the problem. Under the model configurations / code generation you can activate the creation of a make-file (.mk), at least for s-functions. Otherwise you may have to search for another possibility to create it (if there is). This file probably helps you if you want to compile c-code generated.
For my test I needed 1. Source files (.c) from "MODULES" in the make file 2. The Paths under "Include/Lib Path" 3. The libraries under "Additional Libraries", always the first option of the IF case e.g. "ssc_sli_rtwsfcn_vcx64.lib" For these I added the directories where they are as well as search paths.
As a reminder: I am at the moment just trying to recompile an S-Function generated for a SimScape model (which was still possible in 2015b) from its source code. When using mex to compile a S-Function Source File you need to use "" when adding the paths in case your path has a space within. For example: mex sourceFile.c -I"C:\Program Files\MATLAB\toolbox\physmod\network_engine\c"
My final mex command to recompile was:
mex Test8_sf.c Test8_63bfb668_1.c Test8_63bfb668_1_ds.c Test8_63bfb668_1_gateway.c ...
rtGetInf.c rtGetNaN.c rt_backsubrr_dbl.c rt_forwardsubrr_dbl.c rt_lu_real.c rt_matrixlib_dbl.c ...
-L"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\simscape\engine\sli\lib\win64" ...
-L"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\simscape\engine\core\lib\win64" ...
-L"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\network_engine\lib\win64" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\network_engine\lib\win64" ...
-L"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\math\core\lib\win64" ...
-L"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\external\library\lib\win64" ...
-L"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\foundation\core\lib\win64" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\simulink\include" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\extern\include" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\rtw\c\src" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\simscape\engine\sli\c" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\simscape\engine\core\c" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\simscape\compiler\core\c" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\network_engine\c" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\math\core\c" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\external\library\c" ...
-I"C:\Program Files\MATLAB_v86_r15b_x64\toolbox\physmod\common\foundation\core\c" ...
-I"C:\LocalWorkSpace\TestsCompilation\Test8" ...
-lssc_sli_rtwsfcn_vcx64.lib ...
-lssc_core_rtwsfcn_vcx64.lib ...
-lne_rtwsfcn_vcx64.lib ...
-lmc_rtwsfcn_vcx64.lib ...
-lex_rtwsfcn_vcx64.lib ...
-lpm_rtwsfcn_vcx64.lib

em
em on 14 Nov 2022
I had a similar experience. This is so frustrating, until you get it working, then it's super easy to do again.
What worked for me on 2018b:
  • Generate simscape (or other simulink model) code. Enable the option to create a main c file that calls the function. mine was called ert_main.c. Compiling this allows you to run the generated code on your pc (without simulink), and it serves as a good template.
  • go find the .mk file that was generated. This is your makefile. Inside this makefile, it specifies the include paths, object files, and libraries that you need.
  • When using the s-function builder, the tricky part is the libraries list. For each of the include paths in your makefile, add it to the s-function libraries list as INC_PATH [filepath]. Next, add each of the filepaths for the object files from the makefile. Note that by default, the makefile just mentions the filename, not the full path. You need to add the full path for each object to the libraries list as [full filepath].obj. Last, you need to add the .lib files. You can find these as the libraries in the makefile. Just paste each full filepath for each library to the s-function builder.
  • Note that you do not actually need to add any of the source files (.c) to the libraries list inside the s-function builder. The .obj files serve this purpose.
  • You will need to remove the ert_main.obj dependancy, as your s-function builder is replacing the need for this file.
  • Copy the includes from ert_main.c to the includes section in the s-function builder
  • You will need to mention the global variables from your generated code in the extern function section. You do this just like any other C global definition.
  • I actually had conflicts with the tmwtypes.h file which was inside programfiles/matlab. I just commented out these conflicts and it worked for me!
  • from there, mapping the inputs and outputs are pretty straightforward!

Community Treasure Hunt

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

Start Hunting!