Teaching VS Code where to find symbols in fpm dependency

I am trying to play with gtk-fortran. Since it is a huge library, I’d like to take advantage of VS Code + Modern Fortran’s nice features for autocomplete, jump-to-definition, etc. I am using gtk-fortran as an fpm dependency and am able to run some of the simple examples that come with gtk-fortran.

The problem I am having is that VS Code cannot locate the gtk-fortran modules. For example, the linter flags the line use gtk and complains that there is no “gtk.mod” file. I confirmed that when I build the application, fpm puts all the gtk-fortran module files in one of the “build/gfortran_…” directories. So I set up a workspace “settings.json” as follows:

{
    "fortran.linter.includePaths": [
        "${workspaceFolder}",
        "${workspaceFolder}/build/*"
    ],
   "fortran.fortls.suffixes": [".in"]
}

However, VS Code still cannot find “gtk.mod” or any other gtk-fortran module.

Now, if I copy all the module files into the project directory, then VS Code does find them and provides autocomplete, etc. for symbols provided by those modules. But I prefer not to copy these module over. I would think the search paths I provided should be able to detect modules in any fpm build subdirectory. Am I mistaken?

I’m on the go so I’ll edit my response later, but if you use

"${workspaceFolder}/build/**"

It should include all directories under build.
I can probably provide you with a task that installs things locally under workspace/build and you can point the linter to that, otherwise you won’t be fetching consistently the correct mod files of your project

1 Like

Hm, I tried that too and it does not seem to help. I thought ${workspaceFolder}/build/** should recursively search all directories. For completeness, here is the workspace directory structure

+---.vscode
|       settings.json
| 
+---app
|       main.f90
|   
+---build
|   |   .gitignore
|   |   cache.toml
|   |           
|   +---dependencies
|   |   \---gtk-fortran
|   |          [gtk-fortran sources, etc.] 
|   |           
|   +---gfortran_5C85107C14DBE362
|   |   |   [gtk-fortran ".mod" files]
|   |   \---fsplits
|   |          [project & gtk-fortran ".o" and ".log" files]
|   |           
|   +---gfortran_B5ACFFEC01CB0F6A
|   |   \---app
|   |           fsplits.exe
|   |           fsplits.exe.log
|   |           
|   \---gfortran_E9E562C8AB03E1B8
|       \---fsplits
|               libfsplits.a
|               libfsplits.a.log
|               
+---src
|       handlers.f90
|       
\---test
        check.f90

Side question, what command do you use to display the file-tree?

Perhaps not the elegant solution you’re looking for, but, would it make sense that you install gtk-fortran somewhere and then point to the installation directory? Something like

fpm install --prefix=/to/gtk/fortran 

will install all .mod files in /to/gtk/fortran/include

(you could customize include with --includedir "custom_mod_dir").

That would create a stable folder at least for the dependencies in your project.
PS I’m no VS code user so I may be suggesting something silly.

I assume it is the command

tree

At least in Ubuntu it can be easily installed

If not in pre-release version please install it, set the logging level to Debug, and post the OUTPUT of Modern Fortran. That will help clarify what’s going on under the hood.

1 Like

Sounds good. I will try that and report back.

Hi @gnikit, I’ve done the following:

  1. Updated fortls to the latest version on PyPI (3.1.2)
  2. Toggled to the pre-release version of the Modern Fortran extension (v3.4.2024090901)
  3. Added a .fortls.json to enable “debug_log”: true

I’ve attached both the fortls log and the VS Code extension log generated from a fresh session. I opened VS Code in the project workspace, gave the extension some time to load, saved “main.f90” to let the linter run, and hovered over a “use gtk” statement to get the problem tooltip.

2-Modern Fortran.txt (14.0 KB)
fortls_debug.txt (9.7 KB)

If push comes to shove, I can continue just putting all the .mod files in the top-level directory while developing.

From the vscode logs I can tell that the linter paths are not properly resolved, only the manually specified modOutpout directory is present. On Windows, I think the separator is \\ so your settings should look something like this:

{
    "fortran.linter.includePaths": [
        "${workspaceFolder}\\lint\\**",
        "${workspaceFolder}\\build\\**",
    ],
   "fortran.fortls.suffixes": [".in"]
}

You will know that Modern Fortran has correctly expanded your linter includes when the following OUTPUT in the logs looks like this (this is on Linux)

[DEBUG - 07:58:29] [lint] glob paths:
[
  "${workspaceFolder}/build/vscode/**"
]
[DEBUG - 07:58:29] [lint] resolved paths:
[
  "/home/gn/Code/Fortran/fortran-lang/fpm/build/vscode",
  "/home/gn/Code/Fortran/fortran-lang/fpm/build/vscode/lib",
  "/home/gn/Code/Fortran/fortran-lang/fpm/build/vscode/include",
  "/home/gn/Code/Fortran/fortran-lang/fpm/build/vscode/bin"
]

Here is also a link for tasks.json and launch.json for integration with fpm. I think it only needs some minor edits to work on Windows.

This is what I use for my projects.

{
  "fortran.linter.compiler": "gfortran",
  "fortran.linter.includePaths": [
    "${workspaceFolder}/build/**"
  ],
  "fortran.fortls.directories": [
    "${workspaceFolder}/build/**"
  ],
  "fortran.formatting.formatter": "findent",
  "fortran.formatting.findentArgs": [
    "-i2"
  ],
  "todo-tree.regex.regex": "(//|#|<!--|;|/\\*|!|^|^[ \\t]*(-|\\d+.))\\s*($TAGS)",
  // We don't want to see the mod files or the build directory because it clutters everything up.
  "files.exclude": {
    "**/.git": true,
    "**/**.mod": true,
    "build/": true,
    "scripts/": true
  }
}

Great, indeed the escaped forward slash is what was needed. I had also tried “${/}” as a path separator, but somehow that didn’t work…