fpm icon indicating copy to clipboard operation
fpm copied to clipboard

Library configuration: allow multiple source directories

Open perazz opened this issue 2 years ago • 5 comments

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?

perazz avatar Mar 02 '23 09:03 perazz

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?

zoziha avatar Mar 06 '23 03:03 zoziha

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

perazz avatar Mar 08 '23 10:03 perazz

As pointed out in https://github.com/fortran-lang/fpm/issues/821#issuecomment-1451790466, https://github.com/fortran-lang/fpm/issues/821#issuecomment-1464052367 and by yourself https://github.com/fortran-lang/fpm/issues/821#issuecomment-1451866399, 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:

  • Rust: https://doc.rust-lang.org/cargo/guide/project-layout.html
  • C++: https://medium.com/swlh/c-project-structure-for-cmake-67d60135f6f5
  • Java/Maven: https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html
  • JS: https://stackoverflow.com/questions/5178334/folder-structure-for-a-node-js-project
  • Go: https://github.com/golang-standards/project-layout

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.

minhqdao avatar Mar 10 '23 17:03 minhqdao

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.

certik avatar Mar 11 '23 04:03 certik

@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: https://github.com/fortran-lang/fpm/blob/b364bd803311a85d3cffa38cd6e3a639eac74b4c/src/fpm/cmd/new.f90#L270-L281

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.

perazz avatar Mar 11 '23 10:03 perazz