diff --git a/core/src/main/java/org/lflang/generator/python/PythonGenerator.java b/core/src/main/java/org/lflang/generator/python/PythonGenerator.java index 5bbd0de287..4f6ae54b30 100644 --- a/core/src/main/java/org/lflang/generator/python/PythonGenerator.java +++ b/core/src/main/java/org/lflang/generator/python/PythonGenerator.java @@ -61,6 +61,7 @@ import org.lflang.lf.Reactor; import org.lflang.target.Target; import org.lflang.target.property.ProtobufsProperty; +import org.lflang.target.property.PythonVersionProperty; import org.lflang.util.FileUtil; import org.lflang.util.LFCommand; import org.lflang.util.StringUtil; @@ -88,6 +89,7 @@ public class PythonGenerator extends CGenerator { private final List pythonRequiredModules = new ArrayList<>(); private final PythonTypes types; + private static String pythonVersion; public PythonGenerator(LFGeneratorContext context) { this( @@ -275,6 +277,7 @@ protected String generateTopLevelPreambles(Reactor ignored) { @Override protected void handleProtoFiles() { + pythonVersion = targetConfig.get(PythonVersionProperty.INSTANCE); for (String name : targetConfig.get(ProtobufsProperty.INSTANCE)) { this.processProtoFile(name); int dotIndex = name.lastIndexOf("."); @@ -557,34 +560,36 @@ protected void additionalPostProcessingForModes() { } private static String setUpMainTarget( - boolean hasMain, String executableName, Stream cSources) { + boolean hasMain, String executableName, Stream cSources) { + String pyVersion = pythonVersion.isEmpty() ? "3.8" : pythonVersion + " EXACT"; return (""" - set(CMAKE_POSITION_INDEPENDENT_CODE ON) - add_compile_definitions(_PYTHON_TARGET_ENABLED) - add_subdirectory(core) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) - set(LF_MAIN_TARGET ) - find_package(Python 3.10.0...<3.11.0 REQUIRED COMPONENTS Interpreter Development) - Python_add_library( - ${LF_MAIN_TARGET} - MODULE - """ + set(CMAKE_POSITION_INDEPENDENT_CODE ON) + add_compile_definitions(_PYTHON_TARGET_ENABLED) + add_subdirectory(core) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) + set(LF_MAIN_TARGET ) + find_package(Python REQUIRED COMPONENTS Interpreter Development) + Python_add_library( + ${LF_MAIN_TARGET} + MODULE + """ + cSources.collect(Collectors.joining("\n ", " ", "\n")) + """ -) -if (MSVC) - set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) - set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}) - set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}) - set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_SOURCE_DIR}) - set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_SOURCE_DIR}) -endif (MSVC) -set_target_properties(${LF_MAIN_TARGET} PROPERTIES PREFIX "") -include_directories(${Python_INCLUDE_DIRS}) -target_link_libraries(${LF_MAIN_TARGET} PRIVATE ${Python_LIBRARIES}) -target_compile_definitions(${LF_MAIN_TARGET} PUBLIC MODULE_NAME=) -""") - .replace("", generatePythonModuleName(executableName)); + ) + if (MSVC) + set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}) + set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_SOURCE_DIR}) + set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_SOURCE_DIR}) + set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_SOURCE_DIR}) + set_target_properties(${LF_MAIN_TARGET} PROPERTIES LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_SOURCE_DIR}) + endif (MSVC) + set_target_properties(${LF_MAIN_TARGET} PROPERTIES PREFIX "") + include_directories(${Python_INCLUDE_DIRS}) + target_link_libraries(${LF_MAIN_TARGET} PRIVATE ${Python_LIBRARIES}) + target_compile_definitions(${LF_MAIN_TARGET} PUBLIC MODULE_NAME=) + """) + .replace("", generatePythonModuleName(executableName)) + .replace("", pyVersion); // The use of fileConfig.name will break federated execution, but that's fine } diff --git a/core/src/main/java/org/lflang/target/Target.java b/core/src/main/java/org/lflang/target/Target.java index 30048f5a58..08974b7411 100644 --- a/core/src/main/java/org/lflang/target/Target.java +++ b/core/src/main/java/org/lflang/target/Target.java @@ -60,6 +60,7 @@ import org.lflang.target.property.TracingProperty; import org.lflang.target.property.VerifyProperty; import org.lflang.target.property.WorkersProperty; +import org.lflang.target.property.PythonVersionProperty; /** * Enumeration of targets and their associated properties. @@ -640,7 +641,8 @@ public void initialize(TargetConfig config) { SingleThreadedProperty.INSTANCE, TracingProperty.INSTANCE, TracePluginProperty.INSTANCE, - WorkersProperty.INSTANCE); + WorkersProperty.INSTANCE, + PythonVersionProperty.INSTANCE); case Rust -> config.register( BuildTypeProperty.INSTANCE, diff --git a/core/src/main/java/org/lflang/target/property/PythonVersionProperty.java b/core/src/main/java/org/lflang/target/property/PythonVersionProperty.java new file mode 100644 index 0000000000..05ee718acd --- /dev/null +++ b/core/src/main/java/org/lflang/target/property/PythonVersionProperty.java @@ -0,0 +1,19 @@ +package org.lflang.target.property; + +/** + * Directive for specifying a specific version of the reactor runtime library. + */ +public final class PythonVersionProperty extends StringProperty { + + /** Singleton target property instance. */ + public static final PythonVersionProperty INSTANCE = new PythonVersionProperty(); + + private PythonVersionProperty() { + super(); + } + + @Override + public String name() { + return "python-version"; + } +}