How to use headless build for continuous integration?
I'd like to check if any pull requests break the build by automatically running headlessbuild as part of CI.
Unfortunately, there's a critical flaw with how STM32CubeIDE projects are setup, which makes this impossible.
The headless build depends on content in .metadata. This folder is automatically created when importing a project into STM32CubeIDE. But .metadata is also automatically added to .gitignore. It's definitely correct to ignore .metadata, since that contains a lot of user-specific content that you don't want to share among developers. But this now means that headless builds from a fresh clone don't work either.
You can try this out yourself by cloning this repo and branch. Note that this project is setup for Linux, but I'm sure you can reproduce the same issue on Windows too from a new project. You'll just need to call the headless build command directly, instead of using the ci.sh script.
git clone --branch issue-report https://github.com/milesfrain/stm32demo.gitAnd running:
./ci.sh+ /opt/st/stm32cubeide_1.4.0/stm32cubeide --launcher.suppressErrors -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -build all -data .
Building All Projects...
Building workspace
Saving workspace.
+ rtval=0
+ echo exit status: 0
exit status: 0
+ exit 0Note that the build appears to work (exit code of zero indicates success), but it simply failed to find any projects to build.
In order to actually get headless build to work, you must open it once in the IDE first:
Open STM32CubeIDE
Select the cloned repo your workspact and import the ci_test project with:
File > Open Projects From File SystemIf you run `git status` you'll see that a .gitignore file was created to ignore .metadata.
Now the headless build will actually execute the build (with an intentional compilation error for testing purposes). Note that you need to close the IDE before building via command line.
./ci.sh
+ /opt/st/stm32cubeide_1.4.0/stm32cubeide --launcher.suppressErrors -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -build all -data .
Building All Projects...
Building workspace
Building '/RemoteSystemsTempFiles'
Building '/ci_test'
...
../custom/src/mainCpp.cpp: In function 'int main()':
../custom/src/mainCpp.cpp:3:3: error: 'broken' was not declared in this scope
broken();
^~~~~~
make: *** [custom/src/subdir.mk:18: custom/src/mainCpp.o] Error 1
make: *** Waiting for unfinished jobs....
"make -j4 all" terminated with exit code 2. Build might be incomplete.
17:42:58 Build Failed. 3 errors, 0 warnings. (took 643ms)But if you simulate sharing this code with another developer or pushing to CI, for example with a commit and a clean, then the headless build will will fail to actually build the project again and report a false success (exit 0). Note that we'd generally want to ignore the build outputs, but I'm committing those in this case for simplicity.
git add .
git commit -am "some commit"
git clean -xdf
./ci.sh
+ /opt/st/stm32cubeide_1.4.0/stm32cubeide --launcher.suppressErrors -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild -build all -data .
Building All Projects...
Building workspace
Saving workspace.
+ rtval=0
+ echo exit status: 0
exit status: 0
+ exit 0So now I'm not sure how to more forward. I'd really like to take advantage of the built-in MxCube tooling, but it seems like the only way to have a shareable project among developers that's also testable via CI is to ditch STM32CubeIDE and just use the classic Makefile approach. I could try to muck around in .metadata to figure out what to explicitly NOT ignore for headless builds to work, but who knows if that will turn into another huge waste of time.
Version info:
- Ubuntu 20.04
- STM32CubeIDE 1.40 reported, but I believe it's actually 1.42
- FW_F4_V1.25.1 symlinked to /usr/share/stm_repo (but that shouldn't matter for reproducing this issue).
