Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#3733 closed defect (fixed)

C FMI export does not work with external functions

Reported by: rfranke Owned by: adeas31
Priority: blocker Milestone: 1.9.4
Component: FMI Version: v1.9.4-dev-nightly
Keywords: Cc: sjoelund.se

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)

comment:1 in reply to: ↑ description Changed 9 years ago by sjoelund.se

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 Changed 9 years ago by rfranke

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 Changed 9 years ago by sjoelund.se

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 Changed 9 years ago by rfranke

  • Resolution set to fixed
  • Status changed from new to closed

This works. Thanks!

comment:5 Changed 8 years ago by sjoelund.se

  • Milestone changed from 1.9.4 to 1.9.4-1.9.x

Milestone renamed

comment:6 Changed 8 years ago by sjoelund.se

  • Milestone changed from 1.9.4-1.9.x to 1.9.4

Milestone renamed

Note: See TracTickets for help on using tickets.