分发你的程序#
分发程序时,你可以选择多种选项:
分发整个源代码
分发预构建的可执行程序
分发人们可以使用的静态或动态库
选项 1:分发整个源代码
到目前为止,最简单的 —— 对于作为程序员的你来说 —— 就是这个:你把它留给用户在他们自己的机器上构建它。不幸的是,这意味着你必须有一个用户友好的构建系统,并且用户必须能够访问合适的编译器。对于构建系统:请参阅上一节。
选项 2:分发预构建的可执行程序
除了通过其输入之外,不需要定制的预构建程序仍然需要附带各种运行时库,并且将特定于为其构建的操作系统/环境。
运行时库因操作系统和编译器版本而异。对于像 gfortran 这样的免费编译器,最简单的方法是要求用户在他们的系统上安装该编译器。在 Windows 的情况下:可能需要 Cygwin 环境。
或者,你可以将运行时库的副本与你的程序一起提供。将它们放在运行时可以找到的目录中。
注意:在 Windows 上,英特尔 Fortran 附带一组 redistributable 库。这些将需要提供。
一般来说:使用 ldd
或 dependency 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
优点是编译器可以检查传递的函数的接口,并且用户可以更自由地使用你的库提供的功能。