|
| 1 | +--- |
| 2 | +layout: book |
| 3 | +title: Distributing your programs |
| 4 | +permalink: /learn/building_programs/distributing |
| 5 | +--- |
| 6 | + |
| 7 | +When you distribute your programs, there are a number of options you can |
| 8 | +choose from: |
| 9 | + |
| 10 | +1. Distribute the entire source code |
| 11 | +2. Distribute a pre-built executable program |
| 12 | +3. Distribute static or dynamic libraries that people can use |
| 13 | + |
| 14 | +__Option 1: Distribute the entire source code__ |
| 15 | + |
| 16 | +By far the simplest - for you as a programmer - is this one: you leave it |
| 17 | +up to the user to build it on their own machine. Unfortunately, that |
| 18 | +means you will have to have a user-friendly build system in place and |
| 19 | +the user will have to have access to suitable compilers. For build systems: |
| 20 | +see the previous section. |
| 21 | + |
| 22 | +__Option 2: Distribute a pre-built executable program__ |
| 23 | + |
| 24 | +A pre-built program that does not need to be customised, other than via its |
| 25 | +input, will still need to come with the various run-time libraries and will |
| 26 | +be specific to the operating system/environment it was built for. |
| 27 | + |
| 28 | +The set of run-time libraries differs per operating system and compiler version. |
| 29 | +For a freely available compiler like gfortran, the easiest thing is to ask the |
| 30 | +user to install that compiler on their system. In the case of Windows: the Cygwin |
| 31 | +environment may be called for. |
| 32 | + |
| 33 | +Alternatively, you can supply copies of the run-time libraries together with your |
| 34 | +program. Put them in the directory where they can be found at run-time. |
| 35 | + |
| 36 | +Note: On Windows, the Intel Fortran comes with a set of _redistributable_ libraries. |
| 37 | +These will need to be made available. |
| 38 | + |
| 39 | +In general: use a tool like "ldd" or "dependency walker" to find out what |
| 40 | +libraries are required and consult the documentation of the compiler. |
| 41 | + |
| 42 | +If your program does allow customisation, consider using dynamic libraries for this. |
| 43 | +More is said about this below. |
| 44 | + |
| 45 | +__Option 3: Distribute static or dynamic libraries that people can use__ |
| 46 | + |
| 47 | +This option is a combination of the first two options. It does put some burden on |
| 48 | +the user, as they must create a main program that calls your routines in the |
| 49 | +proper way, but they do not need to know much about the build system you used. |
| 50 | +You will have to deal with the run-time libraries, though. |
| 51 | + |
| 52 | +If you choose this option, besides the compiled libraries, you will also need to |
| 53 | +supply the module intermediate files. These files are compiler-specific, but so are |
| 54 | +the static libraries you build. |
| 55 | + |
| 56 | +## Distributing the tabulation program |
| 57 | +As shown above, the tabulation program can be built with the user-defined function |
| 58 | +in a dynamic library. This enables you to: |
| 59 | + |
| 60 | +* Ship the executable (with the appropriate run-time libraries) |
| 61 | +* Provide a skeleton version of the module, something like: |
| 62 | + |
| 63 | +```fortran |
| 64 | + module user_functions |
| 65 | + implicit none |
| 66 | + contains |
| 67 | +
|
| 68 | + real function f( x ) |
| 69 | + !DEC$ ATTRIBUTES DLLEXPORT :: f |
| 70 | + real, intent(in) :: x |
| 71 | +
|
| 72 | + ... TO BE FILLED IN ... |
| 73 | +
|
| 74 | + end function f |
| 75 | + end module user_functions |
| 76 | +``` |
| 77 | + |
| 78 | +* Provide a basic build script with a command like: |
| 79 | + |
| 80 | +```shell |
| 81 | + gfortran -o function.dll function.f90 -shared |
| 82 | +``` |
| 83 | + |
| 84 | +or: |
| 85 | + |
| 86 | +```shell |
| 87 | + ifort -exe:function.dll function.f90 -dll |
| 88 | +``` |
| 89 | + |
| 90 | +As said, you cannot control that the user has done the right thing - any |
| 91 | +DLL "function.dll" with a function `f` would be accepted, but not necessarily |
| 92 | +lead to a successful run. |
| 93 | + |
| 94 | +An alternative set-up would be to change the main program into a subroutine |
| 95 | +and have the function as an argument: |
| 96 | + |
| 97 | +```fortran |
| 98 | + module tabulation |
| 99 | + implicit none |
| 100 | + contains |
| 101 | +
|
| 102 | + subroutine tabulate( f ) |
| 103 | + interface |
| 104 | + real function f( x ) |
| 105 | + real, intent(in) :: x |
| 106 | + end function f |
| 107 | + end interface |
| 108 | +
|
| 109 | + ... actual implementation |
| 110 | +
|
| 111 | + end subroutine tabulate |
| 112 | +
|
| 113 | + end module tabulation |
| 114 | +``` |
| 115 | + |
| 116 | +Then provide a skeleton main program: |
| 117 | + |
| 118 | +```fortran |
| 119 | + program tabulate_f |
| 120 | + use tabulation |
| 121 | +
|
| 122 | + call tabulate( func1 ) |
| 123 | + contains |
| 124 | + real function func1( x ) |
| 125 | + real, intent(in) :: x |
| 126 | +
|
| 127 | + ... TO BE FILLED IN ... |
| 128 | +
|
| 129 | + end function func1 |
| 130 | + end program tabulate_f |
| 131 | +``` |
| 132 | + |
| 133 | +The advantage is that the compiler can check the interface of the |
| 134 | +function that is passed and that the user has more freedom in the use of the |
| 135 | +functionality provided by your library. |
0 commit comments