External Builder. Avoid delete source files on next build
Planned
Hi,
I'm writing an external builder for a dsl. This dsl generates java source code. Part of it goes to gen directory and the other to src directory. I have a `ModuleLevelBuilder` with category `SOURCE_PROCESSOR`, so it's called before the Java builder.
The problem is that registering all outputs, on the next build the files created in src directory are deleted.
If I don't register the files created in src, the java builder doesn't add to compilation unit, and the compilation fails because gen code depends on clases from src files that are not included in compilation.
Is there any way to achieve what I need? For example avoid deleting files on next build, or other way
Thanks!
Please sign in to leave a comment.
Hi Octavio,
> registering all outputs, on the next build the files created in src directory are deleted.
from the point of view of your builder (source generator), generated sources are the output. Normally the build system deletes "outputs" that correspond to changed "sources".
Could you please provide details on how exactly you register the generated files?
Hi Engene
Thanks for answer and sorry for the delay. I try to detail the process:
I have a DSL with a builder (source generator) wich outputs are java clases. Some of the outputs are generated every time and I want to overwrite in the gen directory and some clases I want to generate in the src directory only if them aren't exist. These clases (src) will be modified by the user and I don't want to delete.
I know that when I invoke a rebuild, all outputs registered by my builder are deleted, and if I invoke an incremental build only the classes generated which correspond with the modified inputs are deleted.
What I need is a way to register the src generated classes in order to compile them and avoid to remove then in any way on the next build, because they maybe have been modified by the developer and he need to preserve them.
You can see the details of how I register the outputs here:
https://github.com/intino/plugin/blob/master/jps-plugin/src/org/jetbrains/jps/intino/compiler/IntinoBuilder.java
method finish and registerOutputs.
Resumed, I register the outputs using OutputConsumer.registerOutputFile and then I mark the output as dirty for the current compilation round.
Thanks!
> What I need is a way to register the src generated classes in order to compile them and avoid to remove then in any way on the next build, because they maybe have been modified by the developer
Here we have two desired effects:
- mark generated source 'dirty' in order to compile it
- delete generated sources that correspond to changed "origins", i.e. changed files that the generator used as sources to generate the java code.
To ensure the generated source will be compiled you only need to mark it with FSOperations.markDirty(), no need to call registerOutput()
To prevent some of generated sources from deletion by the JPS just don't register them with outputConsumer.registerOutputFile(). You only need to use this API if you want JPS to track changes later and delete output files automatically as the corresponding "origins" are changed or deleted. This is the main point of registering: once registered, the expected behavior is that JPS will delete the output when required.
If you choose not to register some outputs, the builder has to take care of their life cycle separately: for example, you should define when such files need to be deleted. The solution depends actually on the DSL rules that are defined by you.
Alternatively I would also suggest to reconsider the approach when a user has to modify anything that is generated. If you manage to keep generated and user-editable files separately, that would greatly simplify code generation and the management of generated code. (for example, it can be easily deleted and re-generated without the fear of loosing changes added by user)