CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Why is wmakelnInclude designed the way it is? (https://www.cfd-online.com/Forums/openfoam-programming-development/175095-why-wmakelninclude-designed-way.html)

knuckles July 23, 2016 12:55

Why is wmakelnInclude designed the way it is?
 
As far as I can tell,
  • wmakelnInclude is called by wmake
  • its job is to place a symlink to each of this module's source file swithin the directory lnInclude, so that subsequent modules which depend on this module can be instructed to search for headers within lnInclude - without it, subsequent modules would need to know the exact path to each header they included
  • it does not make symlinks to files from other modules which this module #includes
This means that if I'm compiling module C, which includes B.H, which includes A.H, my Make/options needs to say
Code:

EXE_INC = \
    $(LIB_SRC)/B/lnInclude \
    $(LIB_SRC)/A/lnInclude

i.e., even though my module does not depend directly on A, I am required to point wmake to the directory where A.H an be found. It seems to me that it would be better if wmakeLnInclude also did the following:
  • Generate .dep files for all source files (including headers)
  • Find all files listed in the .dep files (by searching through the directories specified in EXE_INC) and create symlinks to them within lnInclude
This would mean that lnInclude would contain symlinks to all of this module's files and all files that this module depends on. The programmer would then only need to consider the direct dependencies of a module when writing Make/options; in my ABC example, the $(LIB_SRC)/C/Make/options could be changed to
Code:

EXE_INC = \
    $(LIB_SRC)/B/lnInclude

because a symlink to A.H would be present in $(LIB_SRC)/B/lnInclude. Granted, this would completely fail if module B were not built before module C, but then the current system would as well.

It seems to me that the current system forces the programmer to dive into the dependencies of the modules that (s)he uses, and that this is a task which would be easy to delegate to a script. What's the motivation behind the current approach?

GerhardHolzinger July 26, 2016 07:54

Here is my take on the build system:

If wmakeLnInclude would work the way you describe in your post, you would generate loads of symlinks.

In the current implementation, each module has its own lnInclude folder which contains symlinks to all files belonging to that very module. Thus, if you search for a particular file in your OF sources by name, you find it twice. The file and the symlink.

Code:

user@host/OpenFOAM/OpenFOAM-dev/src$ find . -name fvMesh.H
./finiteVolume/lnInclude/fvMesh.H
./finiteVolume/fvMesh/fvMesh.H

If each module, which uses fvMesh.H would also create a symlink to fvMesh.H in its own lnInclude directory, you would end up with one file fvMesh.H and plenty of symlinks to fvMesh.H.
Furthermore, under the system you proposed, there would be a mix of links to files belonging to the module and links to files belonging to other modules in a module's lnInclude directory.

A compiler warning/error pointing to the file moduleA/lnInclude/X.H would then not automatically indicate, that file X of moduleA is at fault. It could also be file X of moduleK.

Granted, you would eliminate the need to include many lnInclude entries in the Make/options file, however, under the current system there is a clear division of labour (or knowledge).

The lnInclude folder contains all the symlinks to the module's own files. Whereas, Make/options contains all information on the dependencies of a module.

knuckles July 26, 2016 13:10

Good points. I don't think that any of the issues you raise are insurmountable, though:
  • symlinks are small - having lots of them isn't inherently problematic
  • searching with "find -type f" limits results to real files (not symlinks)
  • symlinks to source files from other modules wouldn't have to go directly in lnInclude - the could go in lnInclude/secondary or similar. Symlinks to "this module" files and to "other" files could still be separated
  • If a compiler warning points to A/lnInclude/K.H, I would argue that it doesn't matter if this is really a symlink to K/lnInclude/K.H, which is really a symlink to K/somepath/K.H. If I want to open K.H to see the offending code, opening A/lnInclude/K.H will show me exactly the same thing as opening K/lnInclude/K.H or K/somepath/K.H would. If it's important to know where the real K.H is, that information can be extracted from the symlinks.
An alternative option would be to have wmakelnInclude generate symlinks to the lnInclude directories of direct dependencies: when C depends on B depends on A, B/lnInclude contains a symlink "A" pointing to A/lnInclude and C/lnInclude contains a symlink "B" pointing to B/lnInclude. Assuming that wmake could be updated to search lnInclude recursively, this could also alleviate the issues you raise in slightly different ways:
  • fewer symlinks would be generated (one per module dependency, rather than one per source file dependency)
  • "find [sourcefile]" would work as in the current system - only the actual file and one symlink to it will be found
  • source files from other modules would be easy to identify by the fact that they'd appear to be within subfolders in lnInclude (although in reality they'd be behind symlinks)
  • if the compiler complained about C/lnInclude/B/A/A.H, then the path would indicate that C included B included A and thus A.H could be found in A/lnInclude/A.H . The text could still be viewed through the symlink C/lnInclude/B/A/A.H
Either way, it seems to me that a modified wmakelnInclude could maintain the separation that you point out (between "this module" symlinks and "external dependency" symlinks) but would also offer the additional benefit of automation (the user would only need to identify this module's direct dependencies).


All times are GMT -4. The time now is 02:43.