I am a newcomer to fpm and I am trying to build a library project with different options. I am the main developer of the library CrysFML (https://code.ill.fr/scientific-software/crysfml). We use Cmake for building the library with ifort or gfortran for the three platforms Windows, Linux and MacOS with two options: (1) console and (2) using an external library for making GUIs.
I wanted to use something simpler than Cmake to build the library and I came aware of fpm.
I have found that for building console programs fpm is very simple and efficient. However, I had to use a script, invoking fpm with response files and other scripts for renaming files, for handling different compilers and different source files containing the same module name but different content (by automatically renaming before invoking fpm). This is not a problem, but something that I have not found, clearly explained in the documentation, is how to use an external library that is installed locally (*.mod files and library) outside the CrysFML directory. After trying several options using [dependencies] in the fpm.toml file, I never succeeded in building the GUI version of the library CrysFML that uses the commercial Winteracter library.
In the Windows (Linux or MacOS is the same) platform, the (simplified) structure of the two directories is the following
CrysFML
├── Program_Examples
│ └── Subdirectories with different programs
├── rsp
│ └── Directory with different response files
├── fpm.toml
├── make_CrysFML_fpm.bat
├── src
│ └── All module source files
Winter
├── lib.i64 (ifort 64 bits)
│ └── Directory containing *.mod, winter.lib and some *.obj files
├── src
│ └── All interface modules source files
My questions are the following:
What have I to write in the fpm.toml file to make fpm finding the pre-compiled *.mod files of the Winteracter library? The winteracter.mod (within lib.i64) is used by one module of CrysFML when the script for building it is invoked with the appropriate response file.
I have tried to put in the compiler flags the include item “/I…\winter\lib.64” but fpm is always trying to find the source file of the module winteracter which is in “…/…/winter/src”. Is fpm unable to work with pre-compiled objects or mod files?
Thank you in advance for providing some tips.
========================== Content of some files ====================
File fpm.toml
[build]
auto-executables = false
auto-tests = false
auto-examples = false
[install]
library = true
[library]
source-dir = "Src"
include-dir = "Src"
Response file ifort_debug_win.rsp
options install --prefix ifort_debug_win
options --profile debug
options --compiler ifort
options --flags "/I..\..\wint\lib.i64"
Script file: make_CrysFML_fpm.bat
@echo off
rem .
rem Attempt to create a unified build method for CrysFML using fmp
rem .
echo ---- Construction of the CrysFML library for 64 bits using gfortran, ifort or ifx (oneAPI) ----
echo ---- The building procedure installs also some executable programs of the Program_Examples subdirectory
echo Default: ifort compiler in release mode. Equivalent to the first example below
echo Examples of using the script:
echo make_CrysFML_fpm ifort
echo make_CrysFML_fpm ifort debug
echo make_CrysFML_fpm gfortran
echo make_CrysFML_fpm gfortran debug
echo make_CrysFML_fpm ifx
echo make_CrysFML_fpm ifx debug
echo For using the Winteracter library add the word "win" as the last argument (without quotes)
echo ----
(set _DEBUG=N)
(set _COMP=ifort)
(set _WINT=N)
rem > Arguments ----
:LOOP
if [%1]==[debug] (set _DEBUG=Y)
if [%1]==[ifort] (set _COMP=ifort)
if [%1]==[ifx] (set _COMP=ifx)
if [%1]==[gfortran] (set _COMP=gfortran)
if [%1]==[win] (set _WINT=win)
shift
if not [%1]==[] goto LOOP
rem .
rem First change the extensions of files that are optionally used in fpm to "xxx" by
rem invoking the tochange.bat script in the Src directory.
cd .\Src
if [%_WINT%]==[win] (
call tochange xxx win
) else (
call tochange xxx
)
)
cd ..
if [%_COMP%]==[ifort] (
cd .\Src
ren CFML_GlobalDeps_Windows_Intel.xxx CFML_GlobalDeps.f90
cd ..
if [%_WINT%]==[win] (
if [%_DEBUG%]==[Y] (
fpm @./rsp/ifort_debug_win
) else (
fpm @./rsp/ifort_release_win
)
) else (
if [%_DEBUG%]==[Y] (
fpm @./rsp/ifort_debug
) else (
fpm @./rsp/ifort_release
)
)
cd .\Src
ren CFML_GlobalDeps.f90 CFML_GlobalDeps_Windows_Intel.xxx
cd ..
)
if [%_COMP%]==[ifx] (
cd .\Src
ren CFML_GlobalDeps_Windows_Intel.xxx CFML_GlobalDeps.f90
cd ..
if [%_DEBUG%]==[Y] (
fpm @./rsp/ifx_debug
) else (
fpm @./rsp/ifx_release
)
cd .\Src
ren CFML_GlobalDeps.f90 CFML_GlobalDeps_Windows_Intel.xxx
cd ..
)
if [%_COMP%]==[gfortran] (
cd .\Src
ren CFML_GlobalDeps_Windows.xxx CFML_GlobalDeps.f90
cd ..
if [%_DEBUG%]==[Y] (
fpm @./rsp/gf_debug
) else (
fpm @./rsp/gf_release
)
cd .\Src
ren CFML_GlobalDeps.f90 CFML_GlobalDeps_Windows.xxx
cd ..
)
rem .
rem Undo the changes of extensions to be compatilbe with Cmake
rem .
cd .\Src
if [%_WINT%]==[win] (
call tochange f90 win
) else (
call tochange f90
)
)
cd ..
Example or running the script with the option win
c:\ILL_Git\CrysFML>make_CrysFML_fpm ifort debug win
---- Construction of the CrysFML library for 64 bits using gfortran, ifort or ifx (oneAPI) ----
---- The building procedure installs also some executable programs of the Program_Examples subdirectory
Default: ifort compiler in release mode. Equivalent to the first example below
Examples of using the script:
make_CrysFML_fpm ifort
make_CrysFML_fpm ifort debug
make_CrysFML_fpm gfortran
make_CrysFML_fpm gfortran debug
make_CrysFML_fpm ifx
make_CrysFML_fpm ifx debug
For using the Winteracter library add the word "win" as the last argument (without quotes)
----
---- Changing the extension of some *.f90 files to *.xxx to maintain compatibility with FPM
<ERROR>Unable to find source for module dependency: "winteracter" used by ".\Src\CFML_IO_Messages.f90"
STOP 1
---- Changing the extension of *.xxx files to *.f90 to maintain compatibility with CMake