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:
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?
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:
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.
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:
replicate the package tree as a “target” node, so that all options can be made platform-specific (at least supported in the manifest…)
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
[[executable]]
name = "my-app"
link = ["x","y","z"]
link.platform.windows = ["win_lib1","win_lib2"]
link.platform.unix = "mesa"
Rust basically employs option #1, 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.
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 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.
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…
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:
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.