aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Ehlert <28669218+awvwgk@users.noreply.github.com>2021-03-31 16:13:58 +0200
committerGitHub <noreply@github.com>2021-03-31 16:13:58 +0200
commitd9dc9f2ae5f196c15a7d35cddabc805c40ff86ce (patch)
tree6f61952c630b023edec391daae2747063703d489
parent5422ec57f4081bf2225f5dde5cc07999bf8010f9 (diff)
downloadfpm-d9dc9f2ae5f196c15a7d35cddabc805c40ff86ce.tar.gz
fpm-d9dc9f2ae5f196c15a7d35cddabc805c40ff86ce.zip
Phase out Haskell fpm (#420)
- remove bootstrap directory from repository - remove stack-build from CI workflow - move Fortran fpm to project root - adjust install script and bootstrap instructions
-rw-r--r--.github/workflows/CI.yml143
-rw-r--r--.gitignore4
-rw-r--r--README.md48
-rw-r--r--app/main.f90 (renamed from fpm/app/main.f90)0
-rw-r--r--bootstrap/Setup.hs2
-rw-r--r--bootstrap/app/Main.hs8
-rw-r--r--bootstrap/package.yaml72
-rw-r--r--bootstrap/src/Build.hs239
-rw-r--r--bootstrap/src/BuildModel.hs411
-rw-r--r--bootstrap/src/Fpm.hs1227
-rw-r--r--bootstrap/stack.yaml74
-rw-r--r--bootstrap/stack.yaml.lock43
-rw-r--r--bootstrap/test/Spec.hs103
l---------bootstrap/test/example_packages1
-rw-r--r--bootstrap/unit_test/ModuleSourceConstructionTest.hs83
-rw-r--r--bootstrap/unit_test/ModuleToCompileInfoTest.hs73
-rw-r--r--bootstrap/unit_test/ProgramSourceConstructionTest.hs69
-rw-r--r--bootstrap/unit_test/ProgramToCompileInfoTest.hs71
-rw-r--r--bootstrap/unit_test/SubmoduleSourceConstructionTest.hs79
-rw-r--r--bootstrap/unit_test/SubmoduleToCompileInfoTest.hs78
-rw-r--r--bootstrap/unit_test/Trimmer.hs1
-rw-r--r--docs.md6
-rw-r--r--fpm.toml (renamed from fpm/fpm.toml)0
-rw-r--r--fpm/.gitignore1
-rw-r--r--fpm/README.md4
-rwxr-xr-xinstall.sh100
-rw-r--r--manifest-reference.md21
-rw-r--r--src/fpm.f90 (renamed from fpm/src/fpm.f90)0
-rw-r--r--src/fpm/cmd/install.f90 (renamed from fpm/src/fpm/cmd/install.f90)0
-rw-r--r--src/fpm/cmd/new.f90 (renamed from fpm/src/fpm/cmd/new.f90)0
-rw-r--r--src/fpm/cmd/update.f90 (renamed from fpm/src/fpm/cmd/update.f90)0
-rw-r--r--src/fpm/dependency.f90 (renamed from fpm/src/fpm/dependency.f90)0
-rw-r--r--src/fpm/error.f90 (renamed from fpm/src/fpm/error.f90)0
-rw-r--r--src/fpm/git.f90 (renamed from fpm/src/fpm/git.f90)0
-rw-r--r--src/fpm/installer.f90 (renamed from fpm/src/fpm/installer.f90)0
-rw-r--r--src/fpm/manifest.f90 (renamed from fpm/src/fpm/manifest.f90)0
-rw-r--r--src/fpm/manifest/build.f90 (renamed from fpm/src/fpm/manifest/build.f90)0
-rw-r--r--src/fpm/manifest/dependency.f90 (renamed from fpm/src/fpm/manifest/dependency.f90)0
-rw-r--r--src/fpm/manifest/example.f90 (renamed from fpm/src/fpm/manifest/example.f90)0
-rw-r--r--src/fpm/manifest/executable.f90 (renamed from fpm/src/fpm/manifest/executable.f90)0
-rw-r--r--src/fpm/manifest/install.f90 (renamed from fpm/src/fpm/manifest/install.f90)0
-rw-r--r--src/fpm/manifest/library.f90 (renamed from fpm/src/fpm/manifest/library.f90)0
-rw-r--r--src/fpm/manifest/package.f90 (renamed from fpm/src/fpm/manifest/package.f90)0
-rw-r--r--src/fpm/manifest/test.f90 (renamed from fpm/src/fpm/manifest/test.f90)0
-rw-r--r--src/fpm/toml.f90 (renamed from fpm/src/fpm/toml.f90)0
-rw-r--r--src/fpm/versioning.f90 (renamed from fpm/src/fpm/versioning.f90)0
-rw-r--r--src/fpm_backend.f90 (renamed from fpm/src/fpm_backend.f90)0
-rw-r--r--src/fpm_command_line.f90 (renamed from fpm/src/fpm_command_line.f90)0
-rw-r--r--src/fpm_compiler.f90 (renamed from fpm/src/fpm_compiler.f90)0
-rw-r--r--src/fpm_environment.f90 (renamed from fpm/src/fpm_environment.f90)0
-rw-r--r--src/fpm_filesystem.f90 (renamed from fpm/src/fpm_filesystem.f90)0
-rw-r--r--src/fpm_model.f90 (renamed from fpm/src/fpm_model.f90)0
-rw-r--r--src/fpm_source_parsing.f90 (renamed from fpm/src/fpm_source_parsing.f90)0
-rw-r--r--src/fpm_sources.f90 (renamed from fpm/src/fpm_sources.f90)0
-rw-r--r--src/fpm_strings.f90 (renamed from fpm/src/fpm_strings.f90)0
-rw-r--r--src/fpm_targets.f90 (renamed from fpm/src/fpm_targets.f90)0
-rw-r--r--test/cli_test/cli_test.f90 (renamed from fpm/test/cli_test/cli_test.f90)0
-rw-r--r--test/fpm_test/main.f90 (renamed from fpm/test/fpm_test/main.f90)0
-rw-r--r--test/fpm_test/test_backend.f90 (renamed from fpm/test/fpm_test/test_backend.f90)0
-rw-r--r--test/fpm_test/test_filesystem.f90 (renamed from fpm/test/fpm_test/test_filesystem.f90)0
-rw-r--r--test/fpm_test/test_installer.f90 (renamed from fpm/test/fpm_test/test_installer.f90)0
-rw-r--r--test/fpm_test/test_manifest.f90 (renamed from fpm/test/fpm_test/test_manifest.f90)0
-rw-r--r--test/fpm_test/test_module_dependencies.f90 (renamed from fpm/test/fpm_test/test_module_dependencies.f90)0
-rw-r--r--test/fpm_test/test_package_dependencies.f90 (renamed from fpm/test/fpm_test/test_package_dependencies.f90)0
-rw-r--r--test/fpm_test/test_source_parsing.f90 (renamed from fpm/test/fpm_test/test_source_parsing.f90)0
-rw-r--r--test/fpm_test/test_toml.f90 (renamed from fpm/test/fpm_test/test_toml.f90)0
-rw-r--r--test/fpm_test/test_versioning.f90 (renamed from fpm/test/fpm_test/test_versioning.f90)0
-rw-r--r--test/fpm_test/testsuite.f90 (renamed from fpm/test/fpm_test/testsuite.f90)0
-rw-r--r--test/help_test/help_test.f90 (renamed from fpm/test/help_test/help_test.f90)0
-rw-r--r--test/new_test/new_test.f90 (renamed from fpm/test/new_test/new_test.f90)0
70 files changed, 39 insertions, 2922 deletions
diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml
index 9fc7918..8aabcf5 100644
--- a/.github/workflows/CI.yml
+++ b/.github/workflows/CI.yml
@@ -13,138 +13,8 @@ env:
HOMEBREW_NO_BOTTLE_SOURCE_FALLBACK: "ON"
HOMEBREW_NO_GITHUB_API: "ON"
HOMEBREW_NO_INSTALL_CLEANUP: "ON"
- RUST_BACKTRACE: "full" # Make Rust print full backtrace on error
jobs:
- stack-build:
- runs-on: ${{ matrix.os }}
- strategy:
- fail-fast: false
- matrix:
- os: [ubuntu-latest, macos-latest, windows-latest]
- gcc_v: [9] # Version of GFortran we want to use.
- include:
- - os: ubuntu-latest
- STACK_CACHE: "/home/runner/.stack/"
- STACK_CACHE_VERSION: ""
- TEST_SCRIPT: ci/run_tests.sh
- GET_VERSION_CMD: echo ${{ github.ref }} | cut -dv -f2
- CHECK_VERSION_CMD: grep $(cat fpm_version)
- RELEASE_CMD: "cp -- fpm-$(cat fpm_version)-linux-x86_64"
- BOOTSTRAP_RELEASE_CMD: cp /home/runner/.local/bin/fpm fpm-haskell-$(cat fpm_version)-linux-x86_64
- HASH_CMD: ls fpm-*|xargs -i{} sh -c 'sha256sum $1 > $1.sha256' -- {}
- RELEASE_FLAGS: --flag --static --flag -g --flag -fbacktrace --flag -O3
-
- - os: macos-latest
- STACK_CACHE: |
- /Users/runner/.stack/snapshots
- /Users/runner/.stack/setup-exe-src
- STACK_CACHE_VERSION: "v2"
- TEST_SCRIPT: ci/run_tests.sh
- GET_VERSION_CMD: echo ${{ github.ref }} | cut -dv -f2
- CHECK_VERSION_CMD: grep $(cat fpm_version)
- RELEASE_CMD: "cp -- fpm-$(cat fpm_version)-macos-x86_64"
- BOOTSTRAP_RELEASE_CMD: cp /Users/runner/.local/bin/fpm fpm-haskell-$(cat fpm_version)-macos-x86_64
- HASH_CMD: ls fpm-*|xargs -I{} sh -c 'shasum -a 256 $1 > $1.sha256' -- {}
- RELEASE_FLAGS: --flag -g --flag -fbacktrace --flag -O3
-
- - os: windows-latest
- STACK_CACHE: |
- C:\Users\runneradmin\AppData\Roaming\stack
- C:\Users\runneradmin\AppData\Local\Programs\stack
- STACK_CACHE_VERSION: "v2"
- TEST_SCRIPT: ci\run_tests.bat
- GET_VERSION_CMD: ("${{ github.ref }}" -Split "v")[1]
- CHECK_VERSION_CMD: Select-String -Pattern Version | Where-Object { if ($_ -like -join("*",(Get-Content fpm_version),"*")) {echo $_} else {Throw} }
- RELEASE_CMD: copy -- (-join("fpm-",(Get-Content fpm_version),"-windows-x86_64.exe"))
- BOOTSTRAP_RELEASE_CMD: copy C:\Users\runneradmin\AppData\Roaming\local\bin\fpm.exe (-join("fpm-haskell-",(Get-Content fpm_version),"-windows-x86_64.exe"))
- HASH_CMD: Get-ChildItem -File -Filter "fpm-*" | Foreach-Object {echo (Get-FileHash -Algorithm SHA256 $PSItem | Select-Object hash | Format-Table -HideTableHeaders | Out-String) > (-join($PSItem,".sha256"))}
- RELEASE_FLAGS: --flag --static --flag -g --flag -fbacktrace --flag -O3
-
- env:
- FC: gfortran
- GCC_V: ${{ matrix.gcc_v }}
-
- steps:
- - name: Checkout code
- uses: actions/checkout@v1
-
- - name: Install GFortran macOS
- if: contains(matrix.os, 'macos')
- run: |
- ln -s /usr/local/bin/gfortran-${GCC_V} /usr/local/bin/gfortran
- which gfortran-${GCC_V}
- which gfortran
-
- - name: Install GFortran Linux
- if: contains(matrix.os, 'ubuntu')
- run: |
- sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-${GCC_V} 100 \
- --slave /usr/bin/gfortran gfortran /usr/bin/gfortran-${GCC_V} \
- --slave /usr/bingcov gcov /usr/bin/gcov-${GCC_V}
-
- - name: Get Time
- id: time
- uses: nanzm/get-time-action@v1.0
- with:
- format: 'YYYY-MM'
-
- - name: Setup github actions cache
- id: cache
- uses: actions/cache@v2
- with:
- path: ${{matrix.STACK_CACHE}}
- key: ${{ runner.os }}-${{ steps.time.outputs.time }}${{matrix.STACK_CACHE_VERSION}}
-
- - name: Build Haskell fpm
- run: |
- stack build
- stack install
- working-directory: bootstrap
-
- - name: put fpm to PATH (macOS)
- if: contains(matrix.os, 'macos')
- run: |
- cp /Users/runner/.local/bin/fpm /usr/local/bin
-
- - name: put fpm to PATH (Windows)
- if: contains(matrix.os, 'windows')
- run: |
- copy "C:\Users\runneradmin\AppData\Roaming\local\bin\fpm.exe" "C:\Program Files\Git\usr\bin"
-
- - name: put fpm to PATH (Linux)
- if: contains(matrix.os, 'ubuntu')
- run: |
- sudo cp /home/runner/.local/bin/fpm /usr/local/bin
-
- - name: Run tests on Haskell fpm
- run: |
- stack test
- working-directory: bootstrap
-
- # ----- Upload binaries if creating a release -----
- - name: Check that fpm --version matches release tag
- if: github.event_name == 'release'
- run: |
- ${{ matrix.GET_VERSION_CMD }} > fpm_version
- working-directory: fpm
-
- - name: Stage release files for upload
- if: github.event_name == 'release'
- run: |
- ${{ matrix.BOOTSTRAP_RELEASE_CMD }}
- ${{ matrix.HASH_CMD }}
- working-directory: fpm
-
- - name: Upload assets
- if: github.event_name == 'release'
- uses: svenstaro/upload-release-action@v2
- with:
- repo_token: ${{ secrets.GITHUB_TOKEN }}
- file: fpm/fpm-*
- file_glob: true
- tag: ${{ github.ref }}
- overwrite: true
build:
runs-on: ${{ matrix.os }}
@@ -208,7 +78,6 @@ jobs:
shell: bash
run: |
${{ env.BOOTSTRAP }} build
- working-directory: fpm
- name: Run Fortran fpm (bootstrap)
shell: bash
@@ -216,19 +85,16 @@ jobs:
${{ env.BOOTSTRAP }} run
${{ env.BOOTSTRAP }} run -- --version
${{ env.BOOTSTRAP }} run -- --help
- working-directory: fpm
- name: Test Fortran fpm (bootstrap)
shell: bash
run: |
${{ env.BOOTSTRAP }} test
- working-directory: fpm
- name: Install Fortran fpm (bootstrap)
shell: bash
run: |
${{ env.BOOTSTRAP }} install
- working-directory: fpm
# Phase 2: Bootstrap fpm with itself
- name: Replace bootstrapping version
@@ -237,7 +103,6 @@ jobs:
${{ env.BOOTSTRAP }} run --runner cp -- fpm-debug${{ matrix.exe }}
rm -v ${{ env.BOOTSTRAP }}
echo "FPM=$PWD/fpm-debug" | cat >> $GITHUB_ENV
- working-directory: fpm
- name: Get version (normal)
if: github.event_name != 'release'
@@ -266,7 +131,6 @@ jobs:
shell: bash
run: |
${{ env.FPM }} build ${{ matrix.release-flags }}
- working-directory: fpm
- name: Run Fortran fpm
shell: bash
@@ -274,19 +138,16 @@ jobs:
${{ env.FPM }} run ${{ matrix.release-flags }}
${{ env.FPM }} run ${{ matrix.release-flags }} -- --version
${{ env.FPM }} run ${{ matrix.release-flags }} -- --help
- working-directory: fpm
- name: Test Fortran fpm
shell: bash
run: |
${{ env.FPM }} test ${{ matrix.release-flags }}
- working-directory: fpm
- name: Install Fortran fpm
shell: bash
run: |
${{ env.FPM }} install ${{ matrix.release-flags }}
- working-directory: fpm
- name: Package release version
shell: bash
@@ -294,7 +155,6 @@ jobs:
${{ env.FPM }} run ${{ matrix.release-flags }} --runner cp -- ${{ env.EXE }}
rm -v ${{ env.FPM }}
echo "FPM_RELEASE=$PWD/${{ env.EXE }}" | cat >> $GITHUB_ENV
- working-directory: fpm
env:
EXE: fpm-${{ env.VERSION }}-${{ matrix.os-arch }}${{ matrix.exe }}
@@ -308,14 +168,13 @@ jobs:
shell: bash
run: |
${{ matrix.sha256sum }} ${{ env.FPM_RELEASE }} > ${{ env.FPM_RELEASE }}.sha256
- working-directory: fpm
- name: Upload assets
if: github.event_name == 'release'
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
- file: fpm/fpm-*
+ file: fpm-*
file_glob: true
tag: ${{ github.ref }}
overwrite: true
diff --git a/.gitignore b/.gitignore
index fe86e64..a007fea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1 @@
-.stack-work/
-fpm.cabal
-*~
+build/*
diff --git a/README.md b/README.md
index 04ab6ad..d4e9002 100644
--- a/README.md
+++ b/README.md
@@ -18,7 +18,10 @@ matures and we enter production, we will aim to stay backwards compatible.
Please follow the [issues](https://github.com/fortran-lang/fpm/issues) to
contribute and/or stay up to date with the development.
Before opening a bug report or a feature suggestion, please read our
-[Contributor Guide](CONTRIBUTING.md). You can also discuss your ideas and queries with the community in [fpm discussions](https://github.com/fortran-lang/fpm/discussions), or more broadly on [Fortran-Lang Discourse](https://fortran-lang.discourse.group/)
+[Contributor Guide](CONTRIBUTING.md). You can also discuss your ideas and
+queries with the community in
+[fpm discussions](https://github.com/fortran-lang/fpm/discussions),
+or more broadly on [Fortran-Lang Discourse](https://fortran-lang.discourse.group/).
Fortran Package Manager is not to be confused with
[Jordan Sissel's fpm](https://github.com/jordansissel/fpm), a more general,
@@ -71,8 +74,8 @@ with the following contents and initialized as a git repository.
* `README.md` – with your project’s name
* `.gitignore`
* `src/project_name.f90` – with a simple hello world subroutine
-* `app/main.f90` (if `--with-executable` flag used) – a program that calls the subroutine
-* `test/main.f90` (if `--with-test` flag used) – an empty test program
+* `app/main.f90` (if `--app` flag used) – a program that calls the subroutine
+* `test/main.f90` (if `--test` flag used) – an empty test program
### Building your Fortran project with fpm
@@ -81,6 +84,7 @@ with the following contents and initialized as a git repository.
* `fpm build` – build your library, executables and tests
* `fpm run` – run executables
* `fpm test` – run tests
+* `fpm install` - installs the executables locally
The command `fpm run` can optionally accept the name of the specific executable
to run, as can `fpm test`; like `fpm run specific_executable`. Command line
@@ -94,36 +98,24 @@ the [manifest reference](manifest-reference.md).
### Bootstrapping instructions
This guide explains the process of building *fpm* on a platform for the first time.
-If your platform and architecture are already supported, download the binary from the [release page](https://github.com/fortran-lang/fpm/releases) instead.
+To build *fpm* without a prior *fpm* version a single source file version is available
+at each release.
-#### Download this repository
+To build manually using the single source distribution use
-```bash
-$ git clone https://github.com/fortran-lang/fpm
-$ cd fpm/
```
-
-#### Build a bootstrap version of fpm
-
-You can use the install script to bootstrap and install *fpm*:
-
-```bash
-$ ./install.sh
+mkdir _tmp
+curl -LJ https://github.com/fortran-lang/fpm/releases/download/v0.2.0/fpm-0.2.0.f90 > _tmp/fpm.f90
+gfortran -J _tmp _tmp/fpm.f90 -o _tmp/fpm
+_tmp/fpm install --flag "-g -fbacktrace -O3"
+rm -r _tmp
```
-By default, the above command installs `fpm` to `${HOME}/.local/bin/`.
-To specify an alternative destination use the `--prefix=` flag, for example:
+To automatically bootstrap using this appoach run the install script
-```bash
-$ ./install.sh --prefix=/usr/local
```
-
-which will install *fpm* to `/usr/local/bin`.
-
-To test that everything is working as expected you can now build *fpm*
-with itself and run the tests with:
-
-```bash
-$ cd fpm
-$ fpm test
+./install.sh
```
+
+You can set your Fortran compiler and the compiler flags with the ``FC`` and ``FFLAGS``
+environment variables.
diff --git a/fpm/app/main.f90 b/app/main.f90
index 7476df6..7476df6 100644
--- a/fpm/app/main.f90
+++ b/app/main.f90
diff --git a/bootstrap/Setup.hs b/bootstrap/Setup.hs
deleted file mode 100644
index 9a994af..0000000
--- a/bootstrap/Setup.hs
+++ /dev/null
@@ -1,2 +0,0 @@
-import Distribution.Simple
-main = defaultMain
diff --git a/bootstrap/app/Main.hs b/bootstrap/app/Main.hs
deleted file mode 100644
index 4897901..0000000
--- a/bootstrap/app/Main.hs
+++ /dev/null
@@ -1,8 +0,0 @@
-module Main where
-
-import Fpm ( getArguments
- , start
- )
-
-main :: IO ()
-main = getArguments >>= start
diff --git a/bootstrap/package.yaml b/bootstrap/package.yaml
deleted file mode 100644
index 1f5d0fd..0000000
--- a/bootstrap/package.yaml
+++ /dev/null
@@ -1,72 +0,0 @@
-name: fpm
-version: 0.1.0.0
-github: "githubuser/fpm"
-license: BSD3
-author: "Author name here"
-maintainer: "example@example.com"
-copyright: "2020 Author name here"
-
-extra-source-files:
-- ../README.md
-- ../ChangeLog.md
-
-# Metadata used when publishing your package
-# synopsis: Short description of your package
-# category: Web
-
-# To avoid duplicated efforts in documentation and dealing with the
-# complications of embedding Haddock markup inside cabal files, it is
-# common to point users to the README.md file.
-description: Please see the README on GitHub at <https://github.com/githubuser/fpm#readme>
-
-dependencies:
-- base >= 4.7 && < 5
-- containers
-- directory
-- extra
-- filepath
-- hashable
-- MissingH
-- optparse-applicative
-- process
-- shake
-- split
-- text
-- tomland >= 1.0
-
-
-library:
- source-dirs: src
-
-executables:
- fpm:
- main: Main.hs
- source-dirs: app
- ghc-options:
- - -threaded
- - -rtsopts
- - -with-rtsopts=-N
- dependencies:
- - fpm
-
-tests:
- fpm-test:
- main: Spec.hs
- source-dirs: test
- ghc-options:
- - -threaded
- - -rtsopts
- - -with-rtsopts=-N
- dependencies:
- - fpm
- fpm-unittest:
- main: Trimmer.hs
- source-dirs: unit_test
- ghc-options:
- - -threaded
- - -rtsopts
- - -with-rtsopts=-N
- dependencies:
- - fpm
- - hedge
- - hedge-trimmer
diff --git a/bootstrap/src/Build.hs b/bootstrap/src/Build.hs
deleted file mode 100644
index 724a1c6..0000000
--- a/bootstrap/src/Build.hs
+++ /dev/null
@@ -1,239 +0,0 @@
-{-# LANGUAGE MultiWayIf #-}
-module Build
- ( CompilerSettings(..)
- , buildLibrary
- , buildProgram
- , buildWithScript
- )
-where
-
-import BuildModel ( AvailableModule(..)
- , CompileTimeInfo(..)
- , RawSource(..)
- , Source(..)
- , constructCompileTimeInfo
- , getAllObjectFiles
- , getAvailableModules
- , getSourceFileName
- , processRawSource
- )
-import Data.List ( intercalate
- , isSuffixOf
- )
-import Data.List.Utils ( replace )
-import Development.Shake ( FilePattern
- , Change(ChangeModtimeAndDigest)
- , cmd
- , getDirectoryFilesIO
- , liftIO
- , need
- , progressSimple
- , shake
- , shakeChange
- , shakeColor
- , shakeFiles
- , shakeOptions
- , shakeProgress
- , shakeThreads
- , want
- , (<//>)
- , (%>)
- , (&?>)
- )
-import Development.Shake.FilePath ( exe
- , splitDirectories
- , (</>)
- , (<.>)
- )
-import System.Environment ( setEnv )
-import System.FilePath ( takeBaseName )
-import System.Process ( system )
-import System.Directory ( createDirectoryIfMissing
- , makeAbsolute
- , withCurrentDirectory
- )
-
-data CompilerSettings = CompilerSettings {
- compilerSettingsCompiler :: FilePath
- , compilerSettingsFlags :: [String]
- , compilerSettingsModuleFlag :: String
- , compilerSettingsIncludeFlag :: String
-}
-
-buildProgram
- :: FilePath
- -> [FilePath]
- -> [FilePattern]
- -> FilePath
- -> CompilerSettings
- -> String
- -> FilePath
- -> [FilePath]
- -> IO ()
-buildProgram programDirectory' libraryDirectories sourceExtensions buildDirectory' (CompilerSettings { compilerSettingsCompiler = compiler, compilerSettingsFlags = flags, compilerSettingsModuleFlag = moduleFlag, compilerSettingsIncludeFlag = includeFlag }) programName programSource archives
- = do
- libraryModules <- findAvailableModules libraryDirectories
- let programDirectory = foldl1 (</>) (splitDirectories programDirectory')
- let buildDirectory = foldl1 (</>) (splitDirectories buildDirectory')
- let includeFlags = (includeFlag ++ buildDirectory) : map (includeFlag ++) libraryDirectories
- sourceFiles <- getDirectoriesFiles [programDirectory] sourceExtensions
- rawSources <- mapM sourceFileToRawSource sourceFiles
- let sources' = map processRawSource rawSources
- let isThisProgramOrNotProgram p@(Program{}) =
- programSourceFileName p == programDirectory </> programSource
- isThisProgramOrNotProgram _ = True
- let sources = filter isThisProgramOrNotProgram sources'
- let availableModules = (getAvailableModules sources buildDirectory) ++ libraryModules
- let compileTimeInfo = map
- (\s -> constructCompileTimeInfo s availableModules buildDirectory)
- sources
- let objectFiles = getAllObjectFiles buildDirectory sources
- shake shakeOptions { shakeFiles = buildDirectory
- , shakeChange = ChangeModtimeAndDigest
- , shakeColor = True
- , shakeThreads = 0
- , shakeProgress = progressSimple
- }
- $ do
- let infoToRule cti =
- let obj = compileTimeInfoObjectFileProduced cti
- other = compileTimeInfoOtherFilesProduced cti
- directDependencies = compileTimeInfoDirectDependencies cti
- sourceFile = compileTimeInfoSourceFileName cti
- fileMatcher f =
- let realf = foldl1 (</>) (splitDirectories f)
- in if realf == obj || realf `elem` other
- then Just (obj : other)
- else Nothing
- in fileMatcher &?> \(objectFile : _) -> do
- need (sourceFile : directDependencies)
- cmd compiler
- ["-c", moduleFlag, buildDirectory]
- includeFlags
- flags
- ["-o", objectFile, sourceFile]
- want [buildDirectory </> programName <.> exe]
- buildDirectory </> programName <.> exe %> \executable -> do
- need objectFiles
- need archives
- cmd compiler objectFiles archives ["-o", executable] flags
- mapM_ infoToRule compileTimeInfo
-
-buildLibrary
- :: FilePath
- -> [FilePattern]
- -> FilePath
- -> CompilerSettings
- -> String
- -> [FilePath]
- -> IO (FilePath)
-buildLibrary libraryDirectory sourceExtensions buildDirectory (CompilerSettings { compilerSettingsCompiler = compiler, compilerSettingsFlags = flags, compilerSettingsModuleFlag = moduleFlag, compilerSettingsIncludeFlag = includeFlag }) libraryName otherLibraryDirectories
- = do
- otherModules <- findAvailableModules otherLibraryDirectories
- let includeFlags = (includeFlag ++ buildDirectory) : map (includeFlag ++) otherLibraryDirectories
- sourceFiles <- getDirectoriesFiles [libraryDirectory] sourceExtensions
- rawSources <- mapM sourceFileToRawSource sourceFiles
- let sources = map processRawSource rawSources
- let availableModules = (getAvailableModules sources buildDirectory) ++ otherModules
- let compileTimeInfo = map
- (\s -> constructCompileTimeInfo s availableModules buildDirectory)
- sources
- let objectFiles = getAllObjectFiles buildDirectory sources
- let archiveFile = buildDirectory </> "lib" ++ libraryName <.> "a"
- shake shakeOptions { shakeFiles = buildDirectory
- , shakeChange = ChangeModtimeAndDigest
- , shakeColor = True
- , shakeThreads = 0
- , shakeProgress = progressSimple
- }
- $ do
- let infoToRule cti =
- let obj = compileTimeInfoObjectFileProduced cti
- other = compileTimeInfoOtherFilesProduced cti
- directDependencies = compileTimeInfoDirectDependencies cti
- sourceFile = compileTimeInfoSourceFileName cti
- fileMatcher f =
- let realf = foldl1 (</>) (splitDirectories f)
- in if realf == obj || realf `elem` other
- then Just (obj : other)
- else Nothing
- in fileMatcher &?> \(objectFile : _) -> do
- need (sourceFile : directDependencies)
- cmd compiler
- ["-c", moduleFlag, buildDirectory]
- includeFlags
- flags
- ["-o", objectFile, sourceFile]
- want [archiveFile]
- archiveFile %> \a -> do
- need objectFiles
- cmd "ar" ["rs"] a objectFiles
- mapM_ infoToRule compileTimeInfo
- return archiveFile
-
-buildWithScript
- :: String
- -> FilePath
- -> FilePath
- -> CompilerSettings
- -> String
- -> [FilePath]
- -> IO (FilePath)
-buildWithScript script projectDirectory buildDirectory (CompilerSettings { compilerSettingsCompiler = compiler, compilerSettingsFlags = flags, compilerSettingsModuleFlag = moduleFlag, compilerSettingsIncludeFlag = includeFlag }) libraryName otherLibraryDirectories
- = do
- absoluteBuildDirectory <- makeAbsolute buildDirectory
- createDirectoryIfMissing True absoluteBuildDirectory
- absoluteLibraryDirectories <- mapM makeAbsolute otherLibraryDirectories
- setEnv "FC" compiler
- setEnv "FFLAGS" (intercalate " " flags)
- setEnv "FINCLUDEFLAG" includeFlag
- setEnv "FMODUELFLAG" moduleFlag
- setEnv "BUILD_DIR" $ unWindowsPath absoluteBuildDirectory
- setEnv "INCLUDE_DIRS"
- (intercalate " " (map unWindowsPath absoluteLibraryDirectories))
- let archiveFile =
- (unWindowsPath absoluteBuildDirectory)
- ++ "/lib"
- ++ libraryName
- <.> "a"
- withCurrentDirectory
- projectDirectory
- if
- | isMakefile script -> system
- ("make -f " ++ script ++ " " ++ archiveFile)
- | otherwise -> system (script ++ " " ++ archiveFile)
- return archiveFile
-
--- A little wrapper around getDirectoryFiles so we can get files from multiple directories
-getDirectoriesFiles :: [FilePath] -> [FilePattern] -> IO [FilePath]
-getDirectoriesFiles dirs exts = getDirectoryFilesIO "" newPatterns
- where
- newPatterns = concatMap appendExts dirs
- appendExts dir = map ((dir <//> "*") ++) exts
-
-sourceFileToRawSource :: FilePath -> IO RawSource
-sourceFileToRawSource sourceFile = do
- contents <- readFile sourceFile
- return $ RawSource sourceFile contents
-
-isMakefile :: String -> Bool
-isMakefile script | script == "Makefile" = True
- | script == "makefile" = True
- | ".mk" `isSuffixOf` script = True
- | otherwise = False
-
-unWindowsPath :: String -> String
-unWindowsPath = changeSeparators . removeDriveLetter
-
-removeDriveLetter :: String -> String
-removeDriveLetter path | ':' `elem` path = (tail . dropWhile (/= ':')) path
- | otherwise = path
-
-changeSeparators :: String -> String
-changeSeparators = replace "\\" "/"
-
-findAvailableModules :: [FilePath] -> IO [AvailableModule]
-findAvailableModules directories = do
- moduleFiles <- getDirectoriesFiles directories ["*.mod"]
- let availableModules = map (\mf -> AvailableModule { availableModuleName = takeBaseName mf, availableModuleFile = mf }) moduleFiles
- return availableModules
diff --git a/bootstrap/src/BuildModel.hs b/bootstrap/src/BuildModel.hs
deleted file mode 100644
index 4ca5959..0000000
--- a/bootstrap/src/BuildModel.hs
+++ /dev/null
@@ -1,411 +0,0 @@
-module BuildModel where
-
-import Control.Applicative ( (<|>) )
-import Control.Monad ( when )
-import Data.Char ( isAsciiLower
- , isDigit
- , toLower
- )
-import Data.Maybe ( fromMaybe
- , mapMaybe
- )
-import Data.List ( intercalate )
-import System.FilePath ( (</>)
- , (<.>)
- , splitDirectories
- )
-import Text.ParserCombinators.ReadP ( ReadP
- , char
- , eof
- , many
- , many1
- , option
- , readP_to_S
- , satisfy
- , skipSpaces
- , string
- )
-
-data LineContents =
- ProgramDeclaration
- | ModuleDeclaration String
- | ModuleUsed String
- | ModuleSubprogramDeclaration
- | SubmoduleDeclaration String String String
- | Other
-
-data RawSource = RawSource {
- rawSourceFilename :: FilePath
- , rawSourceContents :: String
-}
-
-data Source =
- Program
- { programSourceFileName :: FilePath
- , programObjectFileName :: FilePath -> FilePath
- , programModulesUsed :: [String]
- }
- | Module
- { moduleSourceFileName :: FilePath
- , moduleObjectFileName :: FilePath -> FilePath
- , moduleModulesUsed :: [String]
- , moduleName :: String
- , moduleProducesSmod :: Bool
- }
- | Submodule
- { submoduleSourceFileName :: FilePath
- , submoduleObjectFileName :: FilePath -> FilePath
- , submoduleModulesUsed :: [String]
- , submoduleBaseModuleName :: String
- , submoduleParentName :: String
- , submoduleName :: String
- }
-
-data CompileTimeInfo = CompileTimeInfo {
- compileTimeInfoSourceFileName :: FilePath
- , compileTimeInfoObjectFileProduced :: FilePath
- , compileTimeInfoOtherFilesProduced :: [FilePath]
- , compileTimeInfoDirectDependencies :: [FilePath]
-}
-
-data AvailableModule = AvailableModule {
- availableModuleName :: String
- , availableModuleFile :: FilePath
-}
-
-processRawSource :: RawSource -> Source
-processRawSource rawSource =
- let
- sourceFileName = rawSourceFilename rawSource
- parsedContents = parseContents rawSource
- objectFileName =
- \bd -> bd </> (pathSeparatorsToUnderscores sourceFileName) <.> "o"
- modulesUsed = getModulesUsed parsedContents
- in
- if hasProgramDeclaration parsedContents
- then Program { programSourceFileName = sourceFileName
- , programObjectFileName = objectFileName
- , programModulesUsed = modulesUsed
- }
- else if hasModuleDeclaration parsedContents
- then Module
- { moduleSourceFileName = sourceFileName
- , moduleObjectFileName = objectFileName
- , moduleModulesUsed = modulesUsed
- , moduleName = getModuleName parsedContents
- , moduleProducesSmod = hasModuleSubprogramDeclaration parsedContents
- }
- else if hasSubmoduleDeclaration parsedContents
- then Submodule
- { submoduleSourceFileName = sourceFileName
- , submoduleObjectFileName = objectFileName
- , submoduleModulesUsed = modulesUsed
- , submoduleBaseModuleName = getSubmoduleBaseModuleName
- parsedContents
- , submoduleParentName = getSubmoduleParentName parsedContents
- , submoduleName = getSubmoduleName parsedContents
- }
- else undefined
-
-getAvailableModules :: [Source] -> FilePath -> [AvailableModule]
-getAvailableModules sources buildDirectory = mapMaybe maybeModule sources
- where
- maybeModule m@(Module{}) =
- let mName = moduleName m
- modFile = buildDirectory </> mName <.> "mod"
- in Just $ AvailableModule { availableModuleName = mName, availableModuleFile = modFile }
- maybeModule _ = Nothing
-
-getAllObjectFiles :: FilePath -> [Source] -> [FilePath]
-getAllObjectFiles buildDirectory sources = map getObjectFile sources
- where
- getObjectFile p@(Program{} ) = (programObjectFileName p) buildDirectory
- getObjectFile m@(Module{} ) = (moduleObjectFileName m) buildDirectory
- getObjectFile s@(Submodule{}) = (submoduleObjectFileName s) buildDirectory
-
-getSourceFileName :: Source -> FilePath
-getSourceFileName p@(Program{} ) = programSourceFileName p
-getSourceFileName m@(Module{} ) = moduleSourceFileName m
-getSourceFileName s@(Submodule{}) = submoduleSourceFileName s
-
-constructCompileTimeInfo :: Source -> [AvailableModule] -> FilePath -> CompileTimeInfo
-constructCompileTimeInfo p@(Program{}) availableModules buildDirectory =
- CompileTimeInfo
- { compileTimeInfoSourceFileName = programSourceFileName p
- , compileTimeInfoObjectFileProduced = (programObjectFileName p)
- buildDirectory
- , compileTimeInfoOtherFilesProduced = []
- , compileTimeInfoDirectDependencies = map
- (\am -> availableModuleFile am)
- (filter (\am -> (availableModuleName am) `elem` (programModulesUsed p)) availableModules)
- }
-constructCompileTimeInfo m@(Module{}) availableModules buildDirectory =
- CompileTimeInfo
- { compileTimeInfoSourceFileName = moduleSourceFileName m
- , compileTimeInfoObjectFileProduced = (moduleObjectFileName m)
- buildDirectory
- , compileTimeInfoOtherFilesProduced =
- (buildDirectory </> moduleName m <.> "mod") : if moduleProducesSmod m
- then [buildDirectory </> moduleName m <.> "smod"]
- else []
- , compileTimeInfoDirectDependencies = map
- (\am -> availableModuleFile am)
- (filter (\am -> (availableModuleName am) `elem` (moduleModulesUsed m)) availableModules)
- }
-constructCompileTimeInfo s@(Submodule{}) availableModules buildDirectory =
- CompileTimeInfo
- { compileTimeInfoSourceFileName = submoduleSourceFileName s
- , compileTimeInfoObjectFileProduced = (submoduleObjectFileName s)
- buildDirectory
- , compileTimeInfoOtherFilesProduced = [ buildDirectory
- </> submoduleBaseModuleName s
- ++ "@"
- ++ submoduleName s
- <.> "smod"
- ]
- , compileTimeInfoDirectDependencies =
- (buildDirectory </> submoduleParentName s <.> "smod")
- : (map (\am -> availableModuleFile am)
- (filter (\am -> (availableModuleName am) `elem` (submoduleModulesUsed s)) availableModules)
- )
- }
-
-pathSeparatorsToUnderscores :: FilePath -> FilePath
-pathSeparatorsToUnderscores fileName =
- intercalate "_" (splitDirectories fileName)
-
-parseContents :: RawSource -> [LineContents]
-parseContents rawSource =
- let fileLines = lines $ rawSourceContents rawSource
- in map parseFortranLine fileLines
-
-hasProgramDeclaration :: [LineContents] -> Bool
-hasProgramDeclaration parsedContents = case filter f parsedContents of
- x : _ -> True
- _ -> False
- where
- f lc = case lc of
- ProgramDeclaration -> True
- _ -> False
-
-hasModuleDeclaration :: [LineContents] -> Bool
-hasModuleDeclaration parsedContents = case filter f parsedContents of
- x : _ -> True
- _ -> False
- where
- f lc = case lc of
- ModuleDeclaration{} -> True
- _ -> False
-
-hasSubmoduleDeclaration :: [LineContents] -> Bool
-hasSubmoduleDeclaration parsedContents = case filter f parsedContents of
- x : _ -> True
- _ -> False
- where
- f lc = case lc of
- SubmoduleDeclaration{} -> True
- _ -> False
-
-hasModuleSubprogramDeclaration :: [LineContents] -> Bool
-hasModuleSubprogramDeclaration parsedContents = case filter f parsedContents of
- x : _ -> True
- _ -> False
- where
- f lc = case lc of
- ModuleSubprogramDeclaration -> True
- _ -> False
-
-getModulesUsed :: [LineContents] -> [String]
-getModulesUsed = mapMaybe contentToMaybeModuleName
- where
- contentToMaybeModuleName content = case content of
- ModuleUsed moduleName -> Just moduleName
- _ -> Nothing
-
-getModuleName :: [LineContents] -> String
-getModuleName pc = head $ mapMaybe contentToMaybeModuleName pc
- where
- contentToMaybeModuleName content = case content of
- ModuleDeclaration moduleName -> Just moduleName
- _ -> Nothing
-
-getSubmoduleBaseModuleName :: [LineContents] -> String
-getSubmoduleBaseModuleName pc = head $ mapMaybe contentToMaybeModuleName pc
- where
- contentToMaybeModuleName content = case content of
- SubmoduleDeclaration baseModuleName submoduleParentName submoduleName ->
- Just baseModuleName
- _ -> Nothing
-
-getSubmoduleParentName :: [LineContents] -> String
-getSubmoduleParentName pc = head $ mapMaybe contentToMaybeModuleName pc
- where
- contentToMaybeModuleName content = case content of
- SubmoduleDeclaration baseModuleName submoduleParentName submoduleName ->
- Just submoduleParentName
- _ -> Nothing
-
-getSubmoduleName :: [LineContents] -> String
-getSubmoduleName pc = head $ mapMaybe contentToMaybeModuleName pc
- where
- contentToMaybeModuleName content = case content of
- SubmoduleDeclaration baseModuleName submoduleParentName submoduleName ->
- Just submoduleName
- _ -> Nothing
-
-readFileLinesIO :: FilePath -> IO [String]
-readFileLinesIO file = do
- contents <- readFile file
- return $ lines contents
-
-parseFortranLine :: String -> LineContents
-parseFortranLine line =
- let line' = map toLower line
- result = readP_to_S doFortranLineParse line'
- in getResult result
- where
- getResult (_ : (contents, _) : _) = contents
- getResult [(contents, _) ] = contents
- getResult [] = Other
-
-doFortranLineParse :: ReadP LineContents
-doFortranLineParse = option Other fortranUsefulContents
-
-fortranUsefulContents :: ReadP LineContents
-fortranUsefulContents =
- programDeclaration
- <|> moduleSubprogramDeclaration
- <|> moduleDeclaration
- <|> submoduleDeclaration
- <|> useStatement
-
-programDeclaration :: ReadP LineContents
-programDeclaration = do
- skipSpaces
- _ <- string "program"
- skipAtLeastOneWhiteSpace
- _ <- validIdentifier
- return ProgramDeclaration
-
-moduleDeclaration :: ReadP LineContents
-moduleDeclaration = do
- skipSpaces
- _ <- string "module"
- skipAtLeastOneWhiteSpace
- moduleName <- validIdentifier
- when (moduleName == "procedure") (fail "")
- skipSpaceCommentOrEnd
- return $ ModuleDeclaration moduleName
-
-submoduleDeclaration :: ReadP LineContents
-submoduleDeclaration = do
- skipSpaces
- _ <- string "submodule"
- parents <- submoduleParents
- let parentName = case parents of
- (baseModule : []) -> baseModule
- (multiple ) -> (head multiple) ++ "@" ++ (last multiple)
- skipSpaces
- name <- validIdentifier
- skipSpaceCommentOrEnd
- return $ SubmoduleDeclaration (head parents) parentName name
-
-submoduleParents :: ReadP [String]
-submoduleParents = do
- skipSpaces
- _ <- char '('
- skipSpaces
- firstParent <- validIdentifier
- remainingParents <- many
- (do
- skipSpaces
- _ <- char ':'
- skipSpaces
- name <- validIdentifier
- return name
- )
- skipSpaces
- _ <- char ')'
- return $ firstParent : remainingParents
-
-useStatement :: ReadP LineContents
-useStatement = do
- skipSpaces
- _ <- string "use"
- skipAtLeastOneWhiteSpace
- modName <- validIdentifier
- skipSpaceCommaOrEnd
- return $ ModuleUsed modName
-
-moduleSubprogramDeclaration :: ReadP LineContents
-moduleSubprogramDeclaration = do
- skipSpaces
- skipProcedureQualifiers
- _ <- string "module"
- skipAtLeastOneWhiteSpace
- _ <- string "function" <|> string "subroutine"
- skipAtLeastOneWhiteSpace
- return $ ModuleSubprogramDeclaration
-
-skipProcedureQualifiers :: ReadP ()
-skipProcedureQualifiers = do
- many skipPossibleQualifier
- return ()
-
-skipPossibleQualifier :: ReadP ()
-skipPossibleQualifier = do
- _ <- string "pure" <|> string "elemental" <|> string "impure"
- skipAtLeastOneWhiteSpace
-
-skipAtLeastOneWhiteSpace :: ReadP ()
-skipAtLeastOneWhiteSpace = do
- _ <- many1 whiteSpace
- return ()
-
-skipSpaceOrEnd :: ReadP ()
-skipSpaceOrEnd = eof <|> skipAtLeastOneWhiteSpace
-
-skipSpaceCommaOrEnd :: ReadP ()
-skipSpaceCommaOrEnd = eof <|> skipComma <|> skipAtLeastOneWhiteSpace
-
-skipSpaceCommentOrEnd :: ReadP ()
-skipSpaceCommentOrEnd = eof <|> skipComment <|> skipAtLeastOneWhiteSpace
-
-skipComma :: ReadP ()
-skipComma = do
- _ <- char ','
- return ()
-
-skipComment :: ReadP ()
-skipComment = do
- _ <- char '!'
- return ()
-
-skipAnything :: ReadP ()
-skipAnything = do
- _ <- many (satisfy (const True))
- return ()
-
-whiteSpace :: ReadP Char
-whiteSpace = satisfy (`elem` " \t")
-
-validIdentifier :: ReadP String
-validIdentifier = do
- first <- validFirstCharacter
- rest <- many validIdentifierCharacter
- return $ first : rest
-
-validFirstCharacter :: ReadP Char
-validFirstCharacter = alphabet
-
-validIdentifierCharacter :: ReadP Char
-validIdentifierCharacter = alphabet <|> digit <|> underscore
-
-alphabet :: ReadP Char
-alphabet = satisfy isAsciiLower
-
-digit :: ReadP Char
-digit = satisfy isDigit
-
-underscore :: ReadP Char
-underscore = char '_'
diff --git a/bootstrap/src/Fpm.hs b/bootstrap/src/Fpm.hs
deleted file mode 100644
index 56e2d90..0000000
--- a/bootstrap/src/Fpm.hs
+++ /dev/null
@@ -1,1227 +0,0 @@
-{-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-
-module Fpm
- ( Arguments(..)
- , getArguments
- , start
- )
-where
-
-import Build ( CompilerSettings(..)
- , buildLibrary
- , buildProgram
- , buildWithScript
- )
-import Control.Monad.Extra ( concatMapM
- , forM_
- , when
- )
-import Data.Hashable ( hash )
-import Data.List ( intercalate
- , isInfixOf
- , isSuffixOf
- , find
- , nub
- )
-import qualified Data.Map as Map
-import qualified Data.Text.IO as TIO
-import Development.Shake ( FilePattern
- , (<//>)
- , getDirectoryFilesIO
- )
-import Development.Shake.FilePath ( (</>)
- , (<.>)
- , exe
- , splitDirectories
- )
-import Numeric ( showHex )
-import Options.Applicative ( Parser
- , (<**>)
- , (<|>)
- , auto
- , command
- , execParser
- , fullDesc
- , header
- , help
- , helper
- , info
- , long
- , many
- , metavar
- , option
- , optional
- , progDesc
- , short
- , showDefault
- , strArgument
- , strOption
- , subparser
- , switch
- , value
- )
-import System.Directory ( createDirectory
- , doesDirectoryExist
- , doesFileExist
- , makeAbsolute
- , withCurrentDirectory
- )
-import System.Exit ( ExitCode(..)
- , exitWith
- )
-import System.Process ( readProcess
- , readProcessWithExitCode
- , system
- )
-import Toml ( TomlCodec
- , (.=)
- )
-import qualified Toml
-
-data Arguments =
- New
- { newName :: String
- , newWithExecutable :: Bool
- , newWithTest :: Bool
- , newWithLib :: Bool
- }
- | Build
- { buildRelease :: Bool
- , buildCompiler :: FilePath
- , buildFlags :: [String]
- }
- | Run
- { runRelease :: Bool
- , runExample :: Bool
- , runCompiler :: FilePath
- , runFlags :: [String]
- , runRunner :: Maybe String
- , runTarget :: Maybe String
- , runArgs :: Maybe [String]
- }
- | Test
- { testRelease :: Bool
- , testCompiler :: FilePath
- , testFlags :: [String]
- , testRunner :: Maybe String
- , testTarget :: Maybe String
- , testArgs :: Maybe [String]
- }
-
-data TomlSettings = TomlSettings {
- tomlSettingsProjectName :: String
- , tomlSettingsLibrary :: (Maybe Library)
- , tomlSettingsExecutables :: [Executable]
- , tomlSettingsExamples :: [Executable]
- , tomlSettingsTests :: [Executable]
- , tomlSettingsDependencies :: (Map.Map String Version)
- , tomlSettingsDevDependencies :: (Map.Map String Version)
-}
-
-data AppSettings = AppSettings {
- appSettingsCompiler :: CompilerSettings
- , appSettingsProjectName :: String
- , appSettingsBuildPrefix :: String
- , appSettingsLibrary :: (Maybe Library)
- , appSettingsExecutables :: [Executable]
- , appSettingsExamples :: [Executable]
- , appSettingsTests :: [Executable]
- , appSettingsDependencies :: (Map.Map String Version)
- , appSettingsDevDependencies :: (Map.Map String Version)
-}
-
-data Library = Library { librarySourceDir :: String, libraryBuildScript :: Maybe String }
-
-data Executable = Executable {
- executableSourceDir :: String
- , executableMainFile :: String
- , executableName :: String
- , executableDependencies :: (Map.Map String Version)
-} deriving Show
-
-data Version = SimpleVersion String | GitVersion GitVersionSpec | PathVersion PathVersionSpec deriving Show
-
-data GitVersionSpec = GitVersionSpec { gitVersionSpecUrl :: String, gitVersionSpecRef :: Maybe GitRef } deriving Show
-
-data GitRef = Tag String | Branch String | Commit String deriving Show
-
-data PathVersionSpec = PathVersionSpec { pathVersionSpecPath :: String } deriving Show
-
-data DependencyTree = Dependency {
- dependencyName :: String
- , dependencyPath :: FilePath
- , dependencySourcePath :: FilePath
- , dependencyBuildScript :: Maybe String
- , dependencyDependencies :: [DependencyTree]
-}
-
-start :: Arguments -> IO ()
-start args = case args of
- New { newName = name, newWithExecutable = withExecutable, newWithTest = withTest, newWithLib = withLib }
- -> createNewProject name withExecutable withTest withLib
- _ -> do
- fpmContents <- TIO.readFile "fpm.toml"
- let tomlSettings = Toml.decode settingsCodec fpmContents
- case tomlSettings of
- Left err -> print err
- Right tomlSettings' -> do
- appSettings <- toml2AppSettings tomlSettings' args
- app args appSettings
-
-app :: Arguments -> AppSettings -> IO ()
-app args settings = case args of
- Build{} -> build settings
- Run { runTarget = whichOne, runArgs = runArgs, runRunner = runner, runExample = runExample } -> do
- build settings
- let buildPrefix = appSettingsBuildPrefix settings
- let
- executableNames = if runExample
- then
- map
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name } ->
- sourceDir </> name
- )
- (appSettingsExamples settings)
- else
- map
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name } ->
- sourceDir </> name
- )
- (appSettingsExecutables settings)
- let executables =
- map (buildPrefix </>) $ map (flip (<.>) exe) executableNames
- canonicalExecutables <- mapM makeAbsolute executables
- case canonicalExecutables of
- [] -> putStrLn "No Executables Found"
- _ ->
- let commandPrefix = case runner of
- Nothing -> ""
- Just r -> r ++ " "
- commandSufix = case runArgs of
- Nothing -> ""
- Just a -> " " ++ (intercalate " " a)
- in case whichOne of
- Nothing -> do
- exitCodes <- mapM
- system
- (map (\exe -> commandPrefix ++ exe ++ commandSufix)
- canonicalExecutables
- )
- forM_
- exitCodes
- (\exitCode -> when
- (case exitCode of
- ExitSuccess -> False
- _ -> True
- )
- (exitWith exitCode)
- )
- Just name -> do
- case find (name `isSuffixOf`) canonicalExecutables of
- Nothing -> putStrLn "Executable Not Found"
- Just specified -> do
- exitCode <- system
- (commandPrefix ++ specified ++ commandSufix)
- exitWith exitCode
- Test { testTarget = whichOne, testArgs = testArgs, testRunner = runner } ->
- do
- build settings
- let buildPrefix = appSettingsBuildPrefix settings
- let
- executableNames = map
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name } ->
- sourceDir </> name
- )
- (appSettingsTests settings)
- let executables =
- map (buildPrefix </>) $ map (flip (<.>) exe) executableNames
- canonicalExecutables <- mapM makeAbsolute executables
- case canonicalExecutables of
- [] -> putStrLn "No Tests Found"
- _ ->
- let commandPrefix = case runner of
- Nothing -> ""
- Just r -> r ++ " "
- commandSufix = case testArgs of
- Nothing -> ""
- Just a -> " " ++ (intercalate " " a)
- in case whichOne of
- Nothing -> do
- exitCodes <- mapM
- system
- (map (\exe -> commandPrefix ++ exe ++ commandSufix)
- canonicalExecutables
- )
- forM_
- exitCodes
- (\exitCode -> when
- (case exitCode of
- ExitSuccess -> False
- _ -> True
- )
- (exitWith exitCode)
- )
- Just name -> do
- case find (name `isSuffixOf`) canonicalExecutables of
- Nothing -> putStrLn "Test Not Found"
- Just specified -> do
- exitCode <- system
- (commandPrefix ++ specified ++ commandSufix)
- exitWith exitCode
- _ -> putStrLn "Shouldn't be able to get here"
-
-build :: AppSettings -> IO ()
-build settings = do
- let compilerSettings = appSettingsCompiler settings
- let projectName = appSettingsProjectName settings
- let buildPrefix = appSettingsBuildPrefix settings
- let executables = appSettingsExecutables settings
- let examples = appSettingsExamples settings
- let tests = appSettingsTests settings
- mainDependencyTrees <- fetchDependencies (appSettingsDependencies settings)
- builtDependencies <- buildDependencies buildPrefix
- compilerSettings
- mainDependencyTrees
- (executableDepends, maybeTree) <- case appSettingsLibrary settings of
- Just librarySettings -> do
- let librarySourceDir' = librarySourceDir librarySettings
- let thisDependencyTree = Dependency
- { dependencyName = projectName
- , dependencyPath = "."
- , dependencySourcePath = librarySourceDir'
- , dependencyBuildScript = libraryBuildScript librarySettings
- , dependencyDependencies = mainDependencyTrees
- }
- thisArchive <- case libraryBuildScript librarySettings of
- Just script -> buildWithScript script
- "."
- (buildPrefix </> projectName)
- compilerSettings
- projectName
- (map fst builtDependencies)
- Nothing -> buildLibrary librarySourceDir'
- [".f90", ".f", ".F", ".F90", ".f95", ".f03"]
- (buildPrefix </> projectName)
- compilerSettings
- projectName
- (map fst builtDependencies)
- return
- $ ( (buildPrefix </> projectName, thisArchive) : builtDependencies
- , Just thisDependencyTree
- )
- Nothing -> do
- return (builtDependencies, Nothing)
- mapM_
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name, executableDependencies = dependencies } ->
- do
- localDependencies <-
- fetchExecutableDependencies maybeTree dependencies
- >>= buildDependencies buildPrefix compilerSettings
- buildProgram
- sourceDir
- ((map fst executableDepends) ++ (map fst localDependencies))
- [".f90", ".f", ".F", ".F90", ".f95", ".f03"]
- (buildPrefix </> sourceDir)
- compilerSettings
- name
- mainFile
- ((map snd executableDepends) ++ (map snd localDependencies))
- )
- executables
- devDependencies <-
- fetchExecutableDependencies maybeTree (appSettingsDevDependencies settings)
- >>= buildDependencies buildPrefix compilerSettings
- mapM_
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name, executableDependencies = dependencies } ->
- do
- localDependencies <-
- fetchExecutableDependencies maybeTree dependencies
- >>= buildDependencies buildPrefix compilerSettings
- buildProgram
- sourceDir
- ( (map fst executableDepends)
- ++ (map fst devDependencies)
- ++ (map fst localDependencies)
- )
- [".f90", ".f", ".F", ".F90", ".f95", ".f03"]
- (buildPrefix </> sourceDir)
- compilerSettings
- name
- mainFile
- ( (map snd executableDepends)
- ++ (map snd devDependencies)
- ++ (map snd localDependencies)
- )
- )
- examples
- mapM_
- (\Executable { executableSourceDir = sourceDir, executableMainFile = mainFile, executableName = name, executableDependencies = dependencies } ->
- do
- localDependencies <-
- fetchExecutableDependencies maybeTree dependencies
- >>= buildDependencies buildPrefix compilerSettings
- buildProgram
- sourceDir
- ( (map fst executableDepends)
- ++ (map fst devDependencies)
- ++ (map fst localDependencies)
- )
- [".f90", ".f", ".F", ".F90", ".f95", ".f03"]
- (buildPrefix </> sourceDir)
- compilerSettings
- name
- mainFile
- ( (map snd executableDepends)
- ++ (map snd devDependencies)
- ++ (map snd localDependencies)
- )
- )
- tests
-
-getArguments :: IO Arguments
-getArguments = execParser
- (info
- (arguments <**> helper)
- (fullDesc <> progDesc "Work with Fortran projects" <> header
- "fpm - A Fortran package manager and build system"
- )
- )
-
-arguments :: Parser Arguments
-arguments = subparser
- ( command
- "new"
- (info (newArguments <**> helper)
- (progDesc "Create a new project in a new directory")
- )
- <> command
- "build"
- (info (buildArguments <**> helper) (progDesc "Build the project"))
- <> command
- "run"
- (info (runArguments <**> helper) (progDesc "Run the executable(s)"))
- <> command "test"
- (info (testArguments <**> helper) (progDesc "Run the test(s)"))
- )
-
-newArguments :: Parser Arguments
-newArguments =
- New
- <$> strArgument
- ( metavar "NAME"
- <> help "Name of new project (must be a valid Fortran identifier)"
- )
- <*> switch (long "app" <> help "Include an executable")
- <*> switch (long "test" <> help "Include a test")
- <*> switch (long "lib" <> help "Include a library")
-
-buildArguments :: Parser Arguments
-buildArguments =
- Build
- <$> switch
- ( long "release"
- <> help "Build with optimizations instead of debugging"
- )
- <*> strOption
- ( long "compiler"
- <> metavar "COMPILER"
- <> value "gfortran"
- <> help "specify the compiler to use"
- <> showDefault
- )
- <*> many
- (strOption
- ( long "flag"
- <> metavar "FLAG"
- <> help
- "specify an addional argument to pass to the compiler (can appear multiple times)"
- )
- )
-
-runArguments :: Parser Arguments
-runArguments =
- Run
- <$> switch
- ( long "release"
- <> help "Build with optimizations instead of debugging"
- )
- <*> switch
- ( long "example"
- <> help "Run example programs instead of applications"
- )
- <*> strOption
- ( long "compiler"
- <> metavar "COMPILER"
- <> value "gfortran"
- <> help "specify the compiler to use"
- <> showDefault
- )
- <*> many
- (strOption
- ( long "flag"
- <> metavar "FLAG"
- <> help
- "specify an addional argument to pass to the compiler (can appear multiple times)"
- )
- )
- <*> optional
- (strOption
- (long "runner" <> metavar "RUNNER" <> help
- "specify a command to be used to run the executable(s)"
- )
- )
- <*> optional
- (strOption
- (long "target" <> metavar "TARGET" <> help
- "Name of the executable to run"
- )
- )
- <*> optional
- (many
- (strArgument
- ( metavar "ARGS"
- <> help "Arguments to the executable(s) (should follow '--')"
- )
- )
- )
-
-testArguments :: Parser Arguments
-testArguments =
- Test
- <$> switch
- ( long "release"
- <> help "Build with optimizations instead of debugging"
- )
- <*> strOption
- ( long "compiler"
- <> metavar "COMPILER"
- <> value "gfortran"
- <> help "specify the compiler to use"
- <> showDefault
- )
- <*> many
- (strOption
- ( long "flag"
- <> metavar "FLAG"
- <> help
- "specify an addional argument to pass to the compiler (can appear multiple times)"
- )
- )
- <*> optional
- (strOption
- (long "runner" <> metavar "RUNNER" <> help
- "specify a command to be used to run the test(s)"
- )
- )
- <*> optional
- (strOption
- (long "target" <> metavar "TARGET" <> help "Name of the test to run"
- )
- )
- <*> optional
- (many
- (strArgument
- ( metavar "ARGS"
- <> help "Arguments to the test(s) (should follow '--')"
- )
- )
- )
-
-getDirectoriesFiles :: [FilePath] -> [FilePattern] -> IO [FilePath]
-getDirectoriesFiles dirs exts = getDirectoryFilesIO "" newPatterns
- where
- newPatterns = concatMap appendExts dirs
- appendExts dir = map ((dir <//> "*") ++) exts
-
-settingsCodec :: TomlCodec TomlSettings
-settingsCodec =
- TomlSettings
- <$> Toml.string "name"
- .= tomlSettingsProjectName
- <*> Toml.dioptional (Toml.table libraryCodec "library")
- .= tomlSettingsLibrary
- <*> Toml.list executableCodec "executable"
- .= tomlSettingsExecutables
- <*> Toml.list executableCodec "example"
- .= tomlSettingsExamples
- <*> Toml.list executableCodec "test"
- .= tomlSettingsTests
- <*> Toml.tableMap Toml._KeyString versionCodec "dependencies"
- .= tomlSettingsDependencies
- <*> Toml.tableMap Toml._KeyString versionCodec "dev-dependencies"
- .= tomlSettingsDevDependencies
-
-libraryCodec :: TomlCodec Library
-libraryCodec =
- Library
- <$> Toml.string "source-dir"
- .= librarySourceDir
- <*> Toml.dioptional (Toml.string "build-script")
- .= libraryBuildScript
-
-executableCodec :: TomlCodec Executable
-executableCodec =
- Executable
- <$> Toml.string "source-dir"
- .= executableSourceDir
- <*> Toml.string "main"
- .= executableMainFile
- <*> Toml.string "name"
- .= executableName
- <*> Toml.tableMap Toml._KeyString versionCodec "dependencies"
- .= executableDependencies
-
-matchSimpleVersion :: Version -> Maybe String
-matchSimpleVersion = \case
- SimpleVersion v -> Just v
- _ -> Nothing
-
-matchGitVersion :: Version -> Maybe GitVersionSpec
-matchGitVersion = \case
- GitVersion v -> Just v
- _ -> Nothing
-
-matchPathVersion :: Version -> Maybe PathVersionSpec
-matchPathVersion = \case
- PathVersion v -> Just v
- _ -> Nothing
-
-matchTag :: GitRef -> Maybe String
-matchTag = \case
- Tag v -> Just v
- _ -> Nothing
-
-matchBranch :: GitRef -> Maybe String
-matchBranch = \case
- Branch v -> Just v
- _ -> Nothing
-
-matchCommit :: GitRef -> Maybe String
-matchCommit = \case
- Commit v -> Just v
- _ -> Nothing
-
-versionCodec :: Toml.Key -> Toml.TomlCodec Version
-versionCodec key =
- Toml.dimatch matchSimpleVersion SimpleVersion (Toml.string key)
- <|> Toml.dimatch matchGitVersion GitVersion (Toml.table gitVersionCodec key)
- <|> Toml.dimatch matchPathVersion
- PathVersion
- (Toml.table pathVersionCodec key)
-
-gitVersionCodec :: Toml.TomlCodec GitVersionSpec
-gitVersionCodec =
- GitVersionSpec
- <$> Toml.string "git"
- .= gitVersionSpecUrl
- <*> Toml.dioptional gitRefCodec
- .= gitVersionSpecRef
-
-gitRefCodec :: Toml.TomlCodec GitRef
-gitRefCodec =
- Toml.dimatch matchTag Tag (Toml.string "tag")
- <|> Toml.dimatch matchBranch Branch (Toml.string "branch")
- <|> Toml.dimatch matchCommit Commit (Toml.string "rev")
-
-pathVersionCodec :: Toml.TomlCodec PathVersionSpec
-pathVersionCodec =
- PathVersionSpec <$> Toml.string "path" .= pathVersionSpecPath
-
-toml2AppSettings :: TomlSettings -> Arguments -> IO AppSettings
-toml2AppSettings tomlSettings args = do
- let release = case args of
- Build { buildRelease = r } -> r
- Run { runRelease = r } -> r
- Test { testRelease = r } -> r
- let projectName = tomlSettingsProjectName tomlSettings
- let compiler = case args of
- Build { buildCompiler = c } -> c
- Run { runCompiler = c } -> c
- Test { testCompiler = c } -> c
- let specifiedFlags = case args of
- Build { buildFlags = f } -> f
- Run { runFlags = f } -> f
- Test { testFlags = f } -> f
- when (release && (length specifiedFlags > 0)) $ do
- putStrLn "--release and --flag are mutually exclusive"
- exitWith (ExitFailure 1)
- librarySettings <- getLibrarySettings $ tomlSettingsLibrary tomlSettings
- executableSettings <- getExecutableSettings
- (tomlSettingsExecutables tomlSettings)
- projectName
- exampleSettings <- getExampleSettings $ tomlSettingsExamples tomlSettings
- testSettings <- getTestSettings $ tomlSettingsTests tomlSettings
- compilerSettings <- defineCompilerSettings specifiedFlags compiler release
- buildPrefix <- makeBuildPrefix (compilerSettingsCompiler compilerSettings)
- (compilerSettingsFlags compilerSettings)
- let dependencies = tomlSettingsDependencies tomlSettings
- let devDependencies = tomlSettingsDevDependencies tomlSettings
- return AppSettings { appSettingsCompiler = compilerSettings
- , appSettingsProjectName = projectName
- , appSettingsBuildPrefix = buildPrefix
- , appSettingsLibrary = librarySettings
- , appSettingsExecutables = executableSettings
- , appSettingsExamples = exampleSettings
- , appSettingsTests = testSettings
- , appSettingsDependencies = dependencies
- , appSettingsDevDependencies = devDependencies
- }
-
-defineCompilerSettings :: [String] -> FilePath -> Bool -> IO CompilerSettings
-defineCompilerSettings specifiedFlags compiler release
- | "gfortran" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- [ "-Wall"
- , "-Wextra"
- , "-Wimplicit-interface"
- , "-fPIC"
- , "-fmax-errors=1"
- , "-O3"
- , "-march=native"
- , "-funroll-loops"
- , "-fcoarray=single"
- ]
- else
- [ "-Wall"
- , "-Wextra"
- , "-Wimplicit-interface"
- , "-fPIC"
- , "-fmax-errors=1"
- , "-g"
- , "-fbounds-check"
- , "-fcheck-array-temporaries"
- , "-fbacktrace"
- , "-fcoarray=single"
- ]
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-J"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "caf" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- [ "-Wall"
- , "-Wextra"
- , "-Wimplicit-interface"
- , "-fPIC"
- , "-fmax-errors=1"
- , "-O3"
- , "-march=native"
- , "-funroll-loops"
- ]
- else
- [ "-Wall"
- , "-Wextra"
- , "-Wimplicit-interface"
- , "-fPIC"
- , "-fmax-errors=1"
- , "-g"
- , "-fbounds-check"
- , "-fcheck-array-temporaries"
- , "-fbacktrace"
- ]
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-J"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "f95" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- [ "-O3"
- , "-Wimplicit-interface"
- , "-fPIC"
- , "-fmax-errors=1"
- , "-funroll-loops"
- ]
- else
- [ "-Wall"
- , "-Wextra"
- , "-Wimplicit-interface"
- , "-fPIC"
- , "-fmax-errors=1"
- , "-g"
- , "-fbounds-check"
- , "-fcheck-array-temporaries"
- , "-Wno-maybe-uninitialized"
- , "-Wno-uninitialized"
- , "-fbacktrace"
- ]
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-J"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "nvfortran" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- [ "-Mbackslash"
- ]
- else
- [ "-Minform=inform"
- , "-Mbackslash"
- , "-g"
- , "-Mbounds"
- , "-Mchkptr"
- , "-Mchkstk"
- , "-traceback"
- ]
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-module"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "ifort" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- [ "-fp-model", "precise"
- , "-pc", "64"
- , "-align", "all"
- , "-error-limit", "1"
- , "-reentrancy", "threaded"
- , "-nogen-interfaces"
- , "-assume", "byterecl"
- , "-assume", "nounderscore"
- ]
- else
- [ "-warn", "all"
- , "-check:all:noarg_temp_created"
- , "-error-limit", "1"
- , "-O0"
- , "-g"
- , "-assume", "byterecl"
- , "-traceback"
- ]
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-module"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "ifx" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- []
- else
- []
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-module"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "pgfortran" `isInfixOf` compiler || "pgf90" `isInfixOf` compiler || "pgf95" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- []
- else
- []
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-module"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "flang" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- []
- else
- []
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-module"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "lfc" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- []
- else
- []
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-M"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "nagfor" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- [ "-O4"
- , "-coarray=single"
- , "-PIC"
- ]
- else
- [ "-g"
- , "-C=all"
- , "-O0"
- , "-gline"
- , "-coarray=single"
- , "-PIC"
- ]
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-mdir"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "crayftn" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- []
- else
- []
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-J"
- , compilerSettingsIncludeFlag = "-I"
- }
- | "xlf90" `isInfixOf` compiler
- = let flags = case specifiedFlags of
- [] -> if release
- then
- []
- else
- []
- fs -> fs
- in return $ CompilerSettings { compilerSettingsCompiler = compiler
- , compilerSettingsFlags = flags
- , compilerSettingsModuleFlag = "-qmoddir"
- , compilerSettingsIncludeFlag = "-I"
- }
- | otherwise
- = do
- putStrLn $ "Sorry, compiler is currently unsupported: " ++ compiler
- exitWith (ExitFailure 1)
-
-getLibrarySettings :: Maybe Library -> IO (Maybe Library)
-getLibrarySettings maybeSettings = case maybeSettings of
- Just settings -> return maybeSettings
- Nothing -> do
- defaultExists <- doesDirectoryExist "src"
- if defaultExists
- then return
- (Just
- (Library { librarySourceDir = "src", libraryBuildScript = Nothing })
- )
- else return Nothing
-
-getExecutableSettings :: [Executable] -> String -> IO [Executable]
-getExecutableSettings [] projectName = do
- defaultDirectoryExists <- doesDirectoryExist "app"
- if defaultDirectoryExists
- then do
- defaultMainExists <- doesFileExist ("app" </> "main.f90")
- if defaultMainExists
- then return
- [ Executable { executableSourceDir = "app"
- , executableMainFile = "main.f90"
- , executableName = projectName
- , executableDependencies = Map.empty
- }
- ]
- else return []
- else return []
-getExecutableSettings executables _ = return executables
-
-getExampleSettings :: [Executable] -> IO [Executable]
-getExampleSettings [] = do
- defaultDirectoryExists <- doesDirectoryExist "example"
- if defaultDirectoryExists
- then do
- defaultMainExists <- doesFileExist ("example" </> "main.f90")
- if defaultMainExists
- then return
- [ Executable { executableSourceDir = "example"
- , executableMainFile = "main.f90"
- , executableName = "demo"
- , executableDependencies = Map.empty
- }
- ]
- else return []
- else return []
-getExampleSettings examples = return examples
-
-getTestSettings :: [Executable] -> IO [Executable]
-getTestSettings [] = do
- defaultDirectoryExists <- doesDirectoryExist "test"
- if defaultDirectoryExists
- then do
- defaultMainExists <- doesFileExist ("test" </> "main.f90")
- if defaultMainExists
- then return
- [ Executable { executableSourceDir = "test"
- , executableMainFile = "main.f90"
- , executableName = "runTests"
- , executableDependencies = Map.empty
- }
- ]
- else return []
- else return []
-getTestSettings tests = return tests
-
-makeBuildPrefix :: FilePath -> [String] -> IO FilePath
-makeBuildPrefix compiler flags = do
- -- TODO Figure out what other info should be part of this
- -- Probably version, and make sure to not include path to the compiler
- versionInfo <- do
- (exitCode, stdout, stderr) <- readProcessWithExitCode compiler
- ["--version"]
- []
- case exitCode of
- ExitSuccess -> case stdout of
- "" -> return stderr -- Guess this compiler outputs version info to stderr instead?
- _ -> return stdout
- _ -> do -- guess this compiler doesn't support the --version option. let's try -version
- (exitCode, stdout, stderr) <- readProcessWithExitCode compiler
- ["-version"]
- []
- case exitCode of
- ExitSuccess -> case stdout of
- "" -> return stderr -- Guess this compiler outputs version info to stderr instead?
- _ -> return stdout
- _ -> return "" -- Don't know how to get version info, we'll let defineCompilerSettings report it as unsupported
- let compilerName = last (splitDirectories compiler)
- let versionHash = abs (hash versionInfo)
- let flagsHash = abs (hash flags)
- return
- $ "build"
- </> compilerName
- ++ "_"
- ++ showHex versionHash ""
- ++ "_"
- ++ showHex flagsHash ""
-
-{-
- Fetching the dependencies is done on a sort of breadth first approach. All
- of the dependencies are fetched before doing the transitive dependencies.
- This means that the top level dependencies dictate which version is fetched.
- The fetchDependency function is idempotent, so we don't have to worry about
- dealing with half fetched, or adding dependencies.
- TODO check for version compatibility issues
--}
-fetchDependencies :: Map.Map String Version -> IO [DependencyTree]
-fetchDependencies dependencies = do
- theseDependencies <- mapM (uncurry fetchDependency) (Map.toList dependencies)
- mapM fetchTransitiveDependencies theseDependencies
- where
- fetchTransitiveDependencies :: (String, FilePath) -> IO DependencyTree
- fetchTransitiveDependencies (name, path) = do
- tomlSettings <- Toml.decodeFile settingsCodec (path </> "fpm.toml")
- librarySettingsM <- withCurrentDirectory path
- $ getLibrarySettings (tomlSettingsLibrary tomlSettings)
- case librarySettingsM of
- Just librarySettings -> do
- newDependencies <- fetchDependencies
- (tomlSettingsDependencies tomlSettings)
- return $ Dependency
- { dependencyName = name
- , dependencyPath = path
- , dependencySourcePath = path </> (librarySourceDir librarySettings)
- , dependencyBuildScript = libraryBuildScript librarySettings
- , dependencyDependencies = newDependencies
- }
- Nothing -> do
- putStrLn $ "No library found in " ++ name
- undefined
-
-fetchExecutableDependencies
- :: (Maybe DependencyTree) -> Map.Map String Version -> IO [DependencyTree]
-fetchExecutableDependencies maybeProjectTree dependencies =
- case maybeProjectTree of
- Just projectTree@(Dependency name _ _ _ _) ->
- if name `Map.member` dependencies {- map contains this project-}
- then fmap (projectTree :)
- (fetchDependencies (Map.delete name dependencies)) {- fetch the other dependencies and include the project tree in the result -}
- else do {- fetch all the dependencies, passing the project tree on down -}
- theseDependencies <- mapM (uncurry fetchDependency)
- (Map.toList dependencies)
- mapM fetchTransitiveDependencies theseDependencies
- Nothing -> fetchDependencies dependencies
- where
- fetchTransitiveDependencies :: (String, FilePath) -> IO DependencyTree
- fetchTransitiveDependencies (name, path) = do
- tomlSettings <- Toml.decodeFile settingsCodec (path </> "fpm.toml")
- librarySettingsM <- withCurrentDirectory path
- $ getLibrarySettings (tomlSettingsLibrary tomlSettings)
- case librarySettingsM of
- Just librarySettings -> do
- newDependencies <- fetchExecutableDependencies
- maybeProjectTree
- (tomlSettingsDependencies tomlSettings)
- return $ Dependency
- { dependencyName = name
- , dependencyPath = path
- , dependencySourcePath = path </> (librarySourceDir librarySettings)
- , dependencyBuildScript = libraryBuildScript librarySettings
- , dependencyDependencies = newDependencies
- }
- Nothing -> do
- putStrLn $ "No library found in " ++ name
- undefined
-
-fetchDependency :: String -> Version -> IO (String, FilePath)
-fetchDependency name version = do
- let clonePath = "build" </> "dependencies" </> name
- alreadyFetched <- doesDirectoryExist clonePath
- if alreadyFetched
- then return (name, clonePath)
- else case version of
- SimpleVersion _ -> do
- putStrLn "Simple dependencies are not yet supported :("
- undefined
- GitVersion versionSpec -> do
- system ("git init " ++ clonePath)
- case gitVersionSpecRef versionSpec of
- Just ref -> do
- system
- ( "git -C "
- ++ clonePath
- ++ " fetch "
- ++ gitVersionSpecUrl versionSpec
- ++ " "
- ++ (case ref of
- Tag tag -> tag
- Branch branch -> branch
- Commit commit -> commit
- )
- )
- Nothing -> do
- system
- ( "git -C "
- ++ clonePath
- ++ " fetch "
- ++ gitVersionSpecUrl versionSpec
- )
- system ("git -C " ++ clonePath ++ " checkout -qf FETCH_HEAD")
- return (name, clonePath)
- PathVersion versionSpec -> return (name, pathVersionSpecPath versionSpec)
-
-{-
- Bulding the dependencies is done on a depth first basis to ensure all of
- the transitive dependencies have been built before trying to build this one
--}
-buildDependencies
- :: String -> CompilerSettings -> [DependencyTree] -> IO [(FilePath, FilePath)]
-buildDependencies buildPrefix compilerSettings dependencies = do
- built <- concatMapM (buildDependency buildPrefix compilerSettings)
- dependencies
- return $ reverse (nub (reverse built))
-
-buildDependency
- :: String -> CompilerSettings -> DependencyTree -> IO [(FilePath, FilePath)]
-buildDependency buildPrefix compilerSettings (Dependency name path sourcePath mBuildScript dependencies)
- = do
- transitiveDependencies <- buildDependencies buildPrefix
- compilerSettings
- dependencies
- let buildPath = buildPrefix </> name
- thisArchive <- case mBuildScript of
- Just script -> buildWithScript script
- path
- buildPath
- compilerSettings
- name
- (map fst transitiveDependencies)
- Nothing -> buildLibrary sourcePath
- [".f90", ".f", ".F", ".F90", ".f95", ".f03"]
- buildPath
- compilerSettings
- name
- (map fst transitiveDependencies)
- return $ (buildPath, thisArchive) : transitiveDependencies
-
-createNewProject :: String -> Bool -> Bool -> Bool -> IO ()
-createNewProject projectName withExecutable withTest withLib = do
- createDirectory projectName
- writeFile (projectName </> "fpm.toml") (templateFpmToml projectName)
- writeFile (projectName </> "README.md") (templateReadme projectName)
- writeFile (projectName </> ".gitignore") "build/*\n"
- when withLib $ do
- createDirectory (projectName </> "src")
- writeFile (projectName </> "src" </> projectName <.> "f90")
- (templateModule projectName)
- when withExecutable $ do
- createDirectory (projectName </> "app")
- writeFile (projectName </> "app" </> "main.f90")
- (templateProgram projectName withLib)
- when withTest $ do
- createDirectory (projectName </> "test")
- writeFile (projectName </> "test" </> "main.f90") templateTest
- withCurrentDirectory projectName $ do
- system "git init"
- return ()
-
-templateFpmToml :: String -> String
-templateFpmToml projectName =
- "name = \""
- ++ projectName
- ++ "\"\n"
- ++ "version = \"0.1.0\"\n"
- ++ "license = \"license\"\n"
- ++ "author = \"Jane Doe\"\n"
- ++ "maintainer = \"jane.doe@example.com\"\n"
- ++ "copyright = \"2020 Jane Doe\"\n"
-
-templateModule :: String -> String
-templateModule projectName =
- "module "
- ++ projectName
- ++ "\n"
- ++ " implicit none\n"
- ++ " private\n"
- ++ "\n"
- ++ " public :: say_hello\n"
- ++ "contains\n"
- ++ " subroutine say_hello\n"
- ++ " print *, \"Hello, "
- ++ projectName
- ++ "!\"\n"
- ++ " end subroutine say_hello\n"
- ++ "end module "
- ++ projectName
- ++ "\n"
-
-templateReadme :: String -> String
-templateReadme projectName =
- "# " ++ projectName ++ "\n" ++ "\n" ++ "My cool new project!\n"
-
-templateProgram :: String -> Bool -> String
-templateProgram projectName withLib =
- "program main\n"
- ++ (if withLib then " use " ++ projectName ++ ", only: say_hello\n" else ""
- )
- ++ "\n"
- ++ " implicit none\n"
- ++ "\n"
- ++ " call say_hello\n"
- ++ "end program main\n"
-
-templateTest :: String
-templateTest =
- "program main\n"
- ++ " implicit none\n"
- ++ "\n"
- ++ " print *, \"Put some tests in here!\"\n"
- ++ "end program main\n"
diff --git a/bootstrap/stack.yaml b/bootstrap/stack.yaml
deleted file mode 100644
index 7147c40..0000000
--- a/bootstrap/stack.yaml
+++ /dev/null
@@ -1,74 +0,0 @@
-# This file was automatically generated by 'stack init'
-#
-# Some commonly used options have been documented as comments in this file.
-# For advanced use and comprehensive documentation of the format, please see:
-# https://docs.haskellstack.org/en/stable/yaml_configuration/
-
-# Resolver to choose a 'specific' stackage snapshot or a compiler version.
-# A snapshot resolver dictates the compiler version and the set of packages
-# to be used for project dependencies. For example:
-#
-# resolver: lts-3.5
-# resolver: nightly-2015-09-21
-# resolver: ghc-7.10.2
-#
-# The location of a snapshot can be provided as a file or url. Stack assumes
-# a snapshot provided as a file might change, whereas a url resource does not.
-#
-# resolver: ./custom-snapshot.yaml
-# resolver: https://example.com/snapshots/2018-01-01.yaml
-resolver: lts-14.27
-
-# User packages to be built.
-# Various formats can be used as shown in the example below.
-#
-# packages:
-# - some-directory
-# - https://example.com/foo/bar/baz-0.0.2.tar.gz
-# subdirs:
-# - auto-update
-# - wai
-packages:
-- .
-# Dependency packages to be pulled from upstream that are not in the resolver.
-# These entries can reference officially published versions as well as
-# forks / in-progress versions pinned to a git hash. For example:
-#
-# extra-deps:
-# - acme-missiles-0.3
-# - git: https://github.com/commercialhaskell/stack.git
-# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a
-#
-extra-deps:
-- git: https://github.com/kowainik/tomland.git
- commit: 536a5e6ffb148d0dd4e4c4b120913a6744097676
-- git: https://gitlab.com/everythingfunctional/hedge.git
- commit: 1c6cba3b5f8e52cf317f2421aaca13a0ddab4e92
- subdirs:
- - .
- - hedge-trimmer
-- quickcheck-with-counterexamples-1.2
-
-# Override default flag values for local packages and extra-deps
-# flags: {}
-
-# Extra package databases containing global packages
-# extra-package-dbs: []
-
-# Control whether we use the GHC we find on the path
-# system-ghc: true
-#
-# Require a specific version of stack, using version ranges
-# require-stack-version: -any # Default
-# require-stack-version: ">=2.1"
-#
-# Override the architecture used by stack, especially useful on Windows
-# arch: i386
-# arch: x86_64
-#
-# Extra directories used by stack for building
-# extra-include-dirs: [/path/to/dir]
-# extra-lib-dirs: [/path/to/dir]
-#
-# Allow a newer minor version of GHC than the snapshot specifies
-# compiler-check: newer-minor
diff --git a/bootstrap/stack.yaml.lock b/bootstrap/stack.yaml.lock
deleted file mode 100644
index 0ca18ae..0000000
--- a/bootstrap/stack.yaml.lock
+++ /dev/null
@@ -1,43 +0,0 @@
-# This file was autogenerated by Stack.
-# You should not edit this file by hand.
-# For more information, please see the documentation at:
-# https://docs.haskellstack.org/en/stable/lock_files
-
-packages:
-- completed:
- name: tomland
- version: 1.3.0.0
- git: https://github.com/kowainik/tomland.git
- pantry-tree:
- size: 5000
- sha256: 68d6f9a3e4c20cc4645374b30000017a75c4ab1c131590538edad2ea0e4a53bd
- commit: 536a5e6ffb148d0dd4e4c4b120913a6744097676
- original:
- git: https://github.com/kowainik/tomland.git
- commit: 536a5e6ffb148d0dd4e4c4b120913a6744097676
-- completed:
- subdir: hedge-trimmer
- name: hedge-trimmer
- version: 1.0.0.0
- git: https://gitlab.com/everythingfunctional/hedge.git
- pantry-tree:
- size: 226
- sha256: 19972f5b81c7627d6b66c852dfb7e0e67b3931ed4f418663c152717ce4ea267e
- commit: 1c6cba3b5f8e52cf317f2421aaca13a0ddab4e92
- original:
- subdir: hedge-trimmer
- git: https://gitlab.com/everythingfunctional/hedge.git
- commit: 1c6cba3b5f8e52cf317f2421aaca13a0ddab4e92
-- completed:
- hackage: quickcheck-with-counterexamples-1.2@sha256:d322d79008602df26f5eb4e1379e5b58bf1a92604df8601e71e200cfc3e847a3,1688
- pantry-tree:
- size: 724
- sha256: 0046517e3cc2adebfce19d4aad05a06dcf55ec9e572fa1c661ba9abe81386484
- original:
- hackage: quickcheck-with-counterexamples-1.2
-snapshots:
-- completed:
- size: 524996
- url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/14/27.yaml
- sha256: 7ea31a280c56bf36ff591a7397cc384d0dff622e7f9e4225b47d8980f019a0f0
- original: lts-14.27
diff --git a/bootstrap/test/Spec.hs b/bootstrap/test/Spec.hs
deleted file mode 100644
index 6e9daa2..0000000
--- a/bootstrap/test/Spec.hs
+++ /dev/null
@@ -1,103 +0,0 @@
-import Development.Shake.FilePath ( (</>) )
-import Fpm ( Arguments(..)
- , start
- )
-import System.Directory ( withCurrentDirectory )
-
-example_path = "test" </> "example_packages"
-
-main :: IO ()
-main = do
- testHelloWorld
- testHelloComplex
- testHelloFpm
- testCircular
- testWithMakefile
- testMakefileComplex
- testSubmodule
-
-testHelloWorld :: IO ()
-testHelloWorld =
- withCurrentDirectory (example_path </> "hello_world") $ start $ Run
- { runRelease = False
- , runExample = False
- , runCompiler = "gfortran"
- , runFlags = []
- , runRunner = Nothing
- , runTarget = Nothing
- , runArgs = Nothing
- }
-
-testHelloComplex :: IO ()
-testHelloComplex =
- withCurrentDirectory (example_path </> "hello_complex") $ start $ Test
- { testRelease = False
- , testCompiler = "gfortran"
- , testFlags = []
- , testRunner = Nothing
- , testTarget = Nothing
- , testArgs = Nothing
- }
-
-testHelloFpm :: IO ()
-testHelloFpm =
- withCurrentDirectory (example_path </> "hello_fpm") $ start $ Run
- { runRelease = False
- , runExample = False
- , runCompiler = "gfortran"
- , runFlags = []
- , runRunner = Nothing
- , runTarget = Nothing
- , runArgs = Nothing
- }
-
-testWithExamples :: IO ()
-testWithExamples =
- withCurrentDirectory (example_path </> "with_examples") $ start $ Run
- { runRelease = False
- , runExample = True
- , runCompiler = "gfortran"
- , runFlags = []
- , runRunner = Nothing
- , runTarget = Nothing
- , runArgs = Nothing
- }
-
-testCircular :: IO ()
-testCircular =
- withCurrentDirectory (example_path </> "circular_example") $ start $ Test
- { testRelease = False
- , testCompiler = "gfortran"
- , testFlags = []
- , testRunner = Nothing
- , testTarget = Nothing
- , testArgs = Nothing
- }
-
-testWithMakefile :: IO ()
-testWithMakefile =
- withCurrentDirectory (example_path </> "with_makefile") $ start $ Build
- { buildRelease = False
- , buildCompiler = "gfortran"
- , buildFlags = []
- }
-
-testMakefileComplex :: IO ()
-testMakefileComplex =
- withCurrentDirectory (example_path </> "makefile_complex") $ start $ Run
- { runRelease = False
- , runExample = False
- , runCompiler = "gfortran"
- , runFlags = []
- , runRunner = Nothing
- , runTarget = Nothing
- , runArgs = Nothing
- }
-
-testSubmodule :: IO ()
-testSubmodule =
- withCurrentDirectory (example_path </> "submodules") $ start $ Build
- { buildRelease = False
- , buildCompiler = "gfortran"
- , buildFlags = []
- }
diff --git a/bootstrap/test/example_packages b/bootstrap/test/example_packages
deleted file mode 120000
index b7c12dc..0000000
--- a/bootstrap/test/example_packages
+++ /dev/null
@@ -1 +0,0 @@
-../../example_packages \ No newline at end of file
diff --git a/bootstrap/unit_test/ModuleSourceConstructionTest.hs b/bootstrap/unit_test/ModuleSourceConstructionTest.hs
deleted file mode 100644
index b98e9d3..0000000
--- a/bootstrap/unit_test/ModuleSourceConstructionTest.hs
+++ /dev/null
@@ -1,83 +0,0 @@
-module ModuleSourceConstructionTest
- ( test
- )
-where
-
-import BuildModel ( RawSource(..)
- , Source(..)
- , processRawSource
- )
-import Hedge ( Result
- , Test
- , assertEquals
- , assertThat
- , fail'
- , givenInput
- , then'
- , whenTransformed
- )
-import System.FilePath ( (</>) )
-
-test :: IO (Test ())
-test = return $ givenInput
- "a module"
- exampleModule
- [ whenTransformed
- "processed to a source"
- processRawSource
- [ then' "it is a Module" checkIsModule
- , then' "its source file name is the same as the original"
- checkModuleSourceFileName
- , then'
- "its object file name is the 'flattened' path of the source file with '.o' appeneded"
- checkModuleObjectFileName
- , then' "it knows what modules it uses directly" checkModuleModulesUsed
- , then' "it knows its name" checkModuleName
- , then' "it can tell that it will produce a '.smod' file" checkSmod
- ]
- ]
-
-exampleModule :: RawSource
-exampleModule = RawSource moduleSourceFileName' $ unlines
- [ "module some_module"
- , " use module1"
- , " USE MODULE2"
- , " implicit none"
- , " interface"
- , " pure module function some_func()"
- , " integer :: some_func"
- , " end function"
- , " end interface"
- , "end module"
- ]
-
-moduleSourceFileName' :: String
-moduleSourceFileName' = "some" </> "file" </> "somewhere.f90"
-
-checkIsModule :: Source -> Result
-checkIsModule Module{} = assertThat True
-checkIsModule _ = assertThat False
-
-checkModuleSourceFileName :: Source -> Result
-checkModuleSourceFileName m@(Module{}) =
- assertEquals moduleSourceFileName' $ moduleSourceFileName m
-checkModuleSourceFileName _ = fail' "wasn't a Module"
-
-checkModuleObjectFileName :: Source -> Result
-checkModuleObjectFileName m@(Module{}) =
- assertEquals ("." </> "some_file_somewhere.f90.o")
- $ (moduleObjectFileName m) "."
-checkModuleObjectFileName _ = fail' "wasn't a Module"
-
-checkModuleModulesUsed :: Source -> Result
-checkModuleModulesUsed m@(Module{}) =
- assertEquals ["module1", "module2"] $ moduleModulesUsed m
-checkModuleModulesUsed _ = fail' "wasn't a Module"
-
-checkModuleName :: Source -> Result
-checkModuleName m@(Module{}) = assertEquals "some_module" $ moduleName m
-checkModuleName _ = fail' "wasn't a Module"
-
-checkSmod :: Source -> Result
-checkSmod m@(Module{}) = assertThat $ moduleProducesSmod m
-checkSmod _ = fail' "wasn't a Module"
diff --git a/bootstrap/unit_test/ModuleToCompileInfoTest.hs b/bootstrap/unit_test/ModuleToCompileInfoTest.hs
deleted file mode 100644
index 08cd67c..0000000
--- a/bootstrap/unit_test/ModuleToCompileInfoTest.hs
+++ /dev/null
@@ -1,73 +0,0 @@
-module ModuleToCompileInfoTest
- ( test
- )
-where
-
-import BuildModel ( AvailableModule(..)
- , CompileTimeInfo(..)
- , Source(..)
- , constructCompileTimeInfo
- )
-import Hedge ( Result
- , Test
- , assertEquals
- , givenInput
- , then'
- , whenTransformed
- )
-import System.FilePath ( (</>) )
-
-test :: IO (Test ())
-test = return $ givenInput
- "a module and available modules"
- (exampleModule, availableModules)
- [ whenTransformed
- "its compileTimeInfo is determined"
- doCompileTimeTransformation
- [ then' "it stil knows the original source file" checkSourceFileName
- , then' "it knows what object file will be produced" checkObjectFileName
- , then' "the mod and smod files are also produced" checkOtherFilesProduced
- , then' "the direct dependencies are only the available modules used"
- checkDirectDependencies
- ]
- ]
-
-exampleModule :: Source
-exampleModule = Module
- { moduleSourceFileName = moduleSourceFileName'
- , moduleObjectFileName = \bd -> bd </> "some_file_somewhere.f90.o"
- , moduleModulesUsed = ["module1", "module2", "module3"]
- , moduleName = "some_module"
- , moduleProducesSmod = True
- }
-
-moduleSourceFileName' :: FilePath
-moduleSourceFileName' = "some" </> "file" </> "somewhere.f90"
-
-availableModules :: [AvailableModule]
-availableModules = [ AvailableModule {availableModuleName = "module1", availableModuleFile = "build_dir" </> "module1.mod"}
- , AvailableModule {availableModuleName = "module3", availableModuleFile = "build_dir" </> "module3.mod"}
- ]
-
-doCompileTimeTransformation :: (Source, [AvailableModule]) -> CompileTimeInfo
-doCompileTimeTransformation (programSource, otherSources) =
- constructCompileTimeInfo programSource otherSources "build_dir"
-
-checkSourceFileName :: CompileTimeInfo -> Result
-checkSourceFileName cti =
- assertEquals moduleSourceFileName' (compileTimeInfoSourceFileName cti)
-
-checkObjectFileName :: CompileTimeInfo -> Result
-checkObjectFileName cti = assertEquals
- ("build_dir" </> "some_file_somewhere.f90.o")
- (compileTimeInfoObjectFileProduced cti)
-
-checkOtherFilesProduced :: CompileTimeInfo -> Result
-checkOtherFilesProduced cti = assertEquals
- ["build_dir" </> "some_module.mod", "build_dir" </> "some_module.smod"]
- (compileTimeInfoOtherFilesProduced cti)
-
-checkDirectDependencies :: CompileTimeInfo -> Result
-checkDirectDependencies cti = assertEquals
- ["build_dir" </> "module1.mod", "build_dir" </> "module3.mod"]
- (compileTimeInfoDirectDependencies cti)
diff --git a/bootstrap/unit_test/ProgramSourceConstructionTest.hs b/bootstrap/unit_test/ProgramSourceConstructionTest.hs
deleted file mode 100644
index 6369965..0000000
--- a/bootstrap/unit_test/ProgramSourceConstructionTest.hs
+++ /dev/null
@@ -1,69 +0,0 @@
-module ProgramSourceConstructionTest
- ( test
- )
-where
-
-import BuildModel ( RawSource(..)
- , Source(..)
- , processRawSource
- )
-import Hedge ( Result
- , Test
- , assertEquals
- , assertThat
- , fail'
- , givenInput
- , then'
- , whenTransformed
- )
-import System.FilePath ( (</>) )
-
-test :: IO (Test ())
-test = return $ givenInput
- "a program"
- exampleProgram
- [ whenTransformed
- "processed to a source"
- processRawSource
- [ then' "it is a Program" checkIsProgram
- , then' "its source file name is the same as the original"
- checkProgramSourceFileName
- , then'
- "its object file name is the 'flattened' path of the source file with '.o' appended"
- checkProgramObjectFileName
- , then' "it knows what modules it uses directly" checkProgramModulesUsed
- ]
- ]
-
-exampleProgram :: RawSource
-exampleProgram = RawSource programSourceFileName' $ unlines
- [ "program some_program"
- , " use module1"
- , " USE MODULE2"
- , " implicit none"
- , " print *, \"Hello, World!\""
- , "end program"
- ]
-
-programSourceFileName' :: String
-programSourceFileName' = "some" </> "file" </> "somewhere.f90"
-
-checkIsProgram :: Source -> Result
-checkIsProgram Program{} = assertThat True
-checkIsProgram _ = assertThat False
-
-checkProgramSourceFileName :: Source -> Result
-checkProgramSourceFileName p@(Program{}) =
- assertEquals programSourceFileName' $ programSourceFileName p
-checkProgramSourceFileName _ = fail' "wasn't a Program"
-
-checkProgramObjectFileName :: Source -> Result
-checkProgramObjectFileName p@(Program{}) =
- assertEquals ("." </> "some_file_somewhere.f90.o")
- $ (programObjectFileName p) "."
-checkProgramObjectFileName _ = fail' "wasn't a Program"
-
-checkProgramModulesUsed :: Source -> Result
-checkProgramModulesUsed p@(Program{}) =
- assertEquals ["module1", "module2"] $ programModulesUsed p
-checkProgramModulesUsed _ = fail' "wasn't a Program"
diff --git a/bootstrap/unit_test/ProgramToCompileInfoTest.hs b/bootstrap/unit_test/ProgramToCompileInfoTest.hs
deleted file mode 100644
index a9ad39b..0000000
--- a/bootstrap/unit_test/ProgramToCompileInfoTest.hs
+++ /dev/null
@@ -1,71 +0,0 @@
-module ProgramToCompileInfoTest
- ( test
- )
-where
-
-import BuildModel ( AvailableModule(..)
- , CompileTimeInfo(..)
- , Source(..)
- , constructCompileTimeInfo
- )
-import Hedge ( Result
- , Test
- , assertEmpty
- , assertEquals
- , givenInput
- , then'
- , whenTransformed
- )
-import System.FilePath ( (</>) )
-
-test :: IO (Test ())
-test = return $ givenInput
- "a program and available modules"
- (exampleProgram, availableModules)
- [ whenTransformed
- "its compileTimeInfo is determined"
- doCompileTimeTransformation
- [ then' "it still knows the original source file" checkSourceFileName
- , then' "it knows what object file will be produced" checkObjectFileName
- , then' "there are no other files produced" checkOtherFilesProduced
- , then' "the direct dependencies are only the available modules used"
- checkDirectDependencies
- ]
- ]
-
-exampleProgram :: Source
-exampleProgram = Program
- { programSourceFileName = programSourceFileName'
- , programObjectFileName = \bd -> bd </> "some_file_somewhere.f90.o"
- , programModulesUsed = ["module1", "module2", "module3"]
- }
-
-programSourceFileName' :: FilePath
-programSourceFileName' = "some" </> "file" </> "somewhere.f90"
-
-availableModules :: [AvailableModule]
-availableModules = [ AvailableModule {availableModuleName = "module1", availableModuleFile = "build_dir" </> "module1.mod"}
- , AvailableModule {availableModuleName = "module3", availableModuleFile = "build_dir" </> "module3.mod"}
- ]
-
-doCompileTimeTransformation :: (Source, [AvailableModule]) -> CompileTimeInfo
-doCompileTimeTransformation (programSource, otherSources) =
- constructCompileTimeInfo programSource otherSources "build_dir"
-
-checkSourceFileName :: CompileTimeInfo -> Result
-checkSourceFileName cti =
- assertEquals programSourceFileName' (compileTimeInfoSourceFileName cti)
-
-checkObjectFileName :: CompileTimeInfo -> Result
-checkObjectFileName cti = assertEquals
- ("build_dir" </> "some_file_somewhere.f90.o")
- (compileTimeInfoObjectFileProduced cti)
-
-checkOtherFilesProduced :: CompileTimeInfo -> Result
-checkOtherFilesProduced cti =
- assertEmpty (compileTimeInfoOtherFilesProduced cti)
-
-checkDirectDependencies :: CompileTimeInfo -> Result
-checkDirectDependencies cti = assertEquals
- ["build_dir" </> "module1.mod", "build_dir" </> "module3.mod"]
- (compileTimeInfoDirectDependencies cti)
diff --git a/bootstrap/unit_test/SubmoduleSourceConstructionTest.hs b/bootstrap/unit_test/SubmoduleSourceConstructionTest.hs
deleted file mode 100644
index d07a6ed..0000000
--- a/bootstrap/unit_test/SubmoduleSourceConstructionTest.hs
+++ /dev/null
@@ -1,79 +0,0 @@
-module SubmoduleSourceConstructionTest
- ( test
- )
-where
-
-import BuildModel ( RawSource(..)
- , Source(..)
- , processRawSource
- )
-import Hedge ( Result
- , Test
- , assertEquals
- , assertThat
- , fail'
- , givenInput
- , then'
- , whenTransformed
- )
-import System.FilePath ( (</>) )
-
-test :: IO (Test ())
-test = return $ givenInput
- "a submodule"
- exampleSubmodule
- [ whenTransformed
- "processed to a source"
- processRawSource
- [ then' "it is a Submodule" checkIsSubmodule
- , then' "its source file name is the same as the original"
- checkSubmoduleSourceFileName
- , then'
- "its object file name is the 'flattened' path of the source file with '.o' appeneded"
- checkSubmoduleObjectFileName
- , then' "it knows what modules it uses directly" checkSubmoduleModulesUsed
- , then' "it knows its parent's name" checkSubmoduleParentName
- , then' "it knows its name" checkSubmoduleName
- ]
- ]
-
-exampleSubmodule :: RawSource
-exampleSubmodule = RawSource submoduleSourceFileName' $ unlines
- [ "submodule (some_module:parent) child"
- , " use module1"
- , " USE MODULE2"
- , " implicit none"
- , "end submodule"
- ]
-
-submoduleSourceFileName' :: String
-submoduleSourceFileName' = "some" </> "file" </> "somewhere.f90"
-
-checkIsSubmodule :: Source -> Result
-checkIsSubmodule Submodule{} = assertThat True
-checkIsSubmodule _ = assertThat False
-
-checkSubmoduleSourceFileName :: Source -> Result
-checkSubmoduleSourceFileName s@(Submodule{}) =
- assertEquals submoduleSourceFileName' $ submoduleSourceFileName s
-checkSubmoduleSourceFileName _ = fail' "wasn't a Submodule"
-
-checkSubmoduleObjectFileName :: Source -> Result
-checkSubmoduleObjectFileName s@(Submodule{}) =
- assertEquals ("." </> "some_file_somewhere.f90.o")
- $ (submoduleObjectFileName s) "."
-checkSubmoduleObjectFileName _ = fail' "wasn't a Submodule"
-
-checkSubmoduleModulesUsed :: Source -> Result
-checkSubmoduleModulesUsed s@(Submodule{}) =
- assertEquals ["module1", "module2"] $ submoduleModulesUsed s
-checkSubmoduleModulesUsed _ = fail' "wasn't a Submodule"
-
-checkSubmoduleParentName :: Source -> Result
-checkSubmoduleParentName s@(Submodule{}) =
- assertEquals "some_module@parent" (submoduleParentName s)
-checkSubmoduleParentName _ = fail' "wasn't a Submodule"
-
-checkSubmoduleName :: Source -> Result
-checkSubmoduleName s@(Submodule{}) = assertEquals "child" $ submoduleName s
-checkSubmoduleName _ = fail' "wasn't a Submodule"
diff --git a/bootstrap/unit_test/SubmoduleToCompileInfoTest.hs b/bootstrap/unit_test/SubmoduleToCompileInfoTest.hs
deleted file mode 100644
index 621b0d5..0000000
--- a/bootstrap/unit_test/SubmoduleToCompileInfoTest.hs
+++ /dev/null
@@ -1,78 +0,0 @@
-module SubmoduleToCompileInfoTest
- ( test
- )
-where
-
-import BuildModel ( AvailableModule(..)
- , CompileTimeInfo(..)
- , Source(..)
- , constructCompileTimeInfo
- )
-import Hedge ( Result
- , Test
- , assertEquals
- , givenInput
- , then'
- , whenTransformed
- )
-import System.FilePath ( (</>) )
-
-test :: IO (Test ())
-test = return $ givenInput
- "a submodule and available modules"
- (exampleSubmodule, availableModules)
- [ whenTransformed
- "its compileTimeInfo is determined"
- doCompileTimeTransformation
- [ then' "it still knows the original source file" checkSourceFileName
- , then' "it knows what object file will be produced" checkObjectFileName
- , then' "the smod file is also produced" checkOtherFilesProduced
- , then'
- "the direct dependencies are the parent smod and the available modules used"
- checkDirectDependencies
- ]
- ]
-
-exampleSubmodule :: Source
-exampleSubmodule = Submodule
- { submoduleSourceFileName = submoduleSourceFileName'
- , submoduleObjectFileName = \bd -> bd </> "some_file_somewhere.f90.o"
- , submoduleModulesUsed = ["module1", "module2", "module3"]
- , submoduleBaseModuleName = "base_module"
- , submoduleParentName = "base_module@parent"
- , submoduleName = "some_submodule"
- }
-
-submoduleSourceFileName' :: FilePath
-submoduleSourceFileName' = "some" </> "file" </> "somewhere.f90"
-
-availableModules :: [AvailableModule]
-availableModules = [ AvailableModule {availableModuleName = "module1", availableModuleFile = "build_dir" </> "module1.mod"}
- , AvailableModule {availableModuleName = "module3", availableModuleFile = "build_dir" </> "module3.mod"}
- ]
-
-doCompileTimeTransformation :: (Source, [AvailableModule]) -> CompileTimeInfo
-doCompileTimeTransformation (programSource, otherSources) =
- constructCompileTimeInfo programSource otherSources "build_dir"
-
-checkSourceFileName :: CompileTimeInfo -> Result
-checkSourceFileName cti =
- assertEquals submoduleSourceFileName' (compileTimeInfoSourceFileName cti)
-
-checkObjectFileName :: CompileTimeInfo -> Result
-checkObjectFileName cti = assertEquals
- ("build_dir" </> "some_file_somewhere.f90.o")
- (compileTimeInfoObjectFileProduced cti)
-
-checkOtherFilesProduced :: CompileTimeInfo -> Result
-checkOtherFilesProduced cti = assertEquals
- ["build_dir" </> "base_module@some_submodule.smod"]
- (compileTimeInfoOtherFilesProduced cti)
-
-checkDirectDependencies :: CompileTimeInfo -> Result
-checkDirectDependencies cti = assertEquals
- [ "build_dir" </> "base_module@parent.smod"
- , "build_dir" </> "module1.mod"
- , "build_dir" </> "module3.mod"
- ]
- (compileTimeInfoDirectDependencies cti)
diff --git a/bootstrap/unit_test/Trimmer.hs b/bootstrap/unit_test/Trimmer.hs
deleted file mode 100644
index 4e0f91d..0000000
--- a/bootstrap/unit_test/Trimmer.hs
+++ /dev/null
@@ -1 +0,0 @@
-{-# OPTIONS_GHC -F -pgmF hedge-trimmer #-}
diff --git a/docs.md b/docs.md
index 2ffa611..218367c 100644
--- a/docs.md
+++ b/docs.md
@@ -9,12 +9,12 @@ author_email: fortran-lang@groups.io
github: https://github.com/fortran-lang
twitter: https://twitter.com/fortranlang
website: https://fortran-lang.org
-src_dir: ./fpm/src
+src_dir: ./src
+ ./app
output_dir: ./fpm-doc
page_dir: ./doc
media_dir: ./doc/media
-exclude_dir: ./bootstrap
- ./archive
+exclude_dir: ./example_packages
./test
display: public
protected
diff --git a/fpm/fpm.toml b/fpm.toml
index 4bd2d96..4bd2d96 100644
--- a/fpm/fpm.toml
+++ b/fpm.toml
diff --git a/fpm/.gitignore b/fpm/.gitignore
deleted file mode 100644
index a007fea..0000000
--- a/fpm/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-build/*
diff --git a/fpm/README.md b/fpm/README.md
deleted file mode 100644
index d993787..0000000
--- a/fpm/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Fortran Package Manager
-
-This is the Fortran Package Manager, implemented in Fortran as an fpm package.
-Use fpm to build it.
diff --git a/install.sh b/install.sh
index de2aaa8..7f3908b 100755
--- a/install.sh
+++ b/install.sh
@@ -7,33 +7,18 @@ usage()
echo "Fortran Package Manager Bootstrap Script"
echo ""
echo "USAGE:"
- echo "./install.sh [--help | [--prefix=PREFIX] [--update[=REF]]"
- echo " [--no-openmp] [--static] [--haskell] ]"
+ echo "./install.sh [--help | [--prefix=PREFIX]"
echo ""
echo " --help Display this help text"
echo " --prefix=PREFIX Install binary in 'PREFIX/bin'"
echo " Default prefix='\$HOME/.local/bin'"
- echo " --update[=REF] Update repository from latest release tag"
- echo " or from git reference REF if specified"
- echo " --no-openmp Don't build fpm with openmp support"
- echo " --static Statically link fpm executable"
- echo " (implies --no-openmp)"
- echo " --haskell Only install Haskell fpm"
echo ""
- echo " '--no-openmp' and '--static' do not affect the Haskell fpm"
- echo " build."
+ echo "FC and FFLAGS environment variables can be used to select the"
+ echo "Fortran compiler and the build flags."
echo ""
}
PREFIX="$HOME/.local"
-UPDATE=false
-OMP=true
-STATIC=false
-HASKELL_ONLY=false
-
-STACK_BIN_PATH="$HOME/.local/bin"
-REF=$(git describe --tag --abbrev=0)
-RELEASE_FLAGS="--flag -g --flag -fbacktrace --flag -O3"
while [ "$1" != "" ]; do
PARAM=$(echo "$1" | awk -F= '{print $1}')
@@ -46,22 +31,6 @@ while [ "$1" != "" ]; do
--prefix)
PREFIX=$VALUE
;;
- --update)
- UPDATE=true
- if [ "$VALUE" != "" ]; then
- REF=$VALUE
- fi
- ;;
- --no-openmp)
- OMP=false
- ;;
- --static)
- STATIC=true
- OMP=false
- ;;
- --haskell)
- HASKELL_ONLY=true
- ;;
*)
echo "ERROR: unknown parameter \"$PARAM\""
usage
@@ -73,59 +42,18 @@ done
set -u # error on use of undefined variable
-INSTALL_PATH="$PREFIX/bin"
-
-if command -v stack 1> /dev/null 2>&1 ; then
- echo "Found stack"
-else
- echo "Haskell stack not found."
- echo "Installing Haskell stack"
- curl -sSL https://get.haskellstack.org/ | sh
- if command -v stack 1> /dev/null 2>&1 ; then
- echo "Haskell stack installation successful."
- else
- echo "ERROR: Haskell stack installation unsuccessful."
- exit 1
- fi
+SOURCE_URL="https://github.com/fortran-lang/fpm/releases/download/v0.2.0/fpm-0.2.0.f90"
+BOOTSTRAP_DIR="build/bootstrap"
+if [ -z ${FC+x} ]; then
+ FC="gfortran"
fi
-
-if [ -x "$INSTALL_PATH/fpm" ]; then
- echo "Overwriting existing fpm installation in $INSTALL_PATH"
+if [ -z ${FFLAGS+x} ]; then
+ FFLAGS="-g -fbacktrace -O3"
fi
-if [ "$UPDATE" = true ]; then
- git checkout "$REF"
- if [ $? != 0 ]; then
- echo "ERROR: Unable to checkout $REF."
- exit 1
- fi
-fi
+mkdir -p $BOOTSTRAP_DIR
+curl -LJ $SOURCE_URL > $BOOTSTRAP_DIR/fpm.f90
+$FC $FFLAGS -J $BOOTSTRAP_DIR $BOOTSTRAP_DIR/fpm.f90 -o $BOOTSTRAP_DIR/fpm
-cd bootstrap
-stack install
-
-if [ "$STACK_BIN_PATH" != "$INSTALL_PATH" ]; then
- mv "$STACK_BIN_PATH/fpm" "$INSTALL_PATH/"
-fi
-
-if [ "$HASKELL_ONLY" = true ]; then
- exit
-fi
-
-if [ "$STATIC" = true ]; then
- RELEASE_FLAGS="$RELEASE_FLAGS --flag -static"
-fi
-
-if [ "$OMP" = true ]; then
- RELEASE_FLAGS="$RELEASE_FLAGS --flag -fopenmp"
-fi
-
-cd ../fpm
-"$INSTALL_PATH/fpm" run $RELEASE_FLAGS --runner mv -- "$INSTALL_PATH/"
-
-if [ -x "$INSTALL_PATH/fpm" ]; then
- echo "fpm installed successfully to $INSTALL_PATH"
-else
- echo "ERROR: fpm installation unsuccessful: fpm not found in $INSTALL_PATH"
- exit 1
-fi
+$BOOTSTRAP_DIR/fpm install --compiler "$FC" --flag "$FFLAGS" --prefix "$PREFIX"
+rm -r $BOOTSTRAP_DIR
diff --git a/manifest-reference.md b/manifest-reference.md
index b40eef8..1a33dc1 100644
--- a/manifest-reference.md
+++ b/manifest-reference.md
@@ -217,27 +217,6 @@ include-dir = ["include", "third_party/include"]
> *include-dir* does not currently allow using pre-built module `.mod` files
-#### Custom build script
-
-> Supported in Bootstrap fpm only
-
-Projects with custom build scripts can specify those in the *build-script* entry.
-The custom build script will be executed when the library build step is reached.
-
-*Example:*
-
-```toml
-[library]
-build-script = "build.sh"
-```
-
-Build scripts written in ``make`` are automatically detected and executed with ``make``
-
-```toml
-[library]
-build-script = "Makefile"
-```
-
### Executable targets
diff --git a/fpm/src/fpm.f90 b/src/fpm.f90
index 31b68ff..31b68ff 100644
--- a/fpm/src/fpm.f90
+++ b/src/fpm.f90
diff --git a/fpm/src/fpm/cmd/install.f90 b/src/fpm/cmd/install.f90
index db7a9f8..db7a9f8 100644
--- a/fpm/src/fpm/cmd/install.f90
+++ b/src/fpm/cmd/install.f90
diff --git a/fpm/src/fpm/cmd/new.f90 b/src/fpm/cmd/new.f90
index 5149bea..5149bea 100644
--- a/fpm/src/fpm/cmd/new.f90
+++ b/src/fpm/cmd/new.f90
diff --git a/fpm/src/fpm/cmd/update.f90 b/src/fpm/cmd/update.f90
index d7cc549..d7cc549 100644
--- a/fpm/src/fpm/cmd/update.f90
+++ b/src/fpm/cmd/update.f90
diff --git a/fpm/src/fpm/dependency.f90 b/src/fpm/dependency.f90
index 144ffbe..144ffbe 100644
--- a/fpm/src/fpm/dependency.f90
+++ b/src/fpm/dependency.f90
diff --git a/fpm/src/fpm/error.f90 b/src/fpm/error.f90
index e69ff1e..e69ff1e 100644
--- a/fpm/src/fpm/error.f90
+++ b/src/fpm/error.f90
diff --git a/fpm/src/fpm/git.f90 b/src/fpm/git.f90
index 08e27b2..08e27b2 100644
--- a/fpm/src/fpm/git.f90
+++ b/src/fpm/git.f90
diff --git a/fpm/src/fpm/installer.f90 b/src/fpm/installer.f90
index d01bd27..d01bd27 100644
--- a/fpm/src/fpm/installer.f90
+++ b/src/fpm/installer.f90
diff --git a/fpm/src/fpm/manifest.f90 b/src/fpm/manifest.f90
index 4170b91..4170b91 100644
--- a/fpm/src/fpm/manifest.f90
+++ b/src/fpm/manifest.f90
diff --git a/fpm/src/fpm/manifest/build.f90 b/src/fpm/manifest/build.f90
index d96974f..d96974f 100644
--- a/fpm/src/fpm/manifest/build.f90
+++ b/src/fpm/manifest/build.f90
diff --git a/fpm/src/fpm/manifest/dependency.f90 b/src/fpm/manifest/dependency.f90
index 26b76ee..26b76ee 100644
--- a/fpm/src/fpm/manifest/dependency.f90
+++ b/src/fpm/manifest/dependency.f90
diff --git a/fpm/src/fpm/manifest/example.f90 b/src/fpm/manifest/example.f90
index fc2a0af..fc2a0af 100644
--- a/fpm/src/fpm/manifest/example.f90
+++ b/src/fpm/manifest/example.f90
diff --git a/fpm/src/fpm/manifest/executable.f90 b/src/fpm/manifest/executable.f90
index be02974..be02974 100644
--- a/fpm/src/fpm/manifest/executable.f90
+++ b/src/fpm/manifest/executable.f90
diff --git a/fpm/src/fpm/manifest/install.f90 b/src/fpm/manifest/install.f90
index 6175873..6175873 100644
--- a/fpm/src/fpm/manifest/install.f90
+++ b/src/fpm/manifest/install.f90
diff --git a/fpm/src/fpm/manifest/library.f90 b/src/fpm/manifest/library.f90
index c8ce049..c8ce049 100644
--- a/fpm/src/fpm/manifest/library.f90
+++ b/src/fpm/manifest/library.f90
diff --git a/fpm/src/fpm/manifest/package.f90 b/src/fpm/manifest/package.f90
index bbaa51d..bbaa51d 100644
--- a/fpm/src/fpm/manifest/package.f90
+++ b/src/fpm/manifest/package.f90
diff --git a/fpm/src/fpm/manifest/test.f90 b/src/fpm/manifest/test.f90
index bcacbd8..bcacbd8 100644
--- a/fpm/src/fpm/manifest/test.f90
+++ b/src/fpm/manifest/test.f90
diff --git a/fpm/src/fpm/toml.f90 b/src/fpm/toml.f90
index dbaafcb..dbaafcb 100644
--- a/fpm/src/fpm/toml.f90
+++ b/src/fpm/toml.f90
diff --git a/fpm/src/fpm/versioning.f90 b/src/fpm/versioning.f90
index b24fc3c..b24fc3c 100644
--- a/fpm/src/fpm/versioning.f90
+++ b/src/fpm/versioning.f90
diff --git a/fpm/src/fpm_backend.f90 b/src/fpm_backend.f90
index 74cef61..74cef61 100644
--- a/fpm/src/fpm_backend.f90
+++ b/src/fpm_backend.f90
diff --git a/fpm/src/fpm_command_line.f90 b/src/fpm_command_line.f90
index 9e9a572..9e9a572 100644
--- a/fpm/src/fpm_command_line.f90
+++ b/src/fpm_command_line.f90
diff --git a/fpm/src/fpm_compiler.f90 b/src/fpm_compiler.f90
index 51cda20..51cda20 100644
--- a/fpm/src/fpm_compiler.f90
+++ b/src/fpm_compiler.f90
diff --git a/fpm/src/fpm_environment.f90 b/src/fpm_environment.f90
index 0408ec4..0408ec4 100644
--- a/fpm/src/fpm_environment.f90
+++ b/src/fpm_environment.f90
diff --git a/fpm/src/fpm_filesystem.f90 b/src/fpm_filesystem.f90
index 6acd383..6acd383 100644
--- a/fpm/src/fpm_filesystem.f90
+++ b/src/fpm_filesystem.f90
diff --git a/fpm/src/fpm_model.f90 b/src/fpm_model.f90
index bfb0115..bfb0115 100644
--- a/fpm/src/fpm_model.f90
+++ b/src/fpm_model.f90
diff --git a/fpm/src/fpm_source_parsing.f90 b/src/fpm_source_parsing.f90
index dd9a4c5..dd9a4c5 100644
--- a/fpm/src/fpm_source_parsing.f90
+++ b/src/fpm_source_parsing.f90
diff --git a/fpm/src/fpm_sources.f90 b/src/fpm_sources.f90
index c781535..c781535 100644
--- a/fpm/src/fpm_sources.f90
+++ b/src/fpm_sources.f90
diff --git a/fpm/src/fpm_strings.f90 b/src/fpm_strings.f90
index 3d7d7b1..3d7d7b1 100644
--- a/fpm/src/fpm_strings.f90
+++ b/src/fpm_strings.f90
diff --git a/fpm/src/fpm_targets.f90 b/src/fpm_targets.f90
index 02bb600..02bb600 100644
--- a/fpm/src/fpm_targets.f90
+++ b/src/fpm_targets.f90
diff --git a/fpm/test/cli_test/cli_test.f90 b/test/cli_test/cli_test.f90
index d979f1a..d979f1a 100644
--- a/fpm/test/cli_test/cli_test.f90
+++ b/test/cli_test/cli_test.f90
diff --git a/fpm/test/fpm_test/main.f90 b/test/fpm_test/main.f90
index 0a65307..0a65307 100644
--- a/fpm/test/fpm_test/main.f90
+++ b/test/fpm_test/main.f90
diff --git a/fpm/test/fpm_test/test_backend.f90 b/test/fpm_test/test_backend.f90
index 662e470..662e470 100644
--- a/fpm/test/fpm_test/test_backend.f90
+++ b/test/fpm_test/test_backend.f90
diff --git a/fpm/test/fpm_test/test_filesystem.f90 b/test/fpm_test/test_filesystem.f90
index 5a7e18a..5a7e18a 100644
--- a/fpm/test/fpm_test/test_filesystem.f90
+++ b/test/fpm_test/test_filesystem.f90
diff --git a/fpm/test/fpm_test/test_installer.f90 b/test/fpm_test/test_installer.f90
index 1235ba5..1235ba5 100644
--- a/fpm/test/fpm_test/test_installer.f90
+++ b/test/fpm_test/test_installer.f90
diff --git a/fpm/test/fpm_test/test_manifest.f90 b/test/fpm_test/test_manifest.f90
index 94e5e07..94e5e07 100644
--- a/fpm/test/fpm_test/test_manifest.f90
+++ b/test/fpm_test/test_manifest.f90
diff --git a/fpm/test/fpm_test/test_module_dependencies.f90 b/test/fpm_test/test_module_dependencies.f90
index f193646..f193646 100644
--- a/fpm/test/fpm_test/test_module_dependencies.f90
+++ b/test/fpm_test/test_module_dependencies.f90
diff --git a/fpm/test/fpm_test/test_package_dependencies.f90 b/test/fpm_test/test_package_dependencies.f90
index b70ac13..b70ac13 100644
--- a/fpm/test/fpm_test/test_package_dependencies.f90
+++ b/test/fpm_test/test_package_dependencies.f90
diff --git a/fpm/test/fpm_test/test_source_parsing.f90 b/test/fpm_test/test_source_parsing.f90
index 79a4d7a..79a4d7a 100644
--- a/fpm/test/fpm_test/test_source_parsing.f90
+++ b/test/fpm_test/test_source_parsing.f90
diff --git a/fpm/test/fpm_test/test_toml.f90 b/test/fpm_test/test_toml.f90
index ba48307..ba48307 100644
--- a/fpm/test/fpm_test/test_toml.f90
+++ b/test/fpm_test/test_toml.f90
diff --git a/fpm/test/fpm_test/test_versioning.f90 b/test/fpm_test/test_versioning.f90
index f6dcb57..f6dcb57 100644
--- a/fpm/test/fpm_test/test_versioning.f90
+++ b/test/fpm_test/test_versioning.f90
diff --git a/fpm/test/fpm_test/testsuite.f90 b/test/fpm_test/testsuite.f90
index 124d19a..124d19a 100644
--- a/fpm/test/fpm_test/testsuite.f90
+++ b/test/fpm_test/testsuite.f90
diff --git a/fpm/test/help_test/help_test.f90 b/test/help_test/help_test.f90
index 8f0c455..8f0c455 100644
--- a/fpm/test/help_test/help_test.f90
+++ b/test/help_test/help_test.f90
diff --git a/fpm/test/new_test/new_test.f90 b/test/new_test/new_test.f90
index 3c8c453..3c8c453 100644
--- a/fpm/test/new_test/new_test.f90
+++ b/test/new_test/new_test.f90