分发你的程序#

分发程序时,你可以选择多种选项:

  1. 分发整个源代码

  2. 分发预构建的可执行程序

  3. 分发人们可以使用的静态或动态库

选项 1:分发整个源代码

到目前为止,最简单的 —— 对于作为程序员的你来说 —— 就是这个:你把它留给用户在他们自己的机器上构建它。不幸的是,这意味着你必须有一个用户友好的构建系统,并且用户必须能够访问合适的编译器。对于构建系统:请参阅上一节。

选项 2:分发预构建的可执行程序

除了通过其输入之外,不需要定制的预构建程序仍然需要附带各种运行时库,并且将特定于为其构建的操作系统/环境。

运行时库因操作系统和编译器版本而异。对于像 gfortran 这样的免费编译器,最简单的方法是要求用户在他们的系统上安装该编译器。在 Windows 的情况下:可能需要 Cygwin 环境。

或者,你可以将运行时库的副本与你的程序一起提供。将它们放在运行时可以找到的目录中。

注意:在 Windows 上,英特尔 Fortran 附带一组 redistributable 库。这些将需要提供。

一般来说:使用 ldddependency walker 之类的工具来找出需要哪些库并查阅编译器的文档。

如果你的程序确实允许自定义,请考虑为此使用动态库。下面将对此进行更多说明。

选项 3:分发人们可以使用的静态或动态库

此选项是前两个选项的组合。它确实给用户带来了一些负担,因为他们必须创建一个以正确方式调用你的例程的主程序,但他们不需要对你使用的构建系统有太多了解。不过,你将不得不处理运行时库。

如果选择此选项,除了编译的库之外,你还需要提供模块中间文件。这些文件是特定于编译器的,但你构建的静态库也是如此。

分发制表程序#

如上所示,可以使用动态库中的用户定义函数来构建制表程序。这使你能够:

  • 运送可执行文件(使用适当的运行时库)

  • 提供模块的骨架版本,例如:

module user_functions
    implicit none
contains

real function f( x )
!DEC$ ATTRIBUTES DLLEXPORT :: f
    real, intent(in) :: x

    ! your function body goes here

end function f

end module user_functions
  • 使用以下命令提供基本构建脚本:

gfortran -o functions.dll functions.f90 -shared

或者:

ifort -exe:functions.dll functions.f90 -dll

如前所述,你无法控制用户是否做了正确的事情 —— 任何带有函数 f 的 DLL functions.dll 都会被接受,但不一定会导致成功运行。

另一种设置是将主程序更改为子程序并将函数作为参数:

module tabulation
    implicit none
contains

subroutine tabulate( f )
    interface
        real function f( x )
            real, intent(in) :: x
        end function f
    end interface

    ! your implementation goes here

end subroutine tabulate

end module tabulation

然后提供一个骨架主程序:

program tabulate_f
    use tabulation

    call tabulate( func1 )

contains

real function func1( x )
    real, intent(in) :: x

    ! your function body goes here

end function func1

end program tabulate_f

优点是编译器可以检查传递的函数的接口,并且用户可以更自由地使用你的库提供的功能。