-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
build,examples: add build system #23853
base: master
Are you sure you want to change the base?
Conversation
Connected to Huly®: V_0.6-22257 |
I would be nice if a task could be run dependent on the existence of a file or artifact, similar to GNU make. This would be nice for c dependencies and would not run again if the file already exists. context.artifact(
name: 'cimgui',
file: 'thirdparty/cimgui/libcimgui.a',
run: || system('cd thirdparty/cimgui && make static')
)
context.task(
name: 'build',
depends: ['cimgui'],
run: || system('v .')
) |
You could also just use an if statement in the task's code, like so: context.task(
name: 'cimgui',
run: fn () {
if !exists('thirdparty/cimgui/libcimgui.a') {
system('cd thirdparty/cimgui && make static')
}
}
) I do see the benefit in there being a shorthand, although the name |
|
Make, for example, checks the timestamp of source files against the timestamp of the built "things", and will not re-build if the built "thing"'s timestamp is later than the source. For a more concrete example, if compiling C source to
Most of that won't directly apply to V, unless you want to check the V cache against the V source, but only if |
|
||
// Run the build context. This will iterate over os.args and each corresponding | ||
// task, skipping any arguments that start with a hyphen (-) | ||
context.run() |
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.
What happens for just v build.vsh
?
Is there a concept of a default task?
In make
, the first rule is the default one.
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.
It errors and tells you that you didn't provide any tasks to run, along with mentioning that passing --tasks
will show a list of tasks.
A default task would be good to have, although I'd rather it not just implicitly be the first task. I didn't even know Make done that...
Maybe we could have a default
parameter in the params for task()
, and when true it will function as the default. If multiple are defined then it would error out with a message saying that there can only be one default task.
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 like the idea of a default parameter. make
handles it with the .DEFAULT_GOAL
special variable, or by you specifying what you want run on the command line.
https://www.gnu.org/software/make/manual/html_node/How-Make-Works.html
Of course, you could still adopt the "first rule is default" style if the default parameter isn't set... just document that's what will happen, and how to set the parameter to change it.
@@ -0,0 +1,5 @@ | |||
import os |
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.
imho add a v.mod
file here too, as well as a common/
folder, with a f1.v
and f2.v
files in there, each starting with module common
, and having 2 different public functions, both used by main.v
(after it does import common
).
The general idea, is to make it easy to test, that the build system supports dependencies, and imports, so that later, modifying common/f1.v
, will lead to invalidating the tasks, that depend on main.v
too, and re-running them.
Modifying common/f2.v
should do the same.
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.
Note: v -print-watched-files main.v
will output a list of all the .v files, that are involved in the compilation of main.v
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.
The build system is not doing anything to change how import
would normally function, nor dependencies. I can add automatic dependency downloading (i.e, automatically running v install
to install dependencies in the v.mod
file) if that's what you mean
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.
Build systems are often used for building middle to big projects, that tend to contain several files in them, that depend on each other.
What I mean here, is that the example itself, can contain several files, and I am pointing out the way to do it (adding a v.mod file, + two other, that will be compiled as part of the same project).
That would be useful, so that later, me, or anyone else that wants to review the PR, or check if the build system is suitable for his/her purposes, can check, how the build system reacts to changes to each of the files, without having to create a dummy project from scratch on which to run it, to see the behavior.
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.
Note: I do not care about the task runner aspect, as much as about the build system aspect.
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.
Build systems are often used for building middle to big projects, that tend to contain several files in them, that depend on each other.
What I mean here, is that the example itself, can contain several files, and I am pointing out the way to do it (adding a v.mod file, + two other, that will be compiled as part of the same project).
That would be useful, so that later, me, or anyone else that wants to review the PR, or check if the build system is suitable for his/her purposes, can check, how the build system reacts to changes to each of the files, without having to create a dummy project from scratch on which to run it, to see the behavior.
Yeah I understand this. Though I'm not sure I see why the build system needs to manage imports at all, if it modified how import
would normally behave then I see a reason. At the moment I'm just a little confused by what you mean
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.
He's not saying anything about imports. He's saying that an example for a build system should show examples that make sense for a build system. Only having a single file doesn't really show anything except that the single file can be built.
With multiple files, you can show how if one has already been built, it doesn't get built the next time if it hasn't changed, while those that have been changed are rebuilt, etc.
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.
If I want to rebuild a project, that has no modifications to its source files, and that was already build, the build system should do nothing (since the target executable will already exist).
If I have a project that has modified files in it, the question of whether the target executable should be rebuild, becomes more complicated, and to be solved, it requires the build system to know/record which .v files were used, for the building of the executable, and to only rebuild it, if at least one of them has been changed.
For example, I may have a project that builds 2 executables, one that is build from tool1.v
+ common/*.v
+ somemodule1/*.v
, and another one, that is build from tool2.v
+ common/*.v
+ somemodule2/*.v
.
Note how common/*
is used in both, but somemodule1/*.v
is used only by tool1.v
.
If I make a change in one of the .v files in common/
, the executable tool1.exe
should be rebuild, even if tool1.v
itself was not changed at all. tool2.exe
should also be rebuild potentially.
If I make only a change in somemodule1/*.v
however, then only tool1.exe
should be considered for rebuilding.
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.
Ohhh okay I see what you mean now
I think that each task may need 2 callbacks: The second callback Separating the 2 callbacks allows for caching the output of the |
This PR introduces a small
build
module into the Vlib, based on the API in Clockwork. It's not quite 1:1 but is still similar.I am seeking feedback, just leave a comment here if you have any!
This PR will remain a draft while I am receiving feedback, once I feel like it's in a more comfortable state then I will un-draft it.