Skip to content

Commit baa7680

Browse files
committed
Merge branch 'master' into examples
2 parents d1d87ed + 5a875dc commit baa7680

11 files changed

Lines changed: 25755 additions & 57 deletions

File tree

cmake/generate_fmu.cmake

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,12 @@ function(generateFMU modelIdentifier)
4040
endif ()
4141

4242

43-
# create an internal object library from provided sources
44-
set(model_objects_target "${modelIdentifier}_fmu_objects")
45-
46-
add_library(${model_objects_target} OBJECT ${FMU_SOURCES})
47-
target_include_directories(${model_objects_target} PUBLIC "${_fmu4cpp_root}/export/include")
48-
# apply user-provided include dirs to the object target
49-
if (FMU_INCLUDE_DIRS)
50-
target_include_directories(${model_objects_target} PRIVATE ${FMU_INCLUDE_DIRS})
51-
endif ()
52-
# apply user-provided link targets to the object target
53-
if (FMU_LINK_TARGETS)
54-
target_link_libraries(${model_objects_target} PRIVATE ${FMU_LINK_TARGETS})
55-
endif ()
56-
# apply user-provided compile definitions to the object target
57-
if (FMU_COMPILE_DEFINITIONS)
58-
target_compile_definitions(${model_objects_target} PRIVATE ${FMU_COMPILE_DEFINITIONS})
59-
endif ()
60-
set_target_properties(${model_objects_target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
61-
62-
6343
foreach (fmiVersion IN LISTS FMU_FMI_VERSIONS)
6444

65-
# versioned shared library target built from object libraries
45+
set(fmuOutputDir "${fmuResultDir}/${fmiVersion}")
46+
set(modelOutputDir "${fmuOutputDir}/${modelIdentifier}")
47+
set(binaryOutputDir "$<1:${modelOutputDir}/binaries/${TARGET_PLATFORM}>")
48+
6649
set(versionTarget "${modelIdentifier}_${fmiVersion}")
6750

6851
set(FMU4CPP_MODEL_IDENTIFIER "${versionTarget}")
@@ -75,37 +58,49 @@ function(generateFMU modelIdentifier)
7558

7659
_getTargetPlatform(${fmiVersion})
7760

61+
set(VERSIONS_DEFS "")
7862
if (fmiVersion STREQUAL "fmi2")
63+
list(APPEND VERSION_DEFS "FMI2")
64+
target_compile_definitions(fmu4cpp_fmi2 PUBLIC "FMI2")
7965
list(APPEND VERSION_OBJECTS "$<TARGET_OBJECTS:fmu4cpp_fmi2>")
80-
list(APPEND VERSION_DEFS FMI2)
8166
elseif (fmiVersion STREQUAL "fmi3")
67+
list(APPEND VERSION_DEFS "FMI3")
68+
target_compile_definitions(fmu4cpp_fmi3 PUBLIC "FMI3")
8269
list(APPEND VERSION_OBJECTS "$<TARGET_OBJECTS:fmu4cpp_fmi3>")
83-
list(APPEND VERSION_DEFS FMI3)
8470
endif ()
8571

86-
set(fmuOutputDir "${fmuResultDir}/${fmiVersion}")
87-
set(modelOutputDir "${fmuOutputDir}/${modelIdentifier}")
88-
set(binaryOutputDir "$<1:${modelOutputDir}/binaries/${TARGET_PLATFORM}>")
89-
9072
add_library(${versionTarget} SHARED
9173
"$<TARGET_OBJECTS:fmu4cpp_base>"
92-
"$<TARGET_OBJECTS:${model_objects_target}>"
74+
"${FMU_SOURCES}"
9375
"${VERSION_OBJECTS}"
9476
)
95-
target_include_directories(${versionTarget} PRIVATE "${_fmu4cpp_root}/export/include")
96-
target_compile_definitions(${versionTarget} PRIVATE ${VERSION_DEFS})
77+
target_include_directories(${versionTarget}
78+
PRIVATE
79+
"${_fmu4cpp_root}/export/include"
80+
"${FMU_INCLUDE_DIRS}"
81+
)
82+
83+
target_compile_definitions(${versionTarget}
84+
PUBLIC
85+
${VERSION_DEFS}
86+
${FMU_COMPILE_DEFINITIONS}
87+
)
88+
9789

98-
# link user-provided link targets (must be propagated to the final shared lib)
9990
if (FMU_LINK_TARGETS)
91+
target_link_libraries(${versionTarget} PRIVATE ${FMU_LINK_TARGETS})
10092
_bundle_link_libraries()
10193
endif ()
10294

103-
# if user provided compile definitions, also ensure final target sees them (optional)
104-
if (FMU_COMPILE_DEFINITIONS)
105-
target_compile_definitions(${model_objects_target} PRIVATE ${FMU_COMPILE_DEFINITIONS})
106-
target_compile_definitions(${versionTarget} PRIVATE ${FMU_COMPILE_DEFINITIONS})
95+
if (FMU_WITH_SOURCES)
96+
if (fmiVersion STREQUAL "fmi2")
97+
message(WARNING "[generateFMU-fmi2] FMU_WITH_SOURCES is not supported for fmi2; skipping source inclusion for model '${modelIdentifier}'")
98+
else ()
99+
_include_sources_in_fmu()
100+
endif ()
107101
endif ()
108102

103+
109104
if (WIN32)
110105
set_target_properties(${versionTarget}
111106
PROPERTIES
@@ -119,13 +114,6 @@ function(generateFMU modelIdentifier)
119114
)
120115
endif ()
121116

122-
if (FMU_WITH_SOURCES)
123-
if (fmiVersion STREQUAL "fmi2")
124-
message(WARNING "[generateFMU-fmi2] FMU_WITH_SOURCES is not supported for fmi2; skipping source inclusion for model '${modelIdentifier}'")
125-
else ()
126-
_include_sources_in_fmu()
127-
endif ()
128-
endif ()
129117

130118
# Generate modelDescription.xml
131119
add_custom_command(TARGET ${versionTarget} POST_BUILD

export/include/fmu4cpp/fmu_base.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ namespace fmu4cpp {
7676
return std::nullopt;
7777
}
7878

79+
[[nodiscard]] std::optional<BinaryVariable> get_binary_variable(const std::string &name) const {
80+
for (const auto &v: binary_) {
81+
if (v.name() == name) return v;
82+
}
83+
return std::nullopt;
84+
}
85+
7986
void enter_initialisation_mode(double start, std::optional<double> stop, std::optional<double> tolerance) {
8087
time_ = start;
8188
stop_ = stop;
@@ -196,6 +203,20 @@ namespace fmu4cpp {
196203
}
197204
}
198205

206+
void set_binary(const unsigned int vr[], size_t nvr, const size_t valueSizes[], const uint8_t* const value[]) {
207+
#ifdef FMI2
208+
static_assert("set_binary not available for FMI2");
209+
#endif
210+
211+
for (unsigned i = 0; i < nvr; i++) {
212+
const auto ref = vr[i];
213+
const auto idx = vrToBinaryIndices_.at(ref);
214+
const uint8_t *ptr = value[i];
215+
const size_t len = valueSizes[i];
216+
binary_[idx].set(std::string(reinterpret_cast<const char*>(ptr), len));
217+
}
218+
}
219+
199220
[[nodiscard]] std::string guid() const;
200221

201222
[[nodiscard]] std::string make_description() const;
@@ -246,10 +267,17 @@ namespace fmu4cpp {
246267
const std::function<std::string()> &getter,
247268
const std::optional<std::function<void(std::string)>> &setter = std::nullopt);
248269

270+
BinaryVariable binary(const std::string &name, std::string *ptr, const std::function<void(std::string)> &onChange = {});
271+
BinaryVariable binary(const std::string &name,
272+
const std::function<std::string()> &getter,
273+
const std::optional<std::function<void(std::string)>> &setter = std::nullopt);
274+
249275
void register_variable(IntVariable v);
250276
void register_variable(RealVariable v);
251277
void register_variable(BoolVariable v);
252278
void register_variable(StringVariable v);
279+
void register_variable(BinaryVariable v);
280+
253281

254282
virtual void enter_initialisation_mode();
255283
virtual bool do_step(double dt) = 0;
@@ -283,6 +311,11 @@ namespace fmu4cpp {
283311
std::vector<StringVariable> strings_;
284312
std::vector<std::string> stringBuffer_;
285313
std::unordered_map<unsigned int, size_t> vrToStringIndices_;
314+
315+
std::vector<BinaryVariable> binary_;
316+
std::vector<std::string> binaryBuffer_;
317+
std::unordered_map<unsigned int, size_t> vrToBinaryIndices_;
318+
286319
};
287320

288321

export/include/fmu4cpp/fmu_variable.hpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ namespace fmu4cpp {
263263
: Variable(name, vr, index, getter, setter) {}
264264
};
265265

266-
class StringVariable final : public Variable<std::string, StringVariable> {
266+
class StringVariable : public Variable<std::string, StringVariable> {
267267

268268
public:
269269
StringVariable(
@@ -279,6 +279,22 @@ namespace fmu4cpp {
279279
: Variable(name, vr, index, getter, setter) {}
280280
};
281281

282+
class BinaryVariable : public Variable<std::string, BinaryVariable> {
283+
284+
public:
285+
BinaryVariable(
286+
const std::string &name,
287+
unsigned int vr, size_t index, std::string *ptr, const std::function<void(std::string)> &onChange)
288+
: Variable(name, vr, index, ptr, onChange) {}
289+
290+
BinaryVariable(
291+
const std::string &name,
292+
unsigned int vr, size_t index,
293+
const std::function<std::string()> &getter,
294+
const std::optional<std::function<void(std::string)>> &setter)
295+
: Variable(name, vr, index, getter, setter) {}
296+
};
297+
282298
bool requires_start(const VariableBase &v);
283299

284300
}// namespace fmu4cpp

export/src/fmu4cpp/fmi3/fmi3.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,7 @@ fmi3Status fmi3SetString(
511511

512512
fmi3Status fmi3GetBinary(fmi3Instance c,
513513
const fmi3ValueReference valueReferences[],
514-
size_t nValueReferences,
514+
size_t nvr,
515515
size_t valueSizes[],
516516
fmi3Binary values[],
517517
size_t nValues) {
@@ -523,16 +523,25 @@ fmi3Status fmi3GetBinary(fmi3Instance c,
523523
}
524524

525525
fmi3Status fmi3SetBinary(fmi3Instance c,
526-
const fmi3ValueReference valueReferences[],
527-
size_t nValueReferences,
526+
const fmi3ValueReference vr[],
527+
size_t nvr,
528528
const size_t valueSizes[],
529529
const fmi3Binary values[],
530530
size_t nValues) {
531531

532532
const auto component = static_cast<Fmi3Component *>(c);
533-
534-
component->logger->log(fmiError, "Unsupported function fmi3SetBinary");
535-
return fmi3Error;
533+
try {
534+
component->slave->set_binary(vr, nvr, valueSizes, values);
535+
return fmi3OK;
536+
} catch (const fmu4cpp::fatal_error &ex) {
537+
component->logger->log(fmiFatal, ex.what());
538+
component->state = Fmi3Component::State::Invalid;
539+
return fmi3Fatal;
540+
} catch (const std::exception &ex) {
541+
component->logger->log(fmiError, ex.what());
542+
component->state = Fmi3Component::State::Terminated;
543+
return fmi3Error;
544+
}
536545
}
537546

538547
NOT_IMPLEMENTED_SETTER(UInt8);

export/src/fmu4cpp/fmu_base.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ namespace fmu4cpp {
6868
return {name, vr, numVariables_, getter, setter};
6969
}
7070

71+
BinaryVariable fmu_base::binary(const std::string &name, std::string *ptr, const std::function<void(std::string)> &onChange) {
72+
const auto vr = static_cast<unsigned int>(numVariables_++);
73+
return {name, vr, numVariables_, ptr, onChange};
74+
}
75+
76+
BinaryVariable fmu_base::binary(const std::string &name, const std::function<std::string()> &getter, const std::optional<std::function<void(std::string)>> &setter) {
77+
const auto vr = static_cast<unsigned int>(numVariables_++);
78+
return {name, vr, numVariables_, getter, setter};
79+
}
80+
7181
void fmu_base::register_variable(IntVariable v) {
7282
integers_.emplace_back(std::move(v));
7383
vrToIntegerIndices_.emplace(v.value_reference(), integers_.size() - 1);
@@ -88,6 +98,11 @@ namespace fmu4cpp {
8898
vrToStringIndices_.emplace(v.value_reference(), strings_.size() - 1);
8999
}
90100

101+
void fmu_base::register_variable(BinaryVariable v) {
102+
binary_.emplace_back(std::move(v));
103+
vrToBinaryIndices_.emplace(v.value_reference(), binary_.size() - 1);
104+
}
105+
91106
[[maybe_unused]] std::string fmu_base::guid() const {
92107
const model_info info = get_model_info();
93108
const std::vector content{

export/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ function(make_test fmi_version modelIdentifier sources)
1111
)
1212
target_include_directories(${target_name}
1313
PRIVATE
14+
"${PROJECT_SOURCE_DIR}/export/tests/external"
1415
"${PROJECT_SOURCE_DIR}/export/include"
1516
"${PROJECT_SOURCE_DIR}/export/src"
1617
)

export/tests/basic_test.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
class Model : public fmu4cpp::fmu_base {
88

99
public:
10-
explicit Model(const fmu4cpp::fmu_data &data) : fmu_base(data) {
10+
FMU4CPP_CTOR(Model) {
1111

1212
register_variable(real("myReal", &real_)
1313
.setCausality(fmu4cpp::causality_t::OUTPUT));
@@ -37,15 +37,14 @@ class Model : public fmu4cpp::fmu_base {
3737
}
3838

3939
private:
40-
bool boolean_;
41-
int integer_;
42-
double real_;
40+
bool boolean_{};
41+
int integer_{};
42+
double real_{};
4343
std::string str_;
4444
};
4545

4646
fmu4cpp::model_info fmu4cpp::get_model_info() {
47-
model_info m;
48-
return m;
47+
return {};
4948
}
5049

5150
std::string fmu4cpp::model_identifier() {

0 commit comments

Comments
 (0)