From 0584253a040e5c00c53c2ddc1a32a1de0c880bda Mon Sep 17 00:00:00 2001 From: erlingrj Date: Sun, 8 Dec 2024 09:05:39 -0800 Subject: [PATCH] Have LFC generate a main function that can optionally be included in the build --- examples/flexpret/CMakeLists.txt | 2 +- examples/flexpret/main.c | 5 --- examples/riot/buildAll.sh | 5 +++ examples/riot/hello_lf/main.c | 5 --- examples/riot/hello_lf/run/build.sh | 4 +++ examples/zephyr/buildAll.sh | 7 ++++- examples/zephyr/hello_lf/CMakeLists.txt | 4 +-- examples/zephyr/hello_lf/main.c | 5 --- examples/zephyr/hello_lf/run/build.sh | 4 +++ examples/zephyr/hello_lf/src/HelloLF.lf | 4 +-- .../lflang/generator/uc/UcCmakeGenerator.kt | 4 ++- .../lflang/generator/uc/UcMainGenerator.kt | 31 +++++++------------ .../lflang/generator/uc/UcMakeGenerator.kt | 3 ++ .../generator/uc/UcStandaloneGenerator.kt | 12 ++++--- make/riot/riot.mk | 5 ++- 15 files changed, 51 insertions(+), 49 deletions(-) delete mode 100644 examples/flexpret/main.c delete mode 100644 examples/riot/hello_lf/main.c create mode 100755 examples/riot/hello_lf/run/build.sh delete mode 100644 examples/zephyr/hello_lf/main.c create mode 100755 examples/zephyr/hello_lf/run/build.sh diff --git a/examples/flexpret/CMakeLists.txt b/examples/flexpret/CMakeLists.txt index 9ad27675..2a264437 100644 --- a/examples/flexpret/CMakeLists.txt +++ b/examples/flexpret/CMakeLists.txt @@ -14,7 +14,7 @@ project(fp-lf) include(src-gen/Smoke/CMakeLists.txt) add_subdirectory(${REACTOR_UC_PATH}) -add_executable(fp-smoke main.c ${LFC_GEN_SOURCES}) +add_executable(fp-smoke ${LFC_GEN_MAIN} ${LFC_GEN_SOURCES}) target_link_libraries(fp-smoke PUBLIC reactor-uc) target_include_directories(fp-smoke PRIVATE ${LFC_GEN_INCLUDE_DIRS}) diff --git a/examples/flexpret/main.c b/examples/flexpret/main.c deleted file mode 100644 index 306ba3a2..00000000 --- a/examples/flexpret/main.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "lf_main.h" - -int main() { - lf_start(); -} \ No newline at end of file diff --git a/examples/riot/buildAll.sh b/examples/riot/buildAll.sh index 2ca9484b..eb1cffb3 100755 --- a/examples/riot/buildAll.sh +++ b/examples/riot/buildAll.sh @@ -21,3 +21,8 @@ for board in "${BOARDS[@]}"; do popd done done + +# Build lf example +pushd hello_lf +run/build.sh +popd \ No newline at end of file diff --git a/examples/riot/hello_lf/main.c b/examples/riot/hello_lf/main.c deleted file mode 100644 index 306ba3a2..00000000 --- a/examples/riot/hello_lf/main.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "lf_main.h" - -int main() { - lf_start(); -} \ No newline at end of file diff --git a/examples/riot/hello_lf/run/build.sh b/examples/riot/hello_lf/run/build.sh new file mode 100755 index 00000000..80602f55 --- /dev/null +++ b/examples/riot/hello_lf/run/build.sh @@ -0,0 +1,4 @@ +#!/bin/env bash + +${REACTOR_UC_PATH}/lfc/bin/lfc-dev src/HelloLF.lf +make all \ No newline at end of file diff --git a/examples/zephyr/buildAll.sh b/examples/zephyr/buildAll.sh index 24a9e95c..82926bb0 100755 --- a/examples/zephyr/buildAll.sh +++ b/examples/zephyr/buildAll.sh @@ -16,4 +16,9 @@ for dir in "${FOLDERS[@]}"; do pushd $dir $COMMAND popd -done \ No newline at end of file +done + +# Build lf example +pushd hello_lf +run/build.sh +popd \ No newline at end of file diff --git a/examples/zephyr/hello_lf/CMakeLists.txt b/examples/zephyr/hello_lf/CMakeLists.txt index 0fba35c1..39521f82 100644 --- a/examples/zephyr/hello_lf/CMakeLists.txt +++ b/examples/zephyr/hello_lf/CMakeLists.txt @@ -6,6 +6,6 @@ set(PLATFORM "ZEPHYR" CACHE STRING "Set platform to Zephyr") include(src-gen/HelloLF/CMakeLists.txt) add_subdirectory(${REACTOR_UC_PATH}) -target_sources(app PRIVATE main.c ${LF_SOURCES}) +target_sources(app PRIVATE ${LFC_GEN_MAIN} ${LFC_GEN_SOURCES}) target_link_libraries(app PRIVATE reactor-uc) -target_include_directories(app PRIVATE ${LF_INCLUDE_DIRS}) +target_include_directories(app PRIVATE ${LFC_GEN_INCLUDE_DIRS}) diff --git a/examples/zephyr/hello_lf/main.c b/examples/zephyr/hello_lf/main.c deleted file mode 100644 index 306ba3a2..00000000 --- a/examples/zephyr/hello_lf/main.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "lf_main.h" - -int main() { - lf_start(); -} \ No newline at end of file diff --git a/examples/zephyr/hello_lf/run/build.sh b/examples/zephyr/hello_lf/run/build.sh new file mode 100755 index 00000000..bda655cf --- /dev/null +++ b/examples/zephyr/hello_lf/run/build.sh @@ -0,0 +1,4 @@ +#!/bin/env bash + +${REACTOR_UC_PATH}/lfc/bin/lfc-dev src/HelloLF.lf +west build -b qemu_cortex_m3 -p always \ No newline at end of file diff --git a/examples/zephyr/hello_lf/src/HelloLF.lf b/examples/zephyr/hello_lf/src/HelloLF.lf index a884a08c..3d40abce 100644 --- a/examples/zephyr/hello_lf/src/HelloLF.lf +++ b/examples/zephyr/hello_lf/src/HelloLF.lf @@ -1,6 +1,4 @@ -target uC { - platform: Zephyr -} +target uC main reactor { reaction(startup) {= diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcCmakeGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcCmakeGenerator.kt index ea00a28f..dc5db574 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcCmakeGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcCmakeGenerator.kt @@ -17,6 +17,7 @@ import org.lflang.unreachable import org.lflang.util.FileUtil import java.nio.file.Path import java.time.LocalDateTime +import kotlin.io.path.name import kotlin.math.max class UcCmakeGenerator(private val main: Reactor, private val targetConfig: TargetConfig, private val fileConfig: FileConfig) { @@ -38,8 +39,9 @@ class UcCmakeGenerator(private val main: Reactor, private val targetConfig: Targ |# an existing CMake project. | |set(LFC_GEN_SOURCES - ${" | "..sources.joinWithLn { "$S{CMAKE_CURRENT_LIST_DIR}/${it.toUnixString()}"}} + ${" | "..sources.filterNot{it.name == "lf_main.c"}.joinWithLn { "$S{CMAKE_CURRENT_LIST_DIR}/${it.toUnixString()}"}} |) + |set(LFC_GEN_MAIN "$S{CMAKE_CURRENT_LIST_DIR}/lf_main.c") |set(REACTOR_UC_PATH $S{CMAKE_CURRENT_LIST_DIR}/reactor-uc) |set(LFC_GEN_INCLUDE_DIRS $S{CMAKE_CURRENT_LIST_DIR}) |set(REACTION_QUEUE_SIZE ${main.getReactionQueueSize()} CACHE STRING "Size of the reaction queue") diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMainGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMainGenerator.kt index d23f32f9..4b45066f 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMainGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMainGenerator.kt @@ -20,23 +20,6 @@ class UcMainGenerator( ) { private val ucParameterGenerator = UcParameterGenerator(main) - // For the default POSIX platform we generate a main function, this is only for simplifing - // quick testing. For real applications the code-generated sources must be included in an - // existing project. - fun generateMainFunction() = with(PrependOperator) { - if (targetConfig.get(PlatformProperty.INSTANCE).platform == PlatformType.Platform.NATIVE) { - """ - |// The following is to support convenient compilation of LF programs - |// targeting POSIX. For programs targeting embedded platforms a - |// main function is not generated. - |int main(int argc, char **argv) { - | lf_start(); - |} - """.trimMargin() - } else { - "" - } - } fun getDuration() = if (targetConfig.isSet(TimeOutProperty.INSTANCE)) targetConfig.get(TimeOutProperty.INSTANCE).toCCode() else "FOREVER" @@ -44,7 +27,7 @@ class UcMainGenerator( fun fast() = if(targetConfig.isSet(FastProperty.INSTANCE)) "true" else "false" - fun generateMainSource() = with(PrependOperator) { + fun generateStartSource() = with(PrependOperator) { """ |#include "reactor-uc/reactor-uc.h" |#include "${fileConfig.getReactorHeaderPath(main).toUnixString()}" @@ -63,11 +46,10 @@ class UcMainGenerator( | lf_environment.start(&lf_environment); | lf_exit(); |} - ${" |"..generateMainFunction()} """.trimMargin() } - fun generateMainHeader() = with(PrependOperator) { + fun generateStartHeader() = with(PrependOperator) { """ |#ifndef REACTOR_UC_LF_MAIN_H |#define REACTOR_UC_LF_MAIN_H @@ -78,4 +60,13 @@ class UcMainGenerator( | """.trimMargin() } + + fun generateMainSource() = with(PrependOperator) { + """ + |#include "lf_start.h" + |int main(void) { + | lf_start(); + |} + """.trimMargin() + } } diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMakeGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMakeGenerator.kt index 81ba03d7..7b73a834 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMakeGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcMakeGenerator.kt @@ -11,15 +11,18 @@ import org.lflang.target.property.BuildTypeProperty import org.lflang.toUnixString import java.nio.file.Path import java.time.LocalDateTime +import kotlin.io.path.name import kotlin.math.max class UcMakeGenerator(private val main: Reactor, private val targetConfig: TargetConfig, private val fileConfig: FileConfig) { private val S = '$' // a little trick to escape the dollar sign with $S fun generateMake(sources: List) = with(PrependOperator) { + val sources = sources.filterNot { it.name=="lf_main.c" } """ | # Makefile generated for ${fileConfig.name} |LFC_GEN_SOURCES = \ ${" | "..sources.joinWithLn { it.toUnixString() + if (it != sources.last()) " \\" else ""}} + |LFC_GEN_MAIN = lf_main.c |REACTION_QUEUE_SIZE = ${max(main.getReactionQueueSize(), 1)} |EVENT_QUEUE_SIZE = ${max(main.getEventQueueSize(), 1)} | diff --git a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcStandaloneGenerator.kt b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcStandaloneGenerator.kt index 8eb094fb..4c161ca3 100644 --- a/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcStandaloneGenerator.kt +++ b/lfc/core/src/main/kotlin/org/lflang/generator/uc/UcStandaloneGenerator.kt @@ -33,18 +33,20 @@ class UcStandaloneGenerator(generator: UcGenerator, val srcGenPath: Path) : // generate the main source file (containing main()) val mainGenerator = UcMainGenerator(mainReactor, generator.targetConfig, generator.fileConfig) + val startSourceFile = Paths.get("lf_start.c") + val startHeaderFile = Paths.get("lf_start.h") val mainSourceFile = Paths.get("lf_main.c") - val mainHeaderFile = Paths.get("lf_main.h") + val startCodeMap = CodeMap.fromGeneratedCode(mainGenerator.generateStartSource()) val mainCodeMap = CodeMap.fromGeneratedCode(mainGenerator.generateMainSource()) - ucSources.add(mainSourceFile) + ucSources.addAll(listOf(startSourceFile, mainSourceFile)) + codeMaps[srcGenPath.resolve(startSourceFile)] = startCodeMap codeMaps[srcGenPath.resolve(mainSourceFile)] = mainCodeMap - println("Path: $srcGenPath $srcGenPath") - + FileUtil.writeToFile(startCodeMap.generatedCode, srcGenPath.resolve(startSourceFile), true) FileUtil.writeToFile(mainCodeMap.generatedCode, srcGenPath.resolve(mainSourceFile), true) - FileUtil.writeToFile(mainGenerator.generateMainHeader(), srcGenPath.resolve(mainHeaderFile), true) + FileUtil.writeToFile(mainGenerator.generateStartHeader(), srcGenPath.resolve(startHeaderFile), true) val cmakeGenerator = UcCmakeGenerator(mainReactor, targetConfig, generator.fileConfig) val makeGenerator = UcMakeGenerator(mainReactor, targetConfig, generator.fileConfig) diff --git a/make/riot/riot.mk b/make/riot/riot.mk index a1040634..99b486a5 100644 --- a/make/riot/riot.mk +++ b/make/riot/riot.mk @@ -5,7 +5,10 @@ ifdef SRC_GEN_PATH include $(SRC_GEN_PATH)/Makefile # Include generated c files -SRC += $(patsubst %, $(SRC_GEN_PATH)/%, $(LFC_GEN_SOURCES)) main.c +SRC += $(patsubst %, $(SRC_GEN_PATH)/%, $(LFC_GEN_SOURCES)) + +# Include generated main file +SRC += $(SRC_GEN_PATH)/${LFC_GEN_MAIN} # Include generated h files CFLAGS += -I$(SRC_GEN_PATH)