Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#3733 closed defect (fixed)

C FMI export does not work with external functions

Reported by: Rüdiger Franke Owned by: Adeel Asghar
Priority: blocker Milestone: 1.9.4
Component: FMI Version: v1.9.4-dev-nightly
Keywords: Cc: Martin Sjölund

Description

The new C FMI export uses a temporary build directory. This is why external includes are not found. Assume the following two files in your working directory:

ExternalFunction.mo:

package ExternalFunction
  function mySquare
    input Real x;
    output Real y;
    external "C" y = mysquare(x);
    annotation(Include="#include \"mysquare.c\"");  
  end mySquare;
  model Test
    input Real x = 0;
    output Real x2 = mySquare(5 + x);
  end Test;
end ExternalFunction;

mysquare.c:

double mysquare(double x)
{
  return x*x;
}

The model ExternalFunction.Test simulates. C FMI export failes with the error:

ExternalFunction_Test_includes.h:4:22: fatal error: mysquare.c: No such file or directory
 #include "mysquare.c"

This is because the subdirectory ExternalFunction_Test.fmutmp/sources was created for the compilation of the FMU.

In the simplest case the FMU Makefile could be extended with a "-I../.." directive -- or not use a temporary build directory. A more advanced solution might copy all included files into the sources directory.

Anyhow, FMI export should work for a model that simulates. It was working before the introduction of source code FMUs.

Change History (6)

in reply to:  description comment:1 by Martin Sjölund, 9 years ago

Replying to rfranke:

In the simplest case the FMU Makefile could be extended with a "-I../.." directive -- or not use a temporary build directory. A more advanced solution might copy all included files into the sources directory.

Anyhow, FMI export should work for a model that simulates. It was working before the introduction of source code FMUs.

You need to use the IncludeDirectory annotation in that case. It is just luck that made the simulation builds in the first place. buildModel/simulate also has a tmp-directory option, which is is not used by default. When enabled, this model would also fail since the place we look for the include is ./Resources/Include. In order to copy the files into the FMU (which is planned), you also need the IncludeDirectory option so that we know where to look for the file.

comment:2 by Rüdiger Franke, 9 years ago

Well, the complete compilation command is:

gcc -fPIC -O0 -falign-functions -march=native  -fno-stack-protector -Wno-parentheses-equality -Wno-unused-variable -fPIC -Iinclude/ -Iinclude/fmi2 -I.    -c -o ExternalFunction_Test_functions.o ExternalFunction_Test_functions.c
In file included from ExternalFunction_Test_functions.c:7:0:
ExternalFunction_Test_includes.h:4:22: fatal error: mysquare.c: No such file or directory
 #include "mysquare.c"

I don't see any Resources/Include path in the compiler call. The Modelica spec says:

The annotation(IncludeDirectory="modelica://LibraryName/Resources/Include"), used
to specify a location for header files. The preceding one is the default and need 
not be specified...

So, how can one set up the above example to make it work with FMU export in OpenModelica 1.9.4?

comment:3 by Martin Sjölund, 9 years ago

The -I flag is only added if the directory exists. Try:

package ExternalFunction
  function mySquare
    input Real x;
    output Real y;
    external "C" y = mysquare(x);
    annotation(Include="#include \"mysquare.c\"", IncludeDirectory="modelica://ExternalFunction");
  end mySquare;
  model Test
    input Real x = 0;
    output Real x2 = mySquare(5 + x);
  end Test;
end ExternalFunction;

comment:4 by Rüdiger Franke, 9 years ago

Resolution: fixed
Status: newclosed

This works. Thanks!

comment:5 by Martin Sjölund, 9 years ago

Milestone: 1.9.41.9.4-1.9.x

Milestone renamed

comment:6 by Martin Sjölund, 9 years ago

Milestone: 1.9.4-1.9.x1.9.4

Milestone renamed

Note: See TracTickets for help on using tickets.