Skip to content
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

Library configuration: allow multiple source directories #847

Closed
wants to merge 13 commits into from

Conversation

perazz
Copy link
Contributor

@perazz perazz commented Mar 2, 2023

This PR fixes #821 .

Library configurations already allow multiple include-dir directories, but only allowed 1 source-dir.
This patch extends fpm to specify multiple source dirs for library configurations:

[library]
source-dir=["src","src2"]
include-dir=["include1","include2"]

I think it would make sense to also extend this to executable configurations? @fortran-lang/admins
Or, it's better if we restrict all sources to be inside a single root directory, whichever named?

@zoziha
Copy link
Contributor

zoziha commented Mar 6, 2023

Support for multiple source file paths seems to be a new feature, and it seems good to create an example for it in example_packages folder and test it out?

@perazz
Copy link
Contributor Author

perazz commented Mar 8, 2023

Great suggestion @zoziha, thank you. So:

  • new sample package in example_packages/
  • custom folder array option extended to example, test, executable packages

OK for trunk?
If so, I can begin documenting this extension in https://github.com/fortran-lang/fpm-docs

Copy link
Contributor

@zoziha zoziha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After reading the submission code, I found that this PR did three main things:

  1. Multiple source file paths are supported.
  2. Add multi-source file paths support and a sample package.
  3. The path logic of example, app, and test is changed.

The first two are clear and understandable, but the third seems to break the old fpm source file scoping specification (my fault, I'll update this specification in fpm-doc, see fortran-lang/fpm-docs#95).

@@ -473,14 +473,22 @@ end subroutine add_dependency
!> a source file in the package of the correct scope, then a __fatal error__
!> is returned by the procedure and model construction fails.
!>
subroutine resolve_module_dependencies(targets,external_modules,error)
subroutine resolve_module_dependencies(targets,external_modules,source_dirs,error)
type(build_target_ptr), intent(inout), target :: targets(:)
Copy link
Contributor

@zoziha zoziha Mar 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logic of adding source_dirs argument breaks the fpm source file scoping specification. For details, see:

  1. Source file scoping specification
  2. Source file scoping specification fpm-docs#95

There may be some discussion or improvement needed to the source file scope of app, example, and test.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this screenshot, test/greet_test.f90 can access the app/test_mod.f90 file, which should not be allowed, but the fpm of the current PR code allows this to happen.

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zoziha Thank you for the thorough review - this was not entirely clear to me when I read the code, thank you for documenting it. I will work on some modifications, because like you're pointing out, right now a unique directory search list is built for all targets

@minhqdao
Copy link
Contributor

minhqdao commented Mar 10, 2023

As pointed out in #821 (comment), #821 (comment) and by yourself #821 (comment), I'm rather skeptical of the changes made in this PR.

What is the benefit of having multiple src folders instead of putting all of them inside src? What is the benefit of having multiple test and executable folders? Imagine you're seeing a project for the first time, do you prefer this:

project
│   README.md
│   LICENSE
└───src
│   └───module_a
│   │      a.f90
│   └───module_b
│          b.f90
└───test
    └───test_module_a
    │      a.f90
    └───test_module_b
           b.f90

Or this:

project
│   README.md
│   LICENSE
└───module_a
│      a.f90
└───module_b
│      b.f90
└───test_module_a
│      a.f90
└───test_module_b
       b.f90

Then having to read the manifest to know which modules are app, source, executable and test modules?

Here are some suggested project structures in other languages/frameworks:

I think it is quite apparent that people have been moving away from "collect your source code that's all over the place using complicated build tools" to streamlined processes, while those are visually highlighted by having a clear project structure with dedicated folders for each process. fpm is there to facilitate these streamlined processes for Fortran, therefore I think we shouldn't even give the user the option to mess up the project structure. Allowing the user to define different test, executable and source folders to me feels like we are going back in time, rather than giving the user valuable options.

Having to have a single src folder isn't a restriction because you are free to have as many layers inside as you wish while making sure that the overall package layout always looks clean and comprehensible to new users.

@certik
Copy link
Member

certik commented Mar 11, 2023

I think I agree with @minhqdao's comment, I also think we should keep the structure simple. We can always relax it later, but we can't restrict it later without breaking backwards compatibility. There is great advantage of having restrictive layout, because it makes projects look uniform and easy to understand, and it's easy for us to maintain and test fpm. Regarding existing projects with a complicated build systems, I think to support those all we need is to provide an escape hatch, such as allowing to call a build script (which can then call cmake or make or build things by hand), so that the user can build any project. I believe that's how Cargo does it.

@perazz
Copy link
Contributor Author

perazz commented Mar 11, 2023

@certik @minhqdao Thanks for your comments. Let me summarize fpm's current state of the art:

  • for executable targets we have app/ (default) or an arbitrary user-defined source-dir
  • for test targets we have test/ (default) or an arbitrary user-defined source-dir
  • for example targets we have example/ (default) or an arbitrary user-defined source-dir
  • for library, we have one source-dir and one or many arbitrary include directories.

The CLI help:

fpm/src/fpm/cmd/new.f90

Lines 270 to 281 in b364bd8

&'[library] ',&
&' ',&
&' # You can change the name of the directory to search for your library ',&
&' # source from the default of "src/". Library targets are exported ',&
&' # and usable by other projects. ',&
&' ',&
&'source-dir="src" ',&
&' ',&
&' # this can be a list: ',&
&' ',&
&'#source-dir=["src", "src2"] ',&
&' ',&

has been saying that multiple source folders should be possible for about 3 years (they're currently not), that's what originated this issue I guess, and why it seemed reasonable to me, and in line with the current fpm scope, to go ahead with coding what was part of the original design. I agree it's a design decision: does the fpm community want it to be a full build system that can handle complex folder structures, or a simpler handler of smaller packages?
If you think the latter vision fits not going forward with this PR, feel free to close it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

source-dir in fpm.toml must not be an array
4 participants