Proposal: Enable unit testing Kaleidoscopes core and client plugins by Dependency Inversion

Hello everyone,
first of all: Thank you for developing such an awesome keyboard. I ordered my M01 some weeks ago and can’t wait to receive it and start typing.
Being new around here (and the open source community, FWIW) i hope you don’t consider it rude to jump right in with a large-ish proposal.

TL;DR: I propose applying Dependency Inversion to the Kaleidoscope core. Among other effects this would make the core and most plugins independent of Arduino libraries and hardware. This would allow unit-testing on a developer machine. Additionally it would probably simplify understanding Kaleidoscope and porting it to other hardware. Would you (the maintainers) be interested in such a change?

Here comes the detailed version:

To shorten the wait for my M01, i looked around Kaleidoscope a bit. As i need the M01 to work on PCs with a German keyboard layout i was hoping to contribute in that area. While trying to get started, i found no angle of attack fitting my preferred development process (Test Driven Development) and tools (Windows, modern IDEs, no available M01 for now).

Although i like many aspects of Kaleidoscope (plugin concept, clarity of client plugin code) its current implementation has implications that i would like to see mitigated:

  • I found no simple way to use a modern IDE (i.e. MSVS) for enhanced navigation, refactoring, code-completion, integration of unit-tests, etc.
  • I could not figure out how to apply Test Driven Development
  • I see no possibility to unit-test code without running it on the target hardware

In my eyes the main source for the latter two is Kaleidoscopes direct dependency to the Arduino headers and to Arduino specific plugins. Here’s my proposal for improving upon this:

  • Create abstractions of hardware aspects in the form of interfaces (just like Kaleidoscope-Hardware.h) within the core.
  • Implement those interfaces in plugins (much like Kaleidoscope-Hardware-Model01.h, but implementing kaleidoscope::Hardware instead of incidentally having a similar set of methods).
  • Ensure the core only depends on the aforementioned interfaces, not on the implementing plugins.
  • Move all Arduino dependencies (especially #include <Arduino.h>) down to the implementing plugins or up to the construction root.
  • Bind plugins to their implemented interfaces in the construction root (*.ino files), not within the core.

By applying this kind of Dependency Inversion to all Arduino specific details, the Kaleidoscope core would become independent of the Arduino libraries and hardware.
In case any of you are not familiar with Dependency Inversion: Currently the high-level core directly depends upon low-level plugins like “Kaleidoscope-Hardware-Model01.h”. By applying the above steps, the core (which does not include the construction root) no longer depends on any particular low-level plugin. Instead, the low level plugin depends on the core, by implementing the core interface defined in “Kaleidoscope-Hardware.h”. Thus, the dependencies have been inverted from core->plugin to plugin->core.

My personal goal with this: Allow unit testing the Kaleidoscope core and client plugins in general and Test-Driving their Development in particular
Additional benefits include:

  • Understanding the Kaleidoscope core becomes simpler, as it provides simple interfaces instead of depending on complex implementation plugins.
  • Porting to other Hardware (e.g. virtual devices, non-Arduino keyboards but also other Arduino-hardware) becomes simpler, as the core clearly defines a set of interfaces that need to be implemented.

Whew… that became much longer than i intended. I sure hope it is understandable and you don’t mind making my first appearance like this.
In anticipation of the more frequently raised questions here:

  • I fear it would have some (hopefully minor) impact on the public API. For instance i suspect “extern HARDWARE_IMPLEMENTATION KeyboardHardware;” needed to become “extern Hardware* KeyboardHardware;” in order to allow applying the necessary polymorphism.
  • Probably the compilers ability to inline would be impacted by the interfaces, which might or might not lead to a measurable performance impact. If so, using “static polymorphism” could be explored as an alternative.

Please let me know if you would welcome the described change or have any questions regarding my proposal.

2 Likes

There’s already a virtual hardware plugin, and a Python-scriptable Kaleidoscope simulation package.

See the following thread for more info:

:wink:

1 Like

Thanks for pointing me at Leidokos. It might be a way for me to test code on a virtual keyboard while waiting for my M01.

I do agree with @noseglasses goals in many aspects. But -correct me if i am wrong- i understood, that Kaleidoscope was not going to officially support the CMake portion of it. So i concluded that it is probably not going to be the basis of officially supported und used tests for Kaleidoscope.

My main goal, however, was to contribute the ability to unit-test and test-drive Kaleidoscopes core und client plugins.
Two important characteristics of a unit-test suite are that it should be easy to understand and localized to a small unit under test such as a class or sometimes a bunch of classes like a plugin. The approach i proposed unites both characteristics:

  • As every Kaleidoscope contributor knows C/C++, writing tests in C/C++ as well avoids adding an unnecessary barrier to understanding and writing tests.
  • By pushing Arduino references to the boundaries of the system and introducing interfaces as described in my OP, it becomes possible to test separate plugins or core parts without deploying on (virtual or real) hardware or even instantiating the whole system.

I hope not to bother you by asking again: Would you be interested in the ability to unit-test Kaleidoscopes core and client plugins at the cost of some architectural change? If so i would like to contribute to this endeavour.
If i did not sketch my idea clearly enough, feel free to fire questions at me or propose a more direct form of discussion.
If the proposed change just does not align with Kaleidoscopes goals that’s okay as well - just tell me. I don’t want to waste anyones time and energy discussing, or worse, implementing unwelcome changes.

1 Like

Keyboardio officially concentrates on Arduino as build-platform for Kaleidoscope. Jesse made this very clear to me.

Although I am a great fan of test-driven development, I am concerned about the feasibility of unit-testing in a rapidly evolving FOSS project like Kaleidoscope. When we speak of units, we are talking classes and functions, internal stuff and public interfaces.

Currently with Kaleidoscope it is not all obvious what is considered an internal/private part of the core implementation and what part of the user programming interface for plugins. While the latter seems fairly stable and algernon and jesse take great care not to break user plugin code, internal parts are constantly subject to changes. Unit testing of such internal functions and classes seems infeasible to me, given the current speed of development, the number of contributions and the (restricted) number of core developers. It is important to acknowledge that with unit-testing a lot of development time must be allocated on adapting tests when unit interfaces, i.e. functions and methods change. This can be very frustrating.

On the other hand, the long term goal of having unit testing of stable public interfaces sounds very reasonable to me. Until then, I find it most useful to CI-test the overall behavior of the firmware and its plugins by running IO-tests with a simulated firmware.

To enable IO based CI-tests are one reason why I started Leidokos-Python. Another reason is that I am working on a plugin that is too complex for reasonably being debugged based on printf and assert-macros. Leidokos-Python supports using an ordinary debugger. A third reason is that I, like you @kriber, spend quite some time waiting on my M01 and I wanted to use the time and start developing without hardware, based on a proper simulator and test-driven development.
It turned out that developing the necessary tools (Leidokos-CMake, -Python, -Testing) took more than the waiting time…

3 Likes

Links to related discussions:

1 Like

Thanks for your detailed reply, @noseglasses.

In my personal experience, a high rate of change is no counterindication to unit testing or test driven development. But probably that is a discussion that we should have elsewhere, if at all :wink:

As for FOSS and unit-testing or TDD: I see no reason that this combination couldn’t work in general. But without support of the core maintainers it would probably turn into a frustrating experience for some or all.

As enabling unit testing and the proposed architecural changes don’t seem to resonate with the maintainers of Kaleidoscope i will not pursue this goal any further.

As the tools and processes available here are too far from my comfort zone, i will not contribute to Kaleidoscope. Once i get my M01 i might create a client plugin to fullfil my german layout needs.

I wish you all the best of luck and will continue waiting for my M01 :wink:

Just out of curiosity, can you point me to some C++ FOSS project that consistently and sucessfully uses unit-testing? I would like to learn how other people are dealing with the difficulties I mentioned.

I am german as well. What special requirements do you have?

As i have no experience in open source software and my C++ is a little rusted i don’t have any good examples handy. In my superficial search i quickly stumbled across several C++ unit-testing frameworks. Although i found no concrete numbers, the google test project (is that even considered FOSS?) has unit tests and seems to aim for a good coverage.
Where i do have experience is unit-testing and test-driving development of code in several languages. I have also done so in projects with changing requirements. So if you have any specific questions relating to those practices i might be able to share some insights.

As i don’t yet have my M01 here yet i only have educated guesses for now:

  • I will probably want to use it on Computers with german keyboard layout (as i frequently pair-program with people using QUERTZ keyboards)
  • Probably i want to have a simple access to the german special letters (äöüß). Maybe a dead key would be sufficient, as their frequency is rather low.
  • My current plan is to leave as much of the preset M01-layout intact in order to smoot out the learning curve when transitioning from normal keyboards to the M01.

My initial idea was developing a plugin that allows to use an existing M01-layout and map it to whatever layout the operating system is using. I hoped to achieve this by describing the mapping from english layout to the OS-layout in separation from the mapping from keys to (default english) keycodes. This way people would be able to combine existing layouts (QUERTY, Dvorak, Workman etc.) with a mapping to the OS-layout (german QUERTZ, french, swedish or even Dvorak if somebody needed to).

@noseglasses - I can’t recall if we previously talked through the various possible ‘compromises’ for build systems.

What’s important to me is that we not break support for Arduino-compatible toolchains and platforms. Given that constraint, I’d be thrilled to support other toolchains and platforms.

The CMake implementation you’ve built out is, to the best of my understanding, based on a CMake-native reimplementation from scratch of the Arduino build process. I understand that doing it that way has benefits, especially if you’re skilled at CMake and you spend most of your time in CMake projects. It is, however, not ideal as a ‘second’ build system, as maintaining bug-for-bug compatibility between platforms is difficult burden.

Would you be amenable to a CMake implementation that, instead of reimplementing the Arduino build system and our build tools, wraps them? That’s something that I’d be thrilled to have in core alongside the traditional build infrastructure.

I know that it won’t get you as much magic when doing things like partial rebuilds, but, for an embedded project on a modern CPU, that’s not a huge problem.

As to automated testing, it’s something we very much want to do. I -am- very picky about making sure the test infrastructure is simple and straightforward to use. The current ‘does it build’ smoke tests, coupled with the C++ linter are a start, but are a poor substitute for any sort of real automated regression testing.

I spent a couple years as the project lead for Perl. We put a ton of effort into test infrastructure, as well as making tests easy to read, easy to write and easy to maintain. In terms of project scale for testing, Kaleidoscope is a small opensource project.

Getting the usability of a test system right is pretty important. Otherwise, it can hurt development more than it can help.

I’ve been frustrated and surprised that I haven’t been able to find any good examples of test frameworks for Arduino or other embedded AVR C/C++ projects. What works on desktop or enterprise is rarely also good for embedded. If anybody can point me to good (or bad) test frameworks for embedded systems similar to ours and have some real-world use, I’d be grateful.

@craigdissel’s x86 Arduino core is one tool that’s getting us closer to being able to run automated regression tests (though I’d really like to be able to simulate our actual hardware platform for testing).

(I’ve also been working 12+ hour days getting hardware shipped and supporting customers for months, which hasn’t given me a lot of time to dig into this.)

2 Likes

No, definitely not talked through. We only discussed here and there about regression testing and CMake.

I only mention that you are concentrating on Arduino to make it clear to potential users of my CMake build system that they should not bother you with any questions/issues/etc. about CMake.

Correct.

Agreed. It took me a while and many contributions to Arduino-CMake to get everything to work nicely. And, as you say, this solution is far from ideal.

The reason why I did not wrap Arduino-Builder is that I wanted several features that the Arduino build system is lacking. The most prominent are

  1. Partial rebuilds.
  2. Generate preprocessed input files (important when dealing with complex nested prepro-macros).

Apart from that, I need a build system that allows me to have Kaleidoscope-components (plugins, modules, whatever we call them - Arduino libraries) with additional sophisticated build steps. An application example is a plugin that I am working on:

The plugin does complex key event pattern recognition (chords, clusters, multi-key tap-dances, sequences, …). For this to work it uses an external library, which is another project I am working on and already use with QMK. The C-interface of this library is far too complex to bother the average Kaleidoscope user with and the search tree that is used for the pattern recognition is better allocated statically.

That’s why I implemented an optimizing compiler, that maps a very simple descriptive language to a complex amount of C code that is build automatically and linked with the Kaleidoscope-Plugin. The user only writes some lines of descriptive language in a commented region of the sketch’s C++ code, e voila she/he gains very powerful functionality.

For this to work, several steps are automatized as part of the firmware build

  1. The external C-library must be set up as an Arduino library.
  2. The pre-compiler is build.
  3. The sketch is parsed and compiled by the pre-compiler and converted to a C file.
  4. The firmware is compiled and linked, including the sketch, other plugins, the Kaleidoscope-Papageno plugin, the Papageno C library and the search tree C-code generated as part of the build.

As you can see, this is quite a complex task. I am well aware that 99% of the Kaleidoscope-plugins are less complicated but there might be other devs that have crazy ideas that also require features that the Arduino build system cannot provide.

A CMake based build system makes all this possible and allows to provide a very simple build recipe in the plugin’s github README. Users only have to make sure that CMake and a native C++ compiler are installed, apart from Arduino. The rest is just the ordinary two stage build process of any other C++ FOSS project. I expect this to be feasible, at least for some advanced Kaleidoscope users.

Yes, definitely, because I understand your concerns towards a all-CMake build system very well.

What about a build system that is CMake based but modular. The overall build handling and module/plugin pre-build stage is CMake-driven. The actual firmware build part could be made modular.
The user could choose between a Arduino based build core and a purely CMake based one, one that provides all those features that Arduino is (currently) lacking.

The core build modules could be two independent git repos. One that is a very simple CMake wrapper of Arduino-CMake or Kaleidoscope-CMake and one that is a restructured version of what I am using so far.

I could create something like that but currently I am busy with some other projects that I need to finish first. At least one needs to be finished before I can use my M01.

I agree. The problem is that there are different types of tests with completely different levels of complexity.

While it is very simple to test the keyboard output that results from a series of keystrokes, it is far more complicated once the exact order of HID reports or the internal state of the firmware matter and are to be tested. For the former, craigdissels work seems a perfect match. For the latter, something more complex is necessary…and available.

To ensure that my own complex plugins (e.g. the one that I mentioned above) does and will do what it is supposed to, I came up with Leidokos-Python. It wraps most parts of the Kaleidoscope core module as Python code and allows any other plugins to export their internals as well. This way it is possible to monitor and test the IO behavior but also to keep track of what happens inside the firmware - if necessary. There are already quite sophisticated plugins around where it might be more efficient to test parts of the internal state instead of defining an infinite number of simple IO tests.

Leidokos-Python’s tests are mostly based on formulating expectations. E.g. somthing in the line of “the next HID report must contain certain keys or modifiers or must not… or whatever combinations” or “there must be n HID reports” or “no HID report after the next key event”. First you define a series of expectations for an expected series of HID reports, then you feed the virtual keyboard with key events. Tests fails if expectations are not met.

All this works with simulated real time. Even complex timing issues can be tracked down. As a bonus (not necessary for regression testing), the LED state can be visualized at any time and the whole beast can run in any ordinary debugger on the host system. All this makes Leidokos-Python a valuable tool when developing sophisticated plugins.

To make the handling of tests as convenient as possible, I started another project, Leidokos-Testing that reads a testing directory tree structure and automatically defines a number of regressions tests. A test is defined by its Kaleidoscope plugins (git sha/branch/…), the firmware sketch and the python driver for Leikodos-Python. This information consists of files (the sketch and the python driver) and a yaml-file that contains the information about which Kaleidoscope-plugins to build a firmware of. I chose yaml to make the testing tree structure definition independent from CMake and to be able to replace the CMake parts of Leidokos-Testing if necessary.

Information stored in subdirectories overrides the information of parent directories. This allows to specify a large set of tests with a minimum of spec redundancies. Every leaf of the testing directory tree represents an individual regression-test.

For my purposes this proved to be useful. I already use it for simple tests of Leidokos-Python and am planning to use it for all my plugins’ regression testing.

:+1: I read your backer updates and followed your announcements on twitter. I continuously wondered when you actually sleep? You must be either supernatural or a zombie. Probably a supernatural zombie that builds nice keyboards :slight_smile:

Much appreciated.

Partial rebuilds, while desirable, aren’t (I suspect) a showstopper and wouldn’t have been enough of a win to spend all the time you have on build engineering.

It does appear that arduino-builder has grown more support for partial rebuilds. kaleidoscope-builder could be updated to better use that support. GitHub - arduino/arduino-builder: A command line tool for compiling Arduino sketches

I 100% understand why precompilation or preproccessing steps can be useful tools for metaprogramming or to get you functionality that is otherwise impossible. At the same time, they add nearly infinite new ways for things to break and can lead to brittle, undebuggable, non-portable code.

I do believe that you should have as much rope as you want. whether you turn it into a noose or a lasso is your call. But, given our intent of newbie-friendliness, it’s important to me that we try to steer users toward the simplest thing that could possibly work.

I’d like to figure out a way for you to get what you want without requiring end-users to only be able to use your plugins with a non-standard build system.

In my vocabulary, that’s an “external DSL” (domain specific language) for keyboard configuration. I spent years of my life building DSLs. They have huge advantages, but also some pretty serious disadvantages.

I’m not a fan of storing such stuff in comments. I would -probably- opt for putting it in a well-named file next to the user’s main sketch. But that’s neither here nor there.

I do recall something about Arduino considering adopting a way for libraries to include either prebuilt code or custom build steps, though can’t find a reference to that.

@algernon proposed a fairly evil hack to get something like what you want using the core Arduino build system. I’m not sure either of us actually think it’s a good idea. We could modify the Arduino preprocessor build recipe to run a specific script if it existed. I’d be very, very worried about making sure this works portably.

Well, Arduino-CMake is exactly what I don’t want to get anywhere near. They reimplement, rather than wrap the Arduino build process. I understand the desire for CMake targets for folks who want to more easily use non-Arduino IDEs or automation to build their code. But, as we’ve talked about, adding a second implementation of arduino-builder & kaleidoscope-builder is something I’m not excited to support.

I’d -prefer- not to have a ‘pluggable’ CMake build process with multiple competing backends.
I think I -might- be ok with a top-level sketch CMakefile that uses the core Arduino/Kaleidoscope make targets and has hooks to do custom things if you want to, but I’d like us to talk that through in some detail.

It’s really important to me that different supported build systems don’t give users different functionality. I’d really like every Kaleidoscope user to be able to use the cool features you build, not just folks using CMake.

No worries! You’re a volunteer contributor. You have absolutely zero obligation to to build anything on any kind of schedule (or to do anything at all.)

Very cool. I’m not sure it quite fits the way I’d approach testing, but it’s certainly not wrong to have as an option and is definitely something I’ll look at and play with as I find the time to start defining a core testing framework.

Sadly, I can’t walk through walls, am visible in mirrors and have had no luck casting spells.

That said, I’m quite good at shambling and have a passable thousand yard stare.

You wouldn’t be wrong to vote ‘zombie’.

As i somehow kicked off this discussion i might as well add my 5 cents: I managed to build the Kaleidoscope/M01 sketch with the arduino toolchain on both windows and linux :+1:.
As i very much want to use a modern IDE, i put about 2 days into getting the leidokos-CMake to build and generate projects and failed miserably both on linux and windows.

So i do absolutely agree with @jesse that simplicity for the default case needs to be a priority. In my eyes, this makes a simple CMake solution wrapping the arduino toolchain a good candidate. The most crucial point, for me personally, is using CMake (or whatever alternative) to generate projects for modern IDEs like MSVS or CLion with advanced navigation and refactoring features.

Agreed. If you want to discuss options here, i would gladly volunteer as a sparring partner in that regard. Disclaimer: Although i work on embedded systems, C/C++ is not my strongest language and the systems i work on have enough memory and powerful CPUS for not worrying about those, most of the time :wink:

Still i think most of the common testing wisdom applies here. Therefore, i would suggest adhering to the test pyramid (which has been expressed in many forms): Most tests should be written against small modules (classes) in separation. The more integrated the tests become, the fewer their numbers. At full integration level (the whole system, including hardware) the typical tests are scenario tests that are expressed in terms suitable for business stakeholders. And they are few. All different levels of isolation/integration are valuable, but the bulk of tests typically lies at the isolated level.

Hence my suggestion to tweak Kaleidoscopes architecture to push the Arduino references to the boundaries of the system to enable unit testing (especially of client plugins) in isolation of the Arduino-toolchain and without (virtual or real hardware). For the more integrative tests an easy-to-setup and easy-to-use virtual hardware should be a perfect fit.

Regarding testing frameworks i would lean towards battle-tested unit testing frameworks that do not specifically target Arduino like cppunit or google test. Should those be impossible to use (e.g. by memory restraints on the target hardware) my next best suggestion would be to lean on the most simple working approach (i.e. assert statements and the like).

As far as my searches go there seem to be several production quality projects simulating Arduino hardware. Some of those support custom PCB layouts (i googled for “Arduino Simulator”).
A second route might be to mock/fake the Arduino dependencies. My search into that direction did not turn up any frameworks that look promising enough to suggest them. Depending on how much of the Arduino dependencies Kaleidoscope actually uses, manually faking them might or might not be feasible.
As i do not have experience with any of those, i can’t do more than point them out. Nonetheless, my gut feeling suggests that going down the arduino mocking framework route could raise more problems than it solves.

Thank you very much for putting so much effort into getting the preordered keyboards to people like me :butterfly:. And for making them possible in the first place, of course. I sure hope that all the time and effort you put into this project pays off for you!

:+1: for a precise simulated time in the testing environment! Nonetheless, as @jesse suggested, i also would welcome a testing environment that is far less complex than Leidokos is right now. Especially the dependency on Arduino-CMake causes a lot of trouble for me. Additionally i would hope that staying with C/C++ as testing language would suffice to enable writing expressive tests.

Yeah. I’ve spent days of time with avrsim and simulavr, which appear to be the most developed freely available option. Neither had working support for a 32U4 that could speak USB.

As to mocking Arduino, that’s https://github.com/keyboardio/Kaleidoscope-Hardware-Virtual - I’d love to see it generalized some.

My experience thus far with Kaleidoscope suggests that there are actually quite a lot of problems that would need testcases at the higher levels. There have been quite a lot of bugs that don’t appear at low levels, but do produce incorrect output from interactions between plugins, and between plugins and the core.

I just mentioned the importance of pre-processed code because it is extremely useful for debugging. Kaleidoscope defines pre-processor function macros in many places. Some of them can lead to nasty errors when invoked in a wrong way. Such problems can fairly easily be tracked down by looking at the resulting pre-processed code. Several people asked for help in the forum after passing a wrong number of arguments to KEYMAP_STACKED(...).

Pre-compilation is another topic I will come back to later.

Kaleidoscope is a very small codebase and it compiles within dozens of seconds. But while developing and building, those dozens of seconds are dozens too many if you could have a build within a portion of a second (using Ninja) when e.g. only a single file changed. Build times sum up rapidly during change-build-test cycles. Yes, partial rebuilds do matter (at least to me :wink: because I am an impatient guy).

I definitely agree with both and would also love to offer (internally) complex plugins to newbie users without bothering them with an additional build system and additional build steps.
The CMake build system with multiple backends was just a spontaneous idea. I wouldn’t insist. If there is any other way based on Arduino-Builder alone, I am definitely positive about it and interested.

Now we arrived at the topic pre-compilation.
The choice is between expecting the user write a huge amount of ugly C++ and macro code like the following (parts of my QMK firmware) which uses Papagenos (wrapped) C-interface

or something simple and descriptive in the line of the following (abreviated example) - regardless whether in the sketch or an additional file

glockenspiel_begin

default: event_timeout = $200$

action: Key_Enter <KEYCODE>

input: TestKey1 <KEYPOS> = $3, 7$
input: TestKey2 <KEYPOS> = $3, 8$

% A two key chord
{TestKey1, TestKey2} : Key_Enter

glockenspiel_end

which the Glockenspiel-compiler automatically compiles to this

Glockenspiel does only generate little procedural code (a very small setup function) but mainly an optimized statically allocated data structure. That’s another reason why I went the DSL-road. A pre-compiler can optimize the search tree to something that uses minimal PROGMEM and RAM and goes without dynamic memory allocation.
That is not possible at compile time based on a C/C++ interface - at least not without excessive template meta-programming which is something that I try to avoid where I can because it is even worse to maintain. A pre-compile also allows to exclude memory-wasting search-tree setup code from the firmware binary which additionally safes a lot of PROGMEM.

For the time being - until Kaleidoscope-Builder supports additional build steps - the user can compile the Papageno stuff manually to go without Leidokos-CMake. But I really would appreciate to automatize this to make the plugin as user-friendly as possible.

Leidokos-CMake was just released recently. It is build and tested automatically on Windows, MacOS and Linux.
You could contact me and ask for support. That way, I could improve the documentation where necessary to also provide a better experience for other users.

I definitely would prefer that to you writing that you failed miserably :frowning:

That’s another reason why Leidokos-CMake came to life. I doubt that there is a way to get this with wrapping Arduino-Builder in CMake. Many IDEs support CMake projects and allow to build individual targets or even object files. This information that must be made available by the build system to the IDE is only known to Arduino-Builder.
Include directories are another (less) critical issue. IDEs’ code parsers must know where to look for includes for being able to parse and understand the overall code base. Most IDEs allow to specify include directories manually, though.

We had some discussions about this topic here.

I just ran the tests based on the latest Kaleidoscope Arduino-Boards. There was a build error that I fixed. Leidokos-CMake should now work acording to the documentation.

The problem is that it is hard to keep track of changes in Kaleidoscope. That’s why I plan to bind releases of Leidokos-CMake to specific versions of Kaleidoscope Arduino-Boards.

Here is a new release

@jesse: Are there any plans for a release schedule of Arduino-Boards. The last official release is from last Novermber. It would be nicer to write “tested with Kaleidoscope Arduino-Boards v1.23” than “tested with keyboardio/Arduino-Boards@309a4b9”. Also plugins or other projects that depend on Arduino-Boards and that want to provide CI testing could release new versions following a synchronized schedule.
Or is there any other way that one could receive automatic notification when a github project rolls out a new release? If so, a schedule would not be necessary.

There isn’t currently a schedule for ‘official’ builds. We definitely need to push a new release soon. I need to spend a bit of time going through the current state of known issues and open pull requests. At the moment, I’m still hardware focused and most of my software cycles are going to keyscanner improvements. (Algernon is, of course, still pushing the firmware forward.)

You could, perhaps, poll https://github.com/keyboardio/Arduino-Boards/tags.atom?

Thanks, that looks like a possible way. I am just not very experienced with newsfeeds. I will see how I could do the polling automatically…

I agree. And that’s something that would be straightforward to offer with kaleidoscope-builder, simply by not cleaning up our build directories (or possibly switching to a stable build directory).

I do not disagree with any part of that statement :slight_smile:

:+1: This may be a case where it’s worth asking the Arduino developers mailing list.

Yup. There are places for DSLs. Me being cautious about them doesn’t make them wrong.

I think the goal we should be going for is for Arduino-Builder to support this, rather than Kaleidoscope-Builder. If getting Kaleidoscope-Builder to support a prebuild command at the top level would be ‘enough’ for you to feel comfortable using the standard build infrastructure instead of having to maintain your own, that should be a relatively tiny change that could be done quite quickly.

Of course, I understand if it’s not :wink: