Closed cmnrd closed 3 years ago
I agree that the behavior should be the same across targets, and I think your suggestion to put generated code in <project-root>/src-gen
when running in INTEGRATED
mode, and in <cwd/src-gen>
when running in STANDALONE
mode indeed is the most sensible solution. Unless anyone disagrees, I'll make the change as soon as I get to it. Also, :+1: for the suggestion to add an output path to lfc
:-)
I think the best solution (TM), would be for all targets to use the IFileSystemAccess2 interface that xtext passed to the doGenerate method. This already defaults to the behavior suggested above. I already added a method getAbsolutePath(IFileSystemAccess2 fsa, String file)
to the generator base, that converts a /
separated path relative to the src-gen directory, to an absolute path in the file system. This is very handy when it comes to copying files from the lib dir or for executing commands in a certain directory.
It is also possible to modify the configuration of the file system interface. I didn't look into this yet, but this should allow us to override the default location. Thus we can take a target output directly given to lfc
and update the configuration once in generator base.
sounds good to me.
While we are at it: I think we should also add an option to both lfc
and the GUI to clean up the generated directories. I am just not sure how this would work in the CLI version. For the GUI version I think it is simple: delete all the generated files for the entire project. But for the CLI version this is not safe to do. Simply deleting the src-gen
directory (and others) in the CWD
seems dangerous to me. Maybe we need some kind of manifest file that keeps track over all the generated files and then clean only deletes files listed in the manifest.
Why can’t the user just do rm -rf src-gen?
Because it is a bit more complicated than that. For the C target, for instance, one needs to run rm -rf src-gen bin
to clean everything. This is even more complicated for the C++ target (rm -rf bin build include lib share src-gen
) because it creates various artifacts. I am not sure how cleaning would work in TS.
Probably we should also talk about these other directories. I think src-gen
should really just contain the generated sources. But where should we place all the build artifacts? If we can find a common directory structure, we could stick to the rm -rf
approach.
@edwardalee pointed out the issue of generated source and binaries for .lf
files with the same name but different targets (obviously located in different directories, but within the same project) overwriting one another. To avoid this, we could feature the target in the output path. I.e., we'd put things in <project-root>/src-gen/<target>/
when running in INTEGRATED
mode, and in <cwd>/src-gen/<target>/
when running STANDALONE
, but this seems a bit odd as well.
There's also another solution: if we introduce packages (which has been suggested we do as part of an effort to revamp the import mechanism), we'd get an error if there were two classes with the same name in the same package, and we could use the package name rather than the target name in the src-gen
directory to avoid clashes in the file system. If no package is specified, we'd simply search the entire resource/classpath for name clashes and report them...
Also, @cmnrd mentioned:
We could easily avoid the name conflicts, by placing the generated files in a directory tree that resembles the original source tree. For example, if we compile foo/bar.lf the generated source code could be placed in src-gen/foo/bar/ and the binary in bin/foo/bar. This is also how xtend handles this issue. We should only take care to use the same convention across targets.
Closing this issue as it was addressed in #319
I have noticed that the file generation across targets uses different approaches which also leads to generated files being placed in different locations. I want to start a discussion about this and hope that we can decide for a common approach.
Consider the source file
<project-root>/foo/Bar.lf
where<project-root>
refers to a project directory in the eclipse workspace. When compiling the fileBar.lf
, this is what currently happens in the different targets:<project-root>/foo/src-gen
(In the directory containingBar.lf
. This happens when compiling from Eclipse and when compiling vialfc
.<project-root>/src-gen
. When compiling vialfc
, it places the generated files in the current working directory:<CWD>/src-gen
.<project-root>/foo/Bar/
when compiling from both Eclipse andlfc
.I think in any case, we should stick to the usage of
src-gen
. The TS target can create subdirectories as needed within (src-gen/Bar
). This is also what the C++ target does.But where should the
src-gen
directory be placed? I personally prefer the Xtext default which is used in the C++ target. When runninglfc
, I would expect it to operate in the CWD and not to create new files next to the specified input file. When compiling from Eclipse, it createssrc-gen
in the project root. I am not a regular Eclipse user, but I think that is also what most Eclipse users would expect. It acknowledges that Eclipse has the notion of a project to group related things. If the generated code of two LF files should not be placed in the same src-gen directory, then those two files should actually not be part of the same project.What is your opinion on this matter?
Independent of what the default behavior should be, I think it would make sense for
lfc
to accept an optional command line argument that allows the user to specify the output directory.