Skip to content

Commit

Permalink
Add precompiler definition FMI2_FUNCTION_PREFIX for static CMake FMUs (
Browse files Browse the repository at this point in the history
…#10509)

* Compile static CMake FMUs
* Add FMI2_FUNCTION_PREFIX to CMakeLists.txt
* Adding test to re-compile static FMU
  • Loading branch information
AnHeuermann committed Apr 13, 2023
1 parent cce0dbf commit 872d6a9
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 19 deletions.
24 changes: 21 additions & 3 deletions OMCompiler/Compiler/Script/CevalScriptBackend.mo
Expand Up @@ -3533,9 +3533,27 @@ algorithm
end if;
buildDir := "build_cmake_dynamic";
cmakeCall := Autoconf.cmake + " " + CMAKE_GENERATOR +
"-DFMI_INTERFACE_HEADER_FILES_DIRECTORY=" + defaultFmiIncludeDirectoy + " " +
CMAKE_BUILD_TYPE +
" ..";
CMAKE_BUILD_TYPE +
" ..";
cmd := "cd " + dquote + fmuSourceDir + dquote + " && " +
"mkdir " + buildDir + " && cd " + buildDir + " && " +
cmakeCall + " && " +
Autoconf.cmake + " --build . --target install && " +
"cd .. && rm -rf " + buildDir;
if 0 <> System.systemCall(cmd, outFile=logfile) then
Error.addMessage(Error.SIMULATOR_BUILD_ERROR, {System.readFile(logfile)});
fail();
end if;
then();
case {"static"}
algorithm
if isWindows then
CMAKE_GENERATOR := "-G " + dquote + "MSYS Makefiles" + dquote + " ";
end if;
buildDir := "build_cmake_dynamic";
cmakeCall := Autoconf.cmake + " " + CMAKE_GENERATOR +
CMAKE_BUILD_TYPE +
" ..";
cmd := "cd " + dquote + fmuSourceDir + dquote + " && " +
"mkdir " + buildDir + " && cd " + buildDir + " && " +
cmakeCall + " && " +
Expand Down
13 changes: 8 additions & 5 deletions OMCompiler/Compiler/SimCode/SimCodeMain.mo
Expand Up @@ -752,7 +752,7 @@ algorithm
Boolean needSundials = false;
String fileprefix;
String install_include_omc_dir, install_include_omc_c_dir, install_share_buildproject_dir, install_fmu_sources_dir, fmu_tmp_sources_dir;
String cmakelistsStr;
String cmakelistsStr, needCvode, cvodeDirectory;
list<String> sourceFiles, model_desc_src_files;
list<String> dgesv_sources, cminpack_sources, simrt_c_sundials_sources, simrt_linear_solver_sources, simrt_non_linear_solver_sources;
list<String> simrt_mixed_solver_sources, fmi_export_files, model_gen_files, model_all_gen_files, shared_source_files;
Expand Down Expand Up @@ -928,21 +928,24 @@ algorithm
cmakelistsStr := System.stringReplace(cmakelistsStr, "@FMU_NAME_IN@", simCode.fileNamePrefix);
_ := match (Flags.getConfigString(Flags.FMU_RUNTIME_DEPENDS))
case("none") algorithm
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "none");
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "\"none\"");
then();
case("modelica") algorithm
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "modelica");
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "\"modelica\"");
then();
case("all") algorithm
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "all");
cmakelistsStr := System.stringReplace(cmakelistsStr, "@RUNTIME_DEPENDENCIES_LEVEL@", "\"all\"");
then();
else algorithm
Error.addCompilerError("Unsupported value " + Flags.getConfigString(Flags.FMU_RUNTIME_DEPENDS) + "for compiler flag 'fmuRuntimeDepends'.");
then();
end match;

// Add external libraries and includes
cmakelistsStr := System.stringReplace(cmakelistsStr, "@NEED_CVODE@", SimCodeUtil.getCmakeSundialsLinkCode(simCode.fmiSimulationFlags));
cmakelistsStr := System.stringReplace(cmakelistsStr, "@FMI_INTERFACE_HEADER_FILES_DIRECTORY@", "\"" + Settings.getInstallationDirectoryPath() + "/include/omc/c/fmi" + "\"");
(needCvode, cvodeDirectory) := SimCodeUtil.getCmakeSundialsLinkCode(simCode.fmiSimulationFlags);
cmakelistsStr := System.stringReplace(cmakelistsStr, "@NEED_CVODE@", needCvode);
cmakelistsStr := System.stringReplace(cmakelistsStr, "@CVODE_DIRECTORY@", cvodeDirectory);
cmakelistsStr := System.stringReplace(cmakelistsStr, "@FMU_ADDITIONAL_LIBS@", SimCodeUtil.getCmakeLinkLibrariesCode(simCode.makefileParams.libs));
cmakelistsStr := System.stringReplace(cmakelistsStr, "@FMU_ADDITIONAL_INCLUDES@", SimCodeUtil.make2CMakeInclude(simCode.makefileParams.includes));

Expand Down
11 changes: 5 additions & 6 deletions OMCompiler/Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -15653,13 +15653,12 @@ end getCmakeLinkLibrariesCode;
public function getCmakeSundialsLinkCode
"Code for FMU CMakeLists.txt to specify if CVODE is needed."
input Option<SimCode.FmiSimulationFlags> fmiSimulationFlags;
output String code = "";
output String needCvode = "OFF";
output String cvodeDirectory = "\"\"";
algorithm
if not cvodeFmiFlagIsSet(fmiSimulationFlags) then
code := "set(NEED_CVODE FALSE)";
else
code := "set(NEED_CVODE TRUE)\n" +
"set(CVODE_DIRECTORY \"" + Settings.getInstallationDirectoryPath() + "/lib/${CMAKE_LIBRARY_ARCHITECTURE}/omc\")";
if cvodeFmiFlagIsSet(fmiSimulationFlags) then
needCvode := "ON";
cvodeDirectory := "\"" + Settings.getInstallationDirectoryPath() + "/lib/${CMAKE_LIBRARY_ARCHITECTURE}/omc\"";
end if;
end getCmakeSundialsLinkCode;

Expand Down
@@ -1,22 +1,44 @@

cmake_minimum_required(VERSION 3.5)

set(FMU_NAME @FMU_NAME_IN@)

project(${FMU_NAME})

# Specifies if CVODE is needed
@NEED_CVODE@
# FMU compilation options
set(BUILD_SHARED_LIBS
ON
CACHE BOOL
"Compile DLL/Shared Object binary object if 'ON', compile static binary object if 'OFF'.")
set(FMI_INTERFACE_HEADER_FILES_DIRECTORY
@FMI_INTERFACE_HEADER_FILES_DIRECTORY@
CACHE STRING
"Path to FMI header files containing fmi2Functions.h, fmi2FunctionTypes.h, fmi2TypesPlatforms.h")
set(RUNTIME_DEPENDENCIES_LEVEL
@RUNTIME_DEPENDENCIES_LEVEL@
CACHE STRING
"Add modelica runtime dependencies to FMU if set to 'modelica'. Add system runtime dependencies as well if set to 'all'.")
set(NEED_CVODE
@NEED_CVODE@
CACHE BOOL
"FMU needs to link to SUNDIALS CVODE if 'ON'. Used for CoSimulation FMUs that want to use CVODE as integrator. Use 'OFF' otherwise.")
set(CVODE_DIRECTORY
@CVODE_DIRECTORY@
CACHE STRING
"IF CVODE is needed provide a directory where to find it.")

# Test if RUNTIME_DEPENDENCIES is needed and available
set(RUNTIME_DEPENDENCIES_LEVEL @RUNTIME_DEPENDENCIES_LEVEL@)
if(${CMAKE_VERSION} VERSION_LESS "3.21" AND NOT ${RUNTIME_DEPENDENCIES_LEVEL} STREQUAL "none")
message(FATAL_ERROR
"--fmuRuntimeDepends=${RUNTIME_DEPENDENCIES_LEVEL} requiers CMake version 3.21 or higher.\n"
"You are running version ${CMAKE_VERSION}.\n"
"Use OpenModelica compiler flag '--fmuRuntimeDepends=none' to disable including runtime dependencies into FMU.")
endif()

# Create position independent code for static libraries
if(NOT BUILD_SHARED_LIBS)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
endif()

# FMI header files
if(NOT FMI_INTERFACE_HEADER_FILES_DIRECTORY)
message(FATAL_ERROR "No FMI export headers provided. Set -DFMI_INTERFACE_HEADER_FILES_DIRECTORY=/path/to/fmi/headers")
Expand Down Expand Up @@ -71,6 +93,8 @@ set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/../binaries/${FMU_TARGET_PL
set(CMAKE_INSTALL_LIBDIR ${CMAKE_INSTALL_PREFIX})
set(CMAKE_INSTALL_BINDIR ${CMAKE_INSTALL_PREFIX})
set(CMAKE_SHARED_LIBRARY_PREFIX "")
set(CMAKE_STATIC_LIBRARY_PREFIX "")
message(STATUS "Install directory: ${CMAKE_INSTALL_PREFIX}")

# Set RPATH
if(APPLE)
Expand All @@ -83,7 +107,7 @@ else()
endif()

# Target library
add_library(${FMU_NAME} SHARED
add_library(${FMU_NAME}
${FMU_RUNTIME_SOURCES}
${FMU_GENERATED_MODEL_SOURCES})

Expand All @@ -100,6 +124,7 @@ endif()
target_link_libraries(${FMU_NAME} PRIVATE m Threads::Threads)
@FMU_ADDITIONAL_LIBS@
if(${NEED_CVODE})
message(STATUS "CVODE_DIRECTORY: ${CVODE_DIRECTORY}")
find_library(SUNDIALS_CVODE_LIBRARY sundials_cvode
PATHS ${CVODE_DIRECTORY}
NO_DEFAULT_PATH)
Expand All @@ -121,6 +146,10 @@ target_include_directories(${FMU_NAME} PRIVATE ${FMI_INTERFACE_HEADER_FILES_DIRE

# Set compiler definitions
target_compile_definitions(${FMU_NAME} PRIVATE OMC_MINIMAL_RUNTIME=1;OMC_FMI_RUNTIME=1;CMINPACK_NO_DLL${WITH_SUNDIALS})
if(NOT BUILD_SHARED_LIBS)
# Define FMI2_FUNCTION_PREFIX if FMU compiled statically
target_compile_definitions(${FMU_NAME} PRIVATE FMI2_FUNCTION_PREFIX=${FMU_NAME}_)
endif()

# Install target
if(RUNTIME_DEPENDENCIES_LEVEL STREQUAL "all")
Expand Down
1 change: 1 addition & 0 deletions testsuite/openmodelica/fmi/CoSimulation/2.0/Makefile
Expand Up @@ -6,6 +6,7 @@ ExportCvodeFmu_dynamic.mos \
ExportCvodeFmu_static.mos \
fmi_interpolation_01.mos \
FmuExportFlags.mos \
RecompileSourceCodeFMU.mos \
simpleStiffFMU.mos \
issue10523.mos \

Expand Down
@@ -0,0 +1,53 @@
// name: RecompileSourceCodeFMU
// keywords: fmu export simulation flags
// status: correct
// teardown_command: rm -rf Test_SinSource* reCompile.log Test.SinSource.fmu
//
// Export SinSource as 2.0 CS FMU with CVODE solver and re-compile FMU with static library

// Generate FMU
loadModel(Modelica, {"4.0.0"}); getErrorString();
loadString("
package Test
model SinSource
parameter Real amp=1;
parameter Real freq=1;
Modelica.Blocks.Interfaces.RealOutput y;
protected
Modelica.Blocks.Sources.Sine sine(amplitude = amp, f = freq);
equation
connect(sine.y, y);
end SinSource;
end Test;
"); getErrorString();

setCommandLineOptions("--fmuCMakeBuild=true --fmiFlags=s:cvode --fmuRuntimeDepends=none"); getErrorString();
buildModelFMU(Test.SinSource, version="2.0", fmuType ="cs", platforms={"static"}); getErrorString();

// Check if CMake can re-compile a static library
system("rm -rf Test_SinSource_FMU && unzip -qq Test.SinSource.fmu -d Test_SinSource_FMU && mkdir Test_SinSource_FMU/sources/build_cmake", outputFile="reCompile.log"); getErrorString();
//readFile("reCompile.log");
system("cd Test_SinSource_FMU/sources/build_cmake && cmake .. -DBUILD_SHARED_LIBS=OFF && cmake --build . && make install", outputFile="reCompile.log"); getErrorString();
//readFile("reCompile.log");

// Check if static library was compiled and that it used FMI2_FUNCTION_PREFIX=Test_SinSource_FMU for function names
// Has to return "Test_SinSource_fmi2GetReal"
system("nm Test_SinSource_FMU/binaries/linux64/Test_SinSource.a | grep -wo Test_SinSource_fmi2GetReal"); getErrorString();

// Result:
// true
// ""
// true
// ""
// true
// ""
// "Test.SinSource.fmu"
// ""
// 0
// ""
// 0
// ""
// Test_SinSource_fmi2GetReal
// 0
// ""
// endResult

0 comments on commit 872d6a9

Please sign in to comment.