tools/mkconstfs: Add an improved tool.#9282
tools/mkconstfs: Add an improved tool.#9282MichelRottleuthner merged 1 commit intoRIOT-OS:masterfrom
Conversation
MichelRottleuthner
left a comment
There was a problem hiding this comment.
looks good to me in general. the nested maps and lambdas could be split up a bit though.
I tested the generated file with examples/filesystem. everything looks fine - apart from the fact that the path properties of the generated constfs_file_t structs are missing a slash at the beginning, compared to the old mkconstfs.py. This leads to the files not being accessible. With an added slash infront of the filename everything works fine.
dist/tools/mkconstfs/mkconstfs2.py
Outdated
| lambda x: x[0]//16) | ||
| ) # noqa: E127 | ||
| ) | ||
| ) |
There was a problem hiding this comment.
wooha "the python foo is strong in this one" Not sure if this is more "nice and efficient" than it is "ugly and hard to understand/maintain"^^ I'm also wondering why you are mixing yield from and itertools.chain. I'm certain this can be written in a cleaner way, which might also help with getting rid of all the #noqa ... markers ;)
There was a problem hiding this comment.
actually I'm referring to the lines 105 -111
dist/tools/mkconstfs/mkconstfs2.py
Outdated
|
|
||
| parser.add_argument("-r", '--root', metavar="root_base_path", | ||
| help="Paths on the constf will be gerated for the real" | ||
| "path of the files by considering this path to be the root" |
There was a problem hiding this comment.
insert whitespaces at the end of the multiline strings above (i.e. after root, real, ..)
dist/tools/mkconstfs/mkconstfs2.py
Outdated
| "(i.e. there is no partial output") | ||
|
|
||
| parser.add_argument("-r", '--root', metavar="root_base_path", | ||
| help="Paths on the constf will be gerated for the real" |
|
@MichelRottleuthner I just realized this script will generate wrong paths if ran in a system that doesn't use UNIX paths. Is that a problem? |
dist/tools/mkconstfs/mkconstfs2.py
Outdated
|
|
||
| parser.add_argument("-o", '--output', metavar="output_file", | ||
| help="Write the output to a file instead of stdout." | ||
| "The file is only written if the command is successful" |
There was a problem hiding this comment.
If you use type=argparse.FileType here, argparse checks the file and mode for you automatically 1.
There was a problem hiding this comment.
For some reason, I didn't like FileType, but that was in the past and I think I forgot the reasons.
There was a problem hiding this comment.
Now I remember, it opens the file right away. Not a good idea with mode "w+".
Not a real problem but I'd prefer to make it as independent from the platform as possible. Its python so everyone will assume it works wherever python is available. |
I think the same, but I don't have a windows PC now, so I won't be able to test it. |
|
I have access to a windows machine here so I can help with testing if needed |
|
@MichelRottleuthner Could you test it? |
|
Tried it on a windows machine but it only seems to work if used with files that are not prefixed by a path (backslashes are not converted to slashes). I'll try to find time to look into a solution later today. |
|
@MichelRottleuthner Ouch! I knew I won't get the windows thing right. There is not chance of collision with things like |
|
|
||
|
|
||
| def addroot(fname): | ||
| return "/" + fname if not fname.startswith("/") else fname |
There was a problem hiding this comment.
Is it possible to rework this to something using the python os.path module or the pathlib module to keep it OS agnostic. It might just be what is causing issues for @MichelRottleuthner
There was a problem hiding this comment.
I think this won't help (for everything) because I also got backslashes in the middle of the path
There was a problem hiding this comment.
Ah, so do I understand correctly that the problem is that a path provided as path\to\file on windows shows up in the constfs as /path\to\file?
There was a problem hiding this comment.
Ourch, that is not supposed to happen, but it's not because of addroot.
There was a problem hiding this comment.
Just had another look. The problem actually occurs only if relative paths are used. It then not only leaves backslashes there but also creates some crazy paths like /../C:\path\to/C:/path/to/file. I played around with various os.path / pathlib methods and found the following fix to make it working on linux and windows in the same way:
--- a/dist/tools/mkconstfs/mkconstfs2.py
+++ b/dist/tools/mkconstfs/mkconstfs2.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python3
+import os
import sys
import argparse
import pathlib
@@ -50,7 +51,8 @@ static const uint8_t {varname}[] = {{
def _relpath_p(path, start):
- return posixpath.relpath(path.as_posix(), start.as_posix())
+ return posixpath.relpath(pathlib.Path(os.path.abspath(path)).as_posix(),
+ pathlib.Path(os.path.abspath(start)).as_posix())There was a problem hiding this comment.
@MichelRottleuthner Great! Can you push it to my branch, please?
There was a problem hiding this comment.
just tried that but somehow it doesn't work. Did you allow edits for maintainers?
There was a problem hiding this comment.
nope still doesn't work just add it yourself, please
sorry, my wording wasn't clear enough. What I meant was the name of the struct instance which is put into the constfs_name field in the C_FOOTER template. Arguably one coud blame the user for putting invalid names there but i think it would help if there is some kind of warning (or mangling).
I have to shift that to tomorrow... |
|
@MichelRottleuthner I think it's out of scope to check if the user tells the tool to create a struct with an invalid name. Almost every time this tool is used it will be from within a makefile and the name will be fixed. The Correct(TM) way of generating code and making sure it's correct is to create an abstract tree and dump it as code. Templating things we will always run into some kind of corner case, and it's not practical to check everything. As long as we don't generate wrong code that still compiles and fails silently and weirdly, it's ok. |
|
BTW, what is the opinion on dropping name mangling and going for serially generated identifiers? AFAIK, GCC allows for arbitrarily long identifiers, but then we could have a file that it a hairy mess of characters. |
|
since the user/dev will not use the mangled names in most cases anyway you could also use short numbered identifiers. This could also save some memory ;) |
|
@jcarrano squash and we are ready to go! |
The new tool (mkconstfs2) features: * more robust filename handling: no need for mangling, and works on Windows. * Better output generation: nothing is written in case of failures. * Allows more control over the files that are included: - does not traverse directories, filenames must be explicitly given. - The "root" can be explicitly given (thus the tool can get the same result independently of the CWD). Thanks to MichelRottleuthner for making it work with Windows paths.
|
@MichelRottleuthner Squashed and edited the commit msg to give you some credit. |
|
Oops, accidentally hit "close"!!! |

Background
I need to generate a constant file system to run the Lua test suite, and rather than roll my own, I decided to enhance the one already in RIOT.
The problems I found with the current script:
stdoutonly and does not buffer the whole output, meaning it can fail but still generate a partial output. When this is used inside a makefile, the result is that the first call tomakefails but on the second call there is already a (partial) file up to date andmakeignores the target.Contribution description
In order not to break code that may use the older script, this PR adds a new script with a different name.
Complete name mangling. It will only generate valid C identifiers.No more name mangling: no more problems.argparse.At some point I will extend the tool to embed files in other formats different from constfs.
Issues/PRs references
I need this for #9256.