# FPM: Platform-specific instructions to linker on fpm.toml

**URL:** <https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296>\
**Category:** fpm\
**Created:** [January 30, 2024, 8:34am UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296 "2024-01-30T08:34:04Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![amasaki203](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/amasaki203/32/2730_2.png) [@amasaki203](https://fortran-lang.discourse.group/u/amasaki203)\
**Post date:** [January 30, 2024, 8:34am UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/1 "2024-01-30T08:34:04Z")

</div>

Hi.

I’m using fpm v0.10.0 and writing code that utilizes C interoperability to use OS APIs. To support cross-platform compatibility, I’m switching build code using preprocessor directives, which works fine in general. However, I’ve noticed that I need to add specific instructions to the linker only for Windows.

I attempt to address this in the `fpm.toml` file with the following:

```toml
[build]
auto-executables = true
auto-tests = true
auto-examples = true
module-naming = false
link = ["iphlpapi", "ws2_32"]

```

Specifically, adding `link = ["iphlpapi", "ws2_32"]` to `fpm.toml` for successful Windows builds. However, it seems that this approach isn’t working well, as it causes linker errors on other operating systems (on the premise that `iphlpapi` and `ws2_32` libraries are specific to Windows).

How can I add platform-specific instructions to `fpm.toml` for successful builds on Windows without affecting builds on the other operating systems?

---

<div class="post-metadata">

**Author:** ![hkvzjal](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/hkvzjal/32/3055_2.png) [@hkvzjal](https://fortran-lang.discourse.group/u/hkvzjal)\
**Post date:** [January 30, 2024, 10:19am UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/2 "2024-01-30T10:19:21Z")

</div>

Had similar issue with other libraries, very curious to know if there could be a workaround!

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [January 31, 2024, 1:15am UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/3 "2024-01-31T01:15:24Z")

</div>

The workaround would be to incorporate this into fpm:

> <https://github.com/fortran-lang/fpm/issues/611>
>
> \### Description
> 
> I'm building a project that depends on \[GASNet-EX\], which links… to different libraries on different operating systems (macOS vs Linux). We will need different OS-specific \`fpm.toml\` files.  
> 
> \[GASNet-EX\]: https://bitbucket.org/berkeleylab/gasnet/
> 
> \### Possible Solution
> 
> It would be helpful to have a \`fpm\` argument that specifies which manifest to use, e.g.,
> \`\`\`
> fpm build --manifest macOS-fpm.toml
> \`\`\`
> 
> \### Additional Information
> 
> \_No response\_

---

<div class="post-metadata">

**Author:** ![amasaki203](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/amasaki203/32/2730_2.png) [@amasaki203](https://fortran-lang.discourse.group/u/amasaki203)\
**Post date:** [January 31, 2024, 5:03am UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/4 "2024-01-31T05:03:34Z")

</div>

Thank you, @ivanpribec, for directing me to a place where this issue is being discussed.  
I understood that I need to make some additional changes to fpm to achieve my goal.

In the discussion there, I find the first suggestion from @awvwgk to be nice and concise. i.e. assuming fpm accepts a manifest like:

```toml
[build]
link = ["..."]
link.linux = ["..."]
link.windows = ["iphlpapi", "ws2_32"]

```

First of all, I started by reading the files in the `src/manifest` directory and `CONTRIBUTING.md` of the fpm repository.

---

<div class="post-metadata">

**Author:** ![amasaki203](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/amasaki203/32/2730_2.png) [@amasaki203](https://fortran-lang.discourse.group/u/amasaki203)\
**Post date:** [February 1, 2024, 7:59am UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/5 "2024-02-01T07:59:50Z")

</div>

> <https://github.com/fortran-lang/fpm/issues/611#issuecomment-1920638000>
>
> \### Description
> 
> I'm building a project that depends on \[GASNet-EX\], which links… to different libraries on different operating systems (macOS vs Linux). We will need different OS-specific \`fpm.toml\` files.  
> 
> \[GASNet-EX\]: https://bitbucket.org/berkeleylab/gasnet/
> 
> \### Possible Solution
> 
> It would be helpful to have a \`fpm\` argument that specifies which manifest to use, e.g.,
> \`\`\`
> fpm build --manifest macOS-fpm.toml
> \`\`\`
> 
> \### Additional Information
> 
> \_No response\_

I proposed my idea for `fpm.toml` on the page above.

---

<div class="post-metadata">

**Author:** ![gnikit](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gnikit/32/1213_2.png) [@gnikit](https://fortran-lang.discourse.group/u/gnikit)\
**Post date:** [February 1, 2024, 9:27am UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/6 "2024-02-01T09:27:48Z")

</div>

The problem is more general, it is not just the linker arguments that would need to be aware of platform/processor. Include directories and compiler flags would also need to be exposed.

This would be closer to a ready-made solution, however it has fallen out of sync with the main branch and is in conflict with other design decisions that were made in the manifest.

> <https://github.com/fortran-lang/fpm/pull/498>
>
> \### This pull request contains all my contribution implemented during my \_\*\*GSoC… 2021 Handling compiler arguments project\*\*\_.
> I have implemented the following features:
> \- parsing of profiles table in toml syntax
> \- profiles representation in package
> \- scope of flags (project-wide profiles, package-wide profiles, files scope flags)
> \- organise compiled code into multiple build directories based on the flags of each source file
> \- handle compiler profiles hierarchy (user-specified \> parent user-specified \> built-in profiles)
> 
> \*\*Changes:\*\*
> \- Move the default compiler flags to \`profiles.f90\` to the function \`get\_default\_profiles\`, which returns an array of \`profile\_config\_t\`s
> \- Change \`'gfortran'\` in \`fpm.90/build\_model\` to \`DEFAULT\_COMPILER\` introduced in \`profiles.f90\`, for consistency
> \- Add \`proj\_dir\` argument to \`get\_package\_data\` and \`new\_package\` for file scope profiles
> \- Extend \`package\_t\` and \`package\_config\_t\` definitions with \`profile\_config\_t\`
> \- Create all \`include\_dirs\` at the beginning of \`build\_package\` subroutine
> \- Remove \`build\_name\` from \`fpm\_command\_line\` and simplify \`check\_build\_vals\` subroutine
> \- Modify \`fpm\_compiler/get\_module\_flags\` not to include any directories, but just handle module flags
> \- Add a conditional checking for allocation of fields in \`fpm\_model\` - Should fix issues with \`show\_model\`
> \- Replace \`model%output\_directory\` with function \`get\_output\_directory\`
> 
> \*\*New features:\*\*
> \- \`profile\_config\_t\` and \`profiles\` toml table parser in \`src/fpm/manifest/profiles.f90\`
> \- \`find\_profile\` subroutine which finds a profile with given parameters in an array of \`profile\_config\_t\`
> \- \`info\_profile\` function which returns representation of a profile as a string
> \- Add flags to targets in \`fpm\_targets/build\_target\_list\`
> \- Tests for profiles in \`test\_manifest.f90\`
> \- Example packages tested by \`ci/run\_tests.sh\`
> 
> \*\*My blog on Fortran-lang discourse\*\*
> \[\*link to Fortran-lang discourse\*\](https://fortran-lang.discourse.group/t/handling-compiler-arguments-in-fpm-project-blog-by-jakub-jelinek/1297)

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [February 1, 2024, 2:25pm UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/7 "2024-02-01T14:25:35Z")

</div>

Does it mean that at the moment it’s not possible to define OS/compiler dependent flags?

---

<div class="post-metadata">

**Author:** ![gnikit](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/gnikit/32/1213_2.png) [@gnikit](https://fortran-lang.discourse.group/u/gnikit)\
**Post date:** [February 1, 2024, 5:38pm UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/8 "2024-02-01T17:38:05Z")

</div>

If you wish to include them in the manifest, yes, that would be accurate. You can use response files, a feature of the CLI module fpm uses (M\_CLI2 [GitHub - urbanjost/M\_CLI2: Fortran commandline-interface using a simple prototype command](https://github.com/urbanjost/M_CLI2.git)) but those files would be **in addition** to the fpm manifest (fpm.toml).

The solution thus far has been setting either the cli args every time you run fpm, response files or setting the environmental variables.

---

<div class="post-metadata">

**Author:** ![FedericoPerini](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/federicoperini/32/1750_2.png) [@FedericoPerini](https://fortran-lang.discourse.group/u/FedericoPerini)\
**Post date:** [February 1, 2024, 6:29pm UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/9 "2024-02-01T18:29:38Z")

</div>

I would think that a viable solution is one that includes platform-specific settings (at least for the three major platforms aka unix, Mac, windows). Two ways to structure it would be:

1. replicate the package tree as a “target” node, so that all options can be made platform-specific (at least supported in the manifest…)

```toml
[[target]]
[target.windows]
link = ["lib1","lib2","lib3"]
[target.windows.dependencies]
helloff = { git = "https://gitlab.com/everythingfunctional/helloff.git" }
[target.windows.dev-depencencies]
etc = {git = "..."}

```

1. create a “platform” node that can support string arrays for the three major platforms. Support now only for linking libraries, but later extendable to other features

```auto
[[executable]]
name = "my-app"
link = ["x","y","z"]
link.platform.windows = ["win_lib1","win_lib2"]
link.platform.unix = "mesa"

```

Rust basically [employs option #1](https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies), although it does so via a meta-language. I personally don’t like that and think a very good first iterate would be to only allow the 3/major OS platform that fpm can already deal with.

---

<div class="post-metadata">

**Author:** ![urbanjost](https://avatars.discourse-cdn.com/v4/letter/u/0ea827/32.png) [@urbanjost](https://fortran-lang.discourse.group/u/urbanjost)\
**Post date:** [February 3, 2024, 6:57pm UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/11 "2024-02-03T18:57:01Z")

</div>

not having conditionals in TOML files is problematic.

In addition to the possible approaches above, you can create a plugin command like ‘fpm-config’ that, using any method would generate the fpm.toml file. If no fpm.toml exists the next time the fpm command runs it could run it. This would be similar to the config(1) command and related tools used to create custom make files, for example.

You could look for fpm.linux.gfortran.toml first; then fpm.linux; then fpm.toml. So there could be system-specific and compiler-specific names that would be automatically searched for from most specific to least specific, somewhat like the response files can do.

The fpm.toml file could support conditionals. A simple Fortran example in [GitHub - urbanjost/general-purpose-fortran: General Purpose Fortran Cooperative](https://github.com/urbanjost/general-purpose-fortran) called M\_logic.f90 shows a (originally F77, which still shows) a module that can be used to add if/else/elseif/endif logic to input files, for example.

The conditional processing could be done via a pre-processor such as cpp or m4. Having one supported for the fpm.toml file as well as the code would be most useful; although a pre-processor that can make decisions based on file information such as what libraries are available, what compilers, what OS can be difficult to do both generically and portably across systems.  
I have used each of these approaches. The config one is the most flexible, but it is easy to construct a fpm-config that is not portable to all platforms, which would make placing a package in a public space such as the in-progress fpm repository.

---

<div class="post-metadata">

**Author:** ![amasaki203](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/amasaki203/32/2730_2.png) [@amasaki203](https://fortran-lang.discourse.group/u/amasaki203)\
**Post date:** [February 4, 2024, 9:06am UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/12 "2024-02-04T09:06:13Z")

</div>

Thank you for providing various workarounds on the command line.

I also realize that this is more complex than I initially thought.

The project containing this issue that I am dealing with almost assumes dependencies from another project. Unfortunately, none of the methods are convenient in requiring special actions from the user. I hope that the issue will be resolved in the future…

---

<div class="post-metadata">

**Author:** ![IanMartinAjzenszmidt](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ianmartinajzenszmidt/32/1992_2.png) [@IanMartinAjzenszmidt](https://fortran-lang.discourse.group/u/IanMartinAjzenszmidt)\
**Post date:** [February 6, 2024, 2:37pm UTC](https://fortran-lang.discourse.group/t/fpm-platform-specific-instructions-to-linker-on-fpm-toml/7296/13 "2024-02-06T14:37:11Z")

</div>

> [@amasaki203](#):
>
> Hi.
> 
> I’m using fpm v0.10.0 and writing code that utilizes C interoperability to use OS APIs. To support cross-platform compatibility, I’m switching build code using preprocessor directives, which works fine in general. However, I’ve noticed that I need to add specific instructions to the linker only for Windows.
> 
> I attempt to address this in the `fpm.toml` file with the following:
> 
> ```auto
> [build]
> auto-executables = true
> auto-tests = true
> auto-examples = true
> module-naming = false
> link = ["iphlpapi", "ws2_32"]
> 
> ```
> 
> Specifically, adding `link = ["iphlpapi", "ws2_32"]` to `fpm.toml` for successful Windows builds. However, it seems that this approach isn’t working well, as it causes linker errors on other operating systems (on the premise that `iphlpapi` and `ws2_32` libraries are specific to Windows).
> 
> How can I add platform-specific instructions to `fpm.toml` for successful builds on Windows without affecting builds on the other operating systems?

I cant guarantee that the following is correct, but it might be worth considering.  
To add platform-specific instructions to your `fpm.toml` file for successful builds on Windows without affecting builds on other operating systems, you can utilize conditional compilation supported by Fortran Package Manager (fpm). This approach allows you to specify different settings for different platforms.

In `fpm`, conditional settings can be specified using profile sections in the `fpm.toml` file. Each profile can include conditions based on the operating system, compiler, or build mode, which allows you to tailor the build process for different environments.

Here’s how you can modify your `fpm.toml` file to include Windows-specific linker instructions:

toml

```auto
[build]
auto-executables = true
auto-tests = true
auto-examples = true
module-naming = false

# Default linker settings for non-Windows platforms
link = []

# Windows-specific settings
[profiles.windows-x86_64]
link = ["iphlpapi", "ws2_32"]

```

In this example, the `[profiles.windows-x86_64]` section is used to specify settings that should only apply when building on a 64-bit Windows platform. The `link = ["iphlpapi", "ws2_32"]` line within this section adds the `iphlpapi` and `ws2_32` libraries to the linker settings, but only for Windows builds. The default `link = []` in the `[build]` section ensures that no additional libraries are linked for non-Windows platforms.

This approach should help you avoid linker errors on other operating systems while still including the necessary libraries for Windows builds. Remember to adjust the profile name and conditions according to your specific needs and the platforms you are targeting.
