For several projects I’m using library projects: I build a library and then use that library in the other project. If I change something in a library, I want to run make both on the referenced libraries and rebuild my application if needed. If you don’t know how to do this, then read on… 🙂
(… actually it means workign around known Eclipse CDT bug too….)
Outline
I’m using the MCUXpresso IDE v10.0.2 in this, but basically it should be the same for any other Eclipse CDT distribution (e.g. Kinetis Design Studio or others).
In this article I’m going to use three projects:
- A is a library project producing the library libA.a
- B is a library project producing the library libB.a
- C is the application project and uses libA.a and libB.a
Below it shows the projects and output files in Eclipse:
When compiling the project C, it shall:
- rebuild the project A and/or B if they have changed
- if A or B have changed, the project C shall link the new libraries
Project References
In the project settings, there are the ‘Project References’:
Referencing another project will check and build the referenced projects. As for above, if I build the project ‘C’, it will go and build first ‘A’, then ‘B’ and finally ‘C’.
The think is: this only triggers running the make process for the referenced projects. It will *not* trigger a make for the ‘C’ project if one of the referenced projects is changing. I still have to run the build/make for the ‘C’ project.
Linking Libraries
The usual way to link libraries with the application is shown below, using the -l and -L linker options:
Now one would think that this is all what is needed: with the libraries listed in the linker options, it will relink the application if one of the referenced libraries? Actually this is not the case :-(. It will only build and relink the project if a file of the project itself has changed, but not if a referenced project has changed.
I have found this as a bug in Eclipse CDT managed make. One can see the problem with the managed make file produced by Eclipse CDT:
# Tool invocations C.axf: $(OBJS) $(USER_OBJS) @echo 'Building target: $@' @echo 'Invoking: MCU Linker' arm-none-eabi-gcc -nostdlib -L../../A/Debug/ -L../../B/Debug/ -Xlinker -Map="C.map" -Xlinker --gc-sections -Xlinker -print-memory-usage -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -T "c_app_Debug.ld" -o "C.axf" $(OBJS) $(USER_OBJS) $(LIBS) @echo 'Finished building target: $@' @echo ' ' $(MAKE) --no-print-directory post-build
The rule for C.axf only depends on the project object files plus any user object files. The target C.axf does *not* depend on the $(LIBS) which I have specified above in the linker options.
💡 see Tutorial: Makefile Projects with Eclipse for a more detailed view about make files and make rules.
Other Objects
The solution (or better workaround) I’m using is to specify the libraries in the $(USER_OBJS) list which are configured as ‘Other objects’:
With this: if I build the ‘C’ project and the ‘other objects’ have been changed, it will link them.
Summary
I can use the ‘Project References’ setting in Eclipse CDT to reference other projects. Eclipse will call make for the referenced projects when I build the ‘master’ projects which is a handy thing for library projects my application depends on. In order to trigger a re-linking of my master project if any of the depending projects have been changed, I have to specify the libraries in the ‘Other objects’ settings. Then everything works as I would expect it.
Happy Depending 🙂
Great post! Have been lookig for this.
How do you do dependency magement in source code management tools like git?
Having separate repositories and thus separate projects is the modular approach and allows to perform exactly what you described here. But this requires the developer to specify which branch and commit should be used for building Project C – and this becomes a mess in my experience.
There are other ways, like git submodules or committing binaries. Did you ever solve this “issue of dependency management”?
KR
Marc
LikeLike
Hi Marc,
thanks :-). I usually do not separate things out of repositories. Instead, I have the project(s) in the repository and do the dependency inside. And if using different branches/tags in parallel, I simply can clone the repository into multiple directories. I have not used submodules, as I have not needed them (I rather would split the repository then). But this is just me, others will see this differently I think.
For more complex repository setup, I run a script file which does the checkout/etc for me.
Erich
LikeLike
I think a post on SVN/git management for embedded projects in Eclipse-based IDEs would be interesting.
There are many on line, but I am curious of the DEV perspective instead of the IDE producers one.
LikeLike
I agree with Luca. It’d be very interesting to hear how you solved this conundrum. Especially once a big(ger) team starts working on embedded Software you really start to miss a proper package manager for embedded applications. Nugets and the like are great, but not really suitable.
I think this whole issue doesn’t get the attention it deserves. Everyone seems to be either reinventing the wheel with every new embedded project or has trouble managing/versioning common libraries.
Writing portable code for most embedded applications might be harder, but is far from being impossible.
LikeLike
What I have been using sucessfully is using the components/package manager of Processor Expert: I can create software packages, distribute them on a VCS and have it used by the team. You might have a look at CMSIS-Packs (https://mcuoneclipse.com/2016/02/14/are-arm-cmsis-pack-the-future-of-software-components/) too. That approach could work for you too, although I have stopped using it.
LikeLike
Hi Erich,
firstly, I’d like to congratulate you on your work here at blog and for your effort on disseminate information.
I’ve recently migrate to MCUXpresso and I’m having problems adding features to my existing project (e. g. lwIP, USB Stack MSD FATFS…).
Once I add the files and include the paths at the MCU C Linker I continuously get build erros, as described in this post at NXP community:
https://community.nxp.com/thread/461849
I’ve managed to workaround the first struggle by copy my project on top of the example project of lwIP, and it worked. But, now I’m not able to do this anymore with the USB Stack.
Any thoughts on what the problem might be?
Best regards,
Gustavo Costa
R&D Engineer
LikeLike
Hi Gustavo,
it seems to me that the issue in https://community.nxp.com/thread/461849 is resolved and was because of wrong directory structure?
I’m not sure what problem you face with the USB stack, but I suspect it might be the same problem?
Erich
LikeLike
Excellent tip, thanks! Without this workaround, having multiple Eclipse projects depending on each other simply wouldn’t build properly. You’re a star! 🙂
LikeLike
Thanks! I was trapped by that thing in the past too, that’s why I wrote that article so I can google it if I need it again 🙂
LikeLike