-
Notifications
You must be signed in to change notification settings - Fork 108
Catch module+program or multiple modules in a source file and print a helpful message to the user #130
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
Comments
Just a comment: I noticed that fpm does allow more than one module in a file - and it seems to work: one of the source files I experimented with has a small module to define a type and then a module with the same name as the source file that uses it. So not two independent ones, I agree. |
For simplicity, I think by default fpm should simply expect one module per file, and impose the naming consistency convention. We can discuss if we should implement optional options in |
I think this has been fixed already. |
I tried the latest master and unfortunately there is no error or warning printed when more than one module is present in a file. How to reproduce:
apply the following patch: --- a/src/xx.f90
+++ b/src/xx.f90
@@ -8,3 +8,14 @@ contains
print *, "Hello, xx!"
end subroutine say_hello
end module xx
+
+module yy
+ implicit none
+ private
+
+ public :: say_hello
+contains
+ subroutine say_hello
+ print *, "Hello, xx!"
+ end subroutine say_hello
+end module yy then compile: $ fpm build
+ mkdir -p build/dependencies
+ mkdir -p build/gfortran_2A42023B310FA28D/xx
+ gfortran -c test/check.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/xx -I build/gfortran_2A42023B310FA28D/xx -o build/gfortran_2A42023B310FA28D/xx/test_check.f90.o
+ gfortran -c ././src/xx.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/xx -I build/gfortran_2A42023B310FA28D/xx -o build/gfortran_2A42023B310FA28D/xx/src_xx.f90.o
+ ar -rs build/gfortran_2A42023B310FA28D/xx/libxx.a build/gfortran_2A42023B310FA28D/xx/src_xx.f90.o
ar: creating archive build/gfortran_2A42023B310FA28D/xx/libxx.a
+ gfortran -c app/main.f90 -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/xx -I build/gfortran_2A42023B310FA28D/xx -o build/gfortran_2A42023B310FA28D/xx/app_main.f90.o
+ mkdir -p build/gfortran_2A42023B310FA28D/app/
+ gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/xx -I build/gfortran_2A42023B310FA28D/xx build/gfortran_2A42023B310FA28D/xx/app_main.f90.o build/gfortran_2A42023B310FA28D/xx/libxx.a -o build/gfortran_2A42023B310FA28D/app/xx
+ mkdir -p build/gfortran_2A42023B310FA28D/test/
+ gfortran -Wall -Wextra -Wimplicit-interface -fPIC -fmax-errors=1 -g -fcheck=bounds -fcheck=array-temps -fbacktrace -fcoarray=single -J build/gfortran_2A42023B310FA28D/xx -I build/gfortran_2A42023B310FA28D/xx build/gfortran_2A42023B310FA28D/xx/test_check.f90.o build/gfortran_2A42023B310FA28D/xx/libxx.a -o build/gfortran_2A42023B310FA28D/test/check No warning and no error. We need to be printing warnings (and even errors) every time:
And both can be overiden in |
A program and a module in the same scope seems completely reasonable to me. Multiple modules less so, still there are use cases for this (example). We have to be careful to not break existing projects or fpm itself when introducing this change. Therefore, this check should at first be opt-in for all projects, we can later make it the default once it found adoption. For example in TOML Fortran the package name To handle projects that can't map their package name to a prefix there should be an option in library: name = "toml-f"
[library]
namespace = "tomlf" # or maybe prefix? Regarding the opt-in/opt-out of this convention, what table is best suited for this purpose? I wouldn't put it under the top-level and build also does not seem fitting here. Finally, the namespace rules doesn't really apply for |
Yes, we definitely need to be careful and we don't want to break things. This is why it is very important to do these "compliance requirements" early in We don't need to require this restriction of just one program/module per file. But it seems like a good habit. The same with the naming convention. @everythingfunctional and I even brainstormed being more strict on module names and encode the path in them, say in One way we can enforce these things is with opt in options, that would be enabled by default for new projects ( defaults = "fpm 0.4.0" Which would enable (on opt-in basis) any defaults that |
I don't recall what we decided about this, but I think it was this: To protect against module name clashes between the project modules and those of dependencies, a naming convention needs to be enforced to ensure unique module names. @certik describes that convention above.
I don't think this is what's happening; I think it's more that it just hasn't been implemented. I'm in favor of this, for example. I also vaguely recall us having an overall consensus about this, though I can't find the thread. At the same time, we should also allow building valid Fortran code as much as the convention allows it. Is it possible to design a naming convention that would allow multiple-modules-per-source-file and modules+program in a source file? How about this:
And if this works, we should still detect and print a helpful warning message a-la:
For the program+module pattern which I enjoy very much, I wouldn't even print a warning. But that's just my preference; I wouldn't strongly oppose warnings for that. |
There are two conventions:
I like your thinking about multiple modules in a file. I also use module+main program in the same file sometimes. So I am not against it. As long as |
I'm also in favor of enforcing (with a light touch if possible, i.e. optional) a one module per file and naming convention rule, as it seems like a pretty clear best practice. I think we don't need such restrictions on app, example or test code, because it seems quite frequent to want to put program+modules in a single source file for the purposes of quick one-off and demonstration code. |
When we depend on a library, it's mainly the If so, it would make sense to be strict with the |
As previously discussed I agree with requiring project module prefixes as this is our only option for some form of name-spacing, however I strongly disagree with the need to invent and enforce a convention for naming modules based on file path. IMO, such a path-module convention would greatly restrict the ease and flexibility of using fpm as it is now. I don't see any concrete advantage to creating such a convention, but the cost in terms of project maintenance is quite significant. Consider the simple task of restructuring a growing project into subfolders: this would require manually renaming modules and renaming all This would also greatly complicate the task of converting existing packages to fpm since all modules would require renaming. I really do not think we should pursue such a rigid convention within fpm itself, even as an optional feature, but rather leave it up to project maintainers to use a good naming convention. |
Good point about renaming. Note that you have a similar issue in Python. If you move things around, the imports will break, so you have to fix them. If Fortran introduces some kind of namespaces, based on path, it would have exactly the same issue. Converting existing packages to |
See #126. fpm currently allows either a single module or a single program in a source file. However, Fortran allows having:
fpm should catch these scenarios and print a helpful error message for the user.
The text was updated successfully, but these errors were encountered: