-
-
Notifications
You must be signed in to change notification settings - Fork 8.3k
py/py.mk: Enable makefile for USER_C_MODULES path. #16960
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
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #16960 +/- ##
==========================================
+ Coverage 98.54% 98.57% +0.02%
==========================================
Files 169 169
Lines 21946 21968 +22
==========================================
+ Hits 21626 21654 +28
+ Misses 320 314 -6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Code size report:
|
Can multiple text files be supplied?
I think it does: originally there'de be an error message if passing a non-existing path? Anyway, isn't it somewhat confusing that USER_C_MODULES can either be the modules or a .txt, and that implementing it requires 2 different code paths? How about allowing both? E.g. if there would be a USER_C_MODULES_DEF or something like that, to point to a text file, you could in the .mk probably build the USER_C_MODULES variable by appending each value from USER_C_MODULES_DEF to it and leave the rest of the code the same instead of having to loop over MODULE_PATHS in a slightly different way. |
Taking a step back, I gather the goal here is to provide a mechanism for specifying / listing multiple C modules to include in a build that don't necessarily need to be in flat folders side by side like is currently required. I've wanted something like this myself, particularly to support different folder depths / locations so some can be in arbitrarily structured submodules. For some reason specifying just a list of paths in a text file like this "feels" wrong to me, though I'm not sure why, I'm possibly being quite unfair. Basically what I want is the manifest.py system but for the C modules, which leads me to think perhaps it'd be cleaner to extend the existing manifest.py handlers to also support C modules? The biggest benefit of the manifest system I can think of is that paths are always relative to the manifest file itself, or you have the variables you can use to start from the micropython root dir etc; having something like this would remove a lot of the confusion / discrepancy that currently exists between ports and the "current directory" that relative paths start from. |
It feels like the most reasonable (and probably controversial?) answer is: use CMake. I list multiple C modules frequently across a dozen or more builds just by including them into a CMake file... this feature is already implicitly supported since there's no restriction on what you can put into a Eg: https://github.com/pimoroni/pimoroni-pico/blob/main/micropython/modules/micropython-pico.cmake You can mix and match modules to your heart's content, conditionally enable modules, conditionally configure modules and pretty much anything CMake would ordinarily allow you to do. Want to include modules based on a variable you've set in a board level configuration file? Sure! Want to conditionally include modules based on build target? Go for it! Want to enable modules based on the selected board? Go nuts! Reinventing the wheel here is wasted effort, but we should probably document (or provide an example of) this mechanism for supplying multiple modules and maybe it's long past time that |
28f1878
to
4e637e7
Compare
Based on the feedback I've decided to update this and now the file is a makefile so one can add its own logic, the only requirement is to set
@stinos I guess now you could include multiple makefiles recursively. And no, this still checks first if the path is a directory, if it isn't then checks if the path exists, assuming it is a makefile.
@andrewleech I agree with this and I've updated the PR accordingly 👍🏼
That would be nice but it would probably take considerable more effort than this tiny change. @Gadgetoid I think that now with the makefile you could add the same logic right? |
@Carglglz this feels like a much more logical approach, thank you! |
py/py.mk
Outdated
$(error USER_C_MODULES doesn't exist: $(abspath $(USER_C_MODULES))) | ||
else | ||
# USER_C_MODULES is a .mk file | ||
$(eval include $(USER_C_MODULES)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of this user .mk file setting MODULE_PATHS
, wouldn't it be simpler if that .mk file just did what it needed to do, eg included other .mk files? Then it would work almost the same as the cmake version.
In that case the user .mk file would need to be included below, after setting the SRC_USERMOD variables to empty.
8dc1ae7
to
334752f
Compare
@Carglglz thanks for updating. Did you get a chance to test this new version? |
a11c637
to
328ab76
Compare
@dpgeorge yes, I've tested $ make USER_C_MODULES=../../examples/usercmodule and $ make USER_C_MODULES=../../examples/usercmodule/user_c_modules.mk they both work, I've also updated the docs (feel free to change anything) and let me know if I need to add this method to unix port coverage somehow? 👀 |
@@ -0,0 +1,12 @@ | |||
MODULES_PATH := ../../examples/usercmodule |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this ../../
bit of the path need to be hard coded here? Doesn't it mean that this example must be ../../
relative to where the port is?
If so, that won't work for general C libraries, eg ulab. There needs to be a variable that's available in this file which is the current path, like $(USERMOD_DIR)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this ../../ bit of the path need to be hard coded here? Doesn't it mean that this example must be ../../ relative to where the port is?
No, $(USER_C_MODULES_PATH)
can be used instead which is
USER_C_MODULES_PATH := $(dir $(USER_C_MODULES))
at this point
$(eval USERMOD_DIR = $(patsubst %/,%,$(MODULES_PATH))/$(module))\ | ||
$(info Including User C Module from $(USERMOD_DIR))\ | ||
$(eval include $(USERMOD_DIR)/micropython.mk)\ | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For this example, I'd suggest keeping it as minimal as possible, and similar to the cmake version. Eg just:
include cexample/micropython.mk
include cppexample/micropython.mk
include subpackage/micropython.mk
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with making it similar to the cmake version however then both versions will differ, i.e. this one won't show any information of which modules are included, and also $(USERMOD_DIR)
needs to be set for each module.
So you will end with something like this:
$(eval USERMOD_DIR = $(patsubst %/,%,$(USER_C_MODULES_PATH))/cexample)\
$(info Including User C Module from $(USERMOD_DIR))\
$(eval include $(USERMOD_DIR)/micropython.mk)\
$(eval USERMOD_DIR = $(patsubst %/,%,$(USER_C_MODULES_PATH))/cppexample)\
$(info Including User C Module from $(USERMOD_DIR))\
$(eval include $(USERMOD_DIR)/micropython.mk)\
$(eval USERMOD_DIR = $(patsubst %/,%,$(USER_C_MODULES_PATH))/subpackage)\
$(info Including User C Module from $(USERMOD_DIR))\
$(eval include $(USERMOD_DIR)/micropython.mk)\
So I think the single foreach loop is better, but let me know if you prefer this version 👍🏼
This enables setting a file path to select user C modules in a USER_C_MODULES directory, the same way CMake works. The file is a .mk file with the user modules required. USER_C_MODULES=<path/to/file>/user_c_modules.mk See examples/usercmodule/user_c_modules.mk for reference Signed-off-by: Carlos Gil <[email protected]>
328ab76
to
64e7618
Compare
This enables setting a file path to select user C modules in a
USER_C_MODULES
directory the same way CMake works.The file is a .mk file with the user modules required.
USER_C_MODULES
=<path/to/file>/my_user_modules.mkin my_user_modules.mk:
Note that this doesn't change current behaviour i.e. providing a directory path works as expected.
Summary
Testing
Trade-offs and Alternatives