Trouble setting up new project with fpm-gmsh

Hey all!

I’m recently started to learn fortran and I’m still learning, so please bear with me. I want use the gmsh Fortran API and since I really like the user friendliness of fpm, I’m trying to set up my project with using gmsh-fpm. Sadly I run into various problem, some of which I think I found a solution. Here is a rundown of what I tried.
First I start a new project.

fpm new my_gmsh_project

next I added the dependency to the fpm.toml just like the github readme tells me

[dependencies]
gmsh-fpm = { git="https://github.com/gnikit/gmsh-fpm.git" }

I also downloaded the newest version of the gmsh sdk from here
Then I try to build the project the first time using

fpm build --link-flag "-LC:\Thomas\Programme\gmsh-4.11.1-sdk\lib"

But I get an error, while fpm is pulling the gmsh-fpm repository:

<ERROR> *cmd_build* Model error: Dependency name 'gmsh' found, but expected 'gmsh-fpm' instead
STOP 1

Kinda weird, but let’s try to change ‘gmsh-fpm’ to ‘gmsh’ in the .toml file and try again. This time fpm was succesful. In build/depedencies I can see the downloaded repository ‘gmsh’ (also the duplicate gmsh-fpm from the first try compiling. I deleted this one).

Seems like I’m almost done, however when I try to actually use the API, an error occures and I can’t figure out the reason. Here is my small program

program main
   use, intrinsic :: iso_c_binding
   use gmsh
   implicit none

   type(gmsh_t) :: gmsh

   ! Before using any functions in the Python API, Gmsh must be initialized:
   call gmsh%initialize()

   ! This should be called when you are done using the Gmsh Python API:
   call gmsh%finalize()
end program main

Just start and close gmsh. Nothing to fancy. And here is the error I get:

PS C:\Thomas\FortranTest\my_gmsh_project> fpm run --link-flag "-LC:\Thomas\Programme\gmsh-4.11.1-sdk\lib"
gmsh.f90                               done.
libmy_gmsh_project.a                   done.
main.f90                               done.
my_gmsh_project.exe                    failed.
[100%] Compiling...
C:/Program Files/gcc/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\gfortran_50F62D7499E64B65\my_gmsh_project\libmy_gmsh_project.a(build_dependencies_gmsh_src_gmsh.f90.o): in function `__gmsh_MOD_gmshmodelmeshgetvisibility':
C:\Thomas\FortranTest\my_gmsh_project/build/dependencies/gmsh/src/gmsh.f90:7107: undefined reference to `gmshModelMeshGetVisibility'
C:/Program Files/gcc/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\gfortran_50F62D7499E64B65\my_gmsh_project\libmy_gmsh_project.a(build_dependencies_gmsh_src_gmsh.f90.o): in function `__gmsh_MOD_gmshmodelmeshcomputerenumbering':
C:\Thomas\FortranTest\my_gmsh_project/build/dependencies/gmsh/src/gmsh.f90:6588: undefined reference to `gmshModelMeshComputeRenumbering'
C:/Program Files/gcc/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: build\gfortran_50F62D7499E64B65\my_gmsh_project\libmy_gmsh_project.a(build_dependencies_gmsh_src_gmsh.f90.o): in function `__gmsh_MOD_gmshmodelgetentitiesforphysicalname':
C:\Thomas\FortranTest\my_gmsh_project/build/dependencies/gmsh/src/gmsh.f90:1550: undefined reference to `gmshModelGetEntitiesForPhysicalName'
collect2.exe: error: ld returned 1 exit status
<ERROR> Compilation failed for object " my_gmsh_project.exe "
<ERROR> stopping due to failed compilation
STOP 1

And with this error I’m stumped. It seems really weird, because I can find these procedures in the gmsh.f90 file of the dependecy, but somehow they are gone, when building? Or does the error occure, because fpm can’t find these references while linking to the gmsh sdk?

If you need additional information, let me know.

2 Likes

Welcome to the forum!

Unfortunately, I cannot help you with this problem, but @gnikit, the author of gmsh-fpm is a regular here.

2 Likes

Welcome to Fortran-lang @Tavi007!

You almost got the config right:

In your fpm.toml use (4.11.1 is the latest stable version)

gmsh = { git="https://github.com/gnikit/gmsh-fpm.git", tag = "4.11.1" }

When you run the application via the terminal use this (adjusted for the path to your SDK)

LD_LIBRARY_PATH=./gmsh-4.11.1-Linux64-sdk/lib/ fpm run  --link-flag "-L ./gmsh-4.11.1-Linux6
4-sdk/lib/"

The usual tricks with LD_LIBRARY_PATH and LIBRARY_PATH here work e.g.

export LD_LIBRARY_PATH=`pwd`/gmsh-4.11.1-Linux64-sdk/lib:$LD_LIBRARY_PATH
fpm run --link-flag "-L ./gmsh-4.11.1-Linux64-sdk/lib"

or

For gfortran you can remove explicitly having to link to libgmsh by adding
the lib directory into your LIBRARY_PATH environment variable for gfortran
to search before compiling e,g.

export LIBRARY_PATH=/path/to/gmsh-sdk/lib:$LIBRARY_PATH
fpm run

Hey @gnikit .Thank you very much.
I got it finally working, though with one small hiccup. The Programm could be build successfully, however running the programm result in an error: the gmsh-4.11.dll was not found. Copying the .dll from the sdk/lib folder into my project fixed the issue, but left me wondering, if it is possible for fpm to do that automatically if needed.

But for now I’m happy with the solution I have.

Hello, again. The solution has been working fine, however since my last post I’ve been working on other projects, which are compiled with ifx instead of gfortran. Now I would like to change the compiler of my meshing tool too, but I run into an error.

The command I run:

fpm run --compiler ifx --profile debug --link-flag "-L {path to ./gmsh-4.11.1-Linux64-sdk/lib}"

The error I get:

LINK : fatal error LNK1104: File "gmsh.lib" can not be opened.

I hope @gnikit can help me out once again :slight_smile:

There are a couple of ways you can go about this.

I suspect the most robust way is building Gmsh with the Intel compiler suite. They have a instructions on how to do so on their Wiki over at GitLab.

The second option I can think off is, because Gmsh is written in C++, compiler ABIs are standardised. So you could get the GCC-compiled Gmsh library, create an Intel wrapper library around it using the Intel C++ compiler and then finally point fpm using your Intel Fortran compiler to the Intel wrapper library. Gmsh ships with a wrapper library header file for this exact purpose, although I don’t remember exactly how one would use it.

Just make sure when generating the wrapper library to use the same version of std and ABI.