]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/ldns/README-Travis.md
ldns: Upgrade to 1.8.3.
[FreeBSD/FreeBSD.git] / contrib / ldns / README-Travis.md
1 # Travis Testing
2
3 LDNS 1.7.1 and above leverage Travis CI to increase coverage of compilers and platforms. Compilers include Clang and GCC; while platforms include Android, iOS, Linux, and OS X on AMD64, Aarch64, PowerPC and s390x hardware.
4
5 Android is tested on armv7a, aarch64, x86 and x86_64. The Android recipes build and install OpenSSL, and then builds LDNS. The testing is tailored for Android NDK-r19 and above, and includes NDK-r20 and NDK-r21. Mips and Mips64 are not tested because they are no longer supported under current NDKs.
6
7 iOS is tested for iPhoneOS, WatchOS, AppleTVOS, iPhoneSimulator, AppleTVSimulator and WatchSimulator. The testing uses Xcode 10 on OS X 10.13.
8
9 The LDNS Travis configuration file `.travis.yml` does not use top-level keys like `os:` and `compiler:` so there is no matrix expansion. Instead LDNS specifies the exact job to run under the `jobs:` and `include:` keys.
10
11 ## Typical recipe
12
13 A typical recipe tests Clang and GCC on various hardware. The hardware includes AMD64, Aarch64, PowerPC and s390x. PowerPC is a little-endian platform, and s390x is a big-endian platform. There are pairs of recipes that are similar to the following.
14
15 ```
16 - os: linux
17   name: GCC on Linux, Aarch64
18   compiler: gcc
19   arch: arm64
20   dist: bionic
21 - os: linux
22   name: Clang on Linux, Aarch64
23   compiler: clang
24   arch: arm64
25   dist: bionic
26 ```
27
28 OS X provides a single recipe to test Clang. GCC is not tested because GCC is an alias for Clang.
29
30 ## Sanitizer builds
31
32 Two sanitizer builds are tested using Clang and GCC, for a total of four builds. The first sanitizer is Undefined Behavior sanitizer (UBsan), and the second is Address sanitizer (Asan). The sanitizers are only run on AMD64 hardware. Note the environment includes `UBSAN=yes` or `ASAN=yes` for the sanitizer builds.
33
34 The recipes are similar to the following.
35
36 ```
37 - os: linux
38   name: UBsan, GCC on Linux, Amd64
39   compiler: gcc
40   arch: amd64
41   dist: bionic
42   env: UBSAN=yes
43 - os: linux
44   name: UBsan, Clang on Linux, Amd64
45   compiler: clang
46   arch: amd64
47   dist: bionic
48   env: UBSAN=yes
49 ```
50
51 When the Travis script encounters a sanitizer it uses different `CFLAGS` and configuration string.
52
53 ```
54 if [ "$UBSAN" = "yes" ]; then
55   export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=undefined -fno-sanitize-recover"
56   bash test/test_ci.sh
57 elif [ "$ASAN" = "yes" ]; then
58   export CFLAGS="-DNDEBUG -g2 -O3 -fsanitize=address"
59   bash test/test_ci.sh
60 ...
61 ```
62
63 ## Android builds
64
65 Travis tests Android builds for the armv7a, aarch64, x86 and x86_64 architectures. The builds are trickier than other builds for several reasons. The testing requires installation of the Android NDK and SDK, it requires a cross-compile, and requires OpenSSL prerequisites. The Android cross-compiles also require care to set the Autotools triplet, the OpenSSL triplet, the toolchain path, the tool variables, and the sysroot. The discussion below detail the steps of the Android recipes.
66
67 ### Android job
68
69 The first step sets environmental variables for the cross-compile using the Travis job. A typical job with variables is shown below.
70
71 ```
72 - os: linux
73   name: Android armv7a, Linux, Amd64
74   compiler: clang
75   arch: amd64
76   dist: bionic
77   env:
78     - ANDROID=yes
79     - AUTOTOOLS_HOST=armv7a-linux-androideabi
80     - OPENSSL_HOST=android-arm
81     - ANDROID_CPU=armv7a
82     - ANDROID_API=23
83     - ANDROID_PREFIX="$HOME/android$ANDROID_API-$ANDROID_CPU"
84     - ANDROID_SDK_ROOT="$HOME/android-sdk"
85     - ANDROID_NDK_ROOT="$HOME/android-ndk"
86 ```
87
88 ### ANDROID_NDK_ROOT
89
90 The second step for Android is to set the environmental variables `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT`. This is an important step because the NDK and SDK use the variables internally to locate their own tools. Also see [Recommended NDK Directory?](https://groups.google.com/forum/#!topic/android-ndk/qZjhOaynHXc) on the android-ndk mailing list. (Many folks miss this step, or use incorrect variables like `ANDROID_NDK_HOME` or `ANDROID_SDK_HOME`).
91
92 If you are working from a developer machine you probably already have the necessary tools installed. You should ensure `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT` are set properly.
93
94 ### Tool installation
95
96 The second step installs tools needed for OpenSSL, Expat and LDNS. This step is handled in by the script `contrib/android/install_tools.sh`. The tools include curl, tar, zip, unzip and java.
97
98 ```
99 before_script:
100   - |
101     if [ "$ANDROID" = "yes" ]; then
102       ./contrib/android/install_tools.sh
103     elif [ "$IOS" = "yes" ]; then
104       ./contrib/ios/install_tools.sh
105     fi
106 ```
107
108 ### NDK installation
109
110 The third step installs the NDK and SDK. This step is handled in by the script `contrib/android/install_ndk.sh`. The script uses `ANDROID_NDK_ROOT` and `ANDROID_SDK_ROOT` to place the NDK and SDK in the `$HOME` directory.
111
112 If you are working from a developer machine you probably already have a NDK and SDK installed.
113
114 ### Android environment
115
116 The fourth step sets the Android cross-compile environment using the script `contrib/android/setenv_android.sh`. The script is `sourced` so the variables in the script are available to the calling shell. The script sets variables like `CC`, `CXX`, `AS` and `AR`; sets `CFLAGS` and `CXXFLAGS`; sets a `sysroot` so Android headers and libraries are found; and adds the path to the toolchain to `PATH`.
117
118 `contrib/android/setenv_android.sh` knows which toolchain and architecture to select by inspecting environmental variables set by Travis for the job. In particular, the variables `ANDROID_CPU` and `ANDROID_API` tell `contrib/android/setenv_android.sh` which tools and libraries to select.
119
120 The `contrib/android/setenv_android.sh` script specifies the tools in a `case` statement like the following. There is a case for each of the architectures armv7a, aarch64, x86 and x86_64.
121
122 ```
123 armv8a|aarch64|arm64|arm64-v8a)
124   CC="aarch64-linux-android$ANDROID_API-clang"
125   CXX="aarch64-linux-android$ANDROID_API-clang++"
126   LD="aarch64-linux-android-ld"
127   AS="aarch64-linux-android-as"
128   AR="aarch64-linux-android-ar"
129   RANLIB="aarch64-linux-android-ranlib"
130   STRIP="aarch64-linux-android-strip"
131
132   CFLAGS="-funwind-tables -fexceptions"
133   CXXFLAGS="-funwind-tables -fexceptions -frtti"
134 ```
135
136 ### OpenSSL
137
138 The fifth step builds OpenSSL. OpenSSL is built for iOS using the scripts `contrib/android/install_openssl.sh`. The script downloads, configures and installs the latest release version of the OpenSSL libraries. OpenSSL is configured with `--prefix="$ANDROID_PREFIX"` so the headers are placed in `$ANDROID_PREFIX/include` directory, and the libraries are placed in the `$ANDROID_PREFIX/lib` directory.
139
140 `ANDROID_PREFIX` is the value `$HOME/android$ANDROID_API-$ANDROID_CPU`. The libraries will be installed in `$HOME/android23-armv7a`, `$HOME/android23-aarch64`, etc. For Autotools projects, the appropriate `PKG_CONFIG_PATH` is exported.
141
142 `PKG_CONFIG_PATH` is an important variable. It is the userland equivalent to sysroot, and allows Autotools to find non-system headers and libraries for an architecture. Typical `PKG_CONFIG_PATH` are `$HOME/android23-armv7a/lib/pkgconfig` and `$HOME/android23-aarch64/lib/pkgconfig`.
143
144 OpenSSL also uses a custom configuration file called `15-android.conf`. It is a copy of the OpenSSL's project file and located at `contrib/android/15-android.conf`. The LDNS version is copied to the OpenSSL source files after unpacking the OpenSSL distribution. The LDNS version has legacy NDK support removed and some other fixes, like `ANDROID_NDK_ROOT` awareness. The changes mean LDNS's `15-android.conf` will only work with LDNS, with NDK-r19 and above, and a properly set environment.
145
146 OpenSSL is configured with `no-engine`. If you want to include OpenSSL engines then edit `contrib/android/install_openssl.sh` and remove the config option.
147
148 ### Android build
149
150 Finally, once OpenSSL are built, then the Travis script configures and builds LDNS. The recipe looks as follows.
151
152 ```
153 elif [ "$ANDROID" = "yes" ]; then
154   export AUTOTOOLS_BUILD="$(./config.guess)"
155   export PKG_CONFIG_PATH="$ANDROID_PREFIX/lib/pkgconfig"
156   ./contrib/android/install_ndk.sh
157   source ./contrib/android/setenv_android.sh
158   ./contrib/android/install_openssl.sh
159   ./contrib/android/bootstrap_ldns.sh
160   ./configure \
161     --build="$AUTOTOOLS_BUILD" \
162     --host="$AUTOTOOLS_HOST" \
163     --prefix="$ANDROID_PREFIX" \
164     --with-ssl="$ANDROID_PREFIX" \
165     --disable-gost \
166     --with-drill --with-examples
167   make -j 2
168   make install
169 ```
170
171 Travis only smoke tests an Android build using a compile, link and install. The self tests are not run. TODO: figure out how to fire up an emulator, push the tests to the device and run them.
172
173 ### Android flags
174
175 `contrib/android/setenv_android.sh` uses specific flags for `CFLAGS` and `CXXFLAGS`. They are taken from `ndk-build`, so we consider them the official flag set. It is important to use the same flags across projects to avoid subtle problems due to mixing and matching different flags.
176
177 `CXXFLAGS` includes `-fexceptions` and `-frtti` because exceptions and runtime type info are disabled by default. `CFLAGS` include `-funwind-tables` and `-fexceptions` to ensure C++ exceptions pass through C code, if needed. Also see `docs/CPLUSPLUS-SUPPORT.html` in the NDK docs.
178
179 To inspect the flags used by `ndk-build` for a platform clone ASOP's [ndk-samples](https://github.com/android/ndk-samples/tree/master/hello-jni) and build the `hello-jni` project. Use the `V=1` flag to see the full compiler output from `ndk-build`.
180
181 ## iOS builds
182
183 Travis tests iOS builds for the armv7a, armv7s and aarch64 architectures for iPhoneOS, AppleTVOS and WatchOS. iPhoneOS is tested using both 32-bit builds (iPhones) and 64-bit builds (iPads). Travis also tests compiles against the simulators. The builds are trickier than other builds for several reasons. The testing requires a cross-compile, and requires OpenSSL prerequisites. The iOS cross-compiles also require care to set the Autotools triplet, the OpenSSL triplet, the toolchain path, the tool variables, and the sysroot. The discussion below detail the steps of the iOS recipes.
184
185 ### iOS job
186
187 The first step sets environmental variables for the cross-compile using the Travis job. A typical job with variables is shown below.
188
189 ```
190 - os: osx
191   osx_image: xcode10
192   name: Apple iPhone on iOS, armv7
193   compiler: clang
194   env:
195     - IOS=yes
196     - AUTOTOOLS_HOST=armv7-apple-ios
197     - OPENSSL_HOST=ios-cross
198     - IOS_SDK=iPhoneOS
199     - IOS_CPU=armv7s
200     - IOS_PREFIX="$HOME/$IOS_SDK-$IOS_CPU"
201 ```
202
203 ### Tool installation
204
205 The second step installs tools needed for OpenSSL, Expat and LDNS. This step is handled in by the script `contrib/ios/install_tools.sh`. The tools include autotools, curl and perl. The installation happens at the `before_script:` stage of Travis.
206
207 ```
208 before_script:
209   - |
210     if [ "$ANDROID" = "yes" ]; then
211       ./contrib/android/install_tools.sh
212     elif [ "$IOS" = "yes" ]; then
213       ./contrib/ios/install_tools.sh
214     fi
215 ```
216
217 ### iOS environment
218
219 The third step sets the iOS cross-compile environment using the script `contrib/ios/setenv_ios.sh`. The script is `sourced` so the variables in the script are available to the calling shell. The script sets variables like `CC`, `CXX`, `AS` and `AR`; sets `CFLAGS` and `CXXFLAGS`; sets a `sysroot` so iOS headers and libraries are found; and adds the path to the toolchain to `PATH`.
220
221 `contrib/ios/setenv_ios.sh` knows which toolchain and architecture to select by inspecting environmental variables set by Travis for the job. In particular, the variables `IOS_SDK` and `IOS_CPU` tell `contrib/ios/setenv_ios.sh` which tools and libraries to select.
222
223 The `contrib/ios/setenv_ios.sh` script specifies the tools to use during the cross-compile. For Apple SDKs, the tool names are the same as a desktop. There are no special prefixes for the mobile tools.
224
225 ```
226 CPP=cpp
227 CC=clang
228 CXX=clang++
229 LD=ld
230 AS=as
231 AR=ar
232 RANLIB=ranlib
233 STRIP=strip
234 ```
235
236 If you are working from a developer machine you probably already have the necessary tools installed.
237
238 ### OpenSSL
239
240 The fourth step builds OpenSSL. OpenSSL is built for iOS using the scripts `contrib/ios/install_openssl.sh`. The script downloads, configures and installs the latest release version of the OpenSSL libraries. OpenSSL is configured with `--prefix="$IOS_PREFIX"` so the headers are placed in `$IOS_PREFIX/include` directory, and the libraries are placed in the `$IOS_PREFIX/lib` directory.
241
242 `IOS_PREFIX` is the value `$HOME/$IOS_SDK-$IOS_CPU`. The scheme handles both iOS SDKs and cpu architectures so the pair receives a unique installation directory. The libraries will be installed in `$HOME/iPhoneOS-armv7s`, `$HOME/iPhoneOS-arm64`, `$HOME/iPhoneSimulator-i386`, etc. For Autotools projects, the appropriate `PKG_CONFIG_PATH` is exported.
243
244 `PKG_CONFIG_PATH` is an important variable. It is the userland equivalent to sysroot, and allows Autotools to find non-system headers and libraries for an architecture. Typical `PKG_CONFIG_PATH` are `$HOME/iPhoneOS-armv7s/lib/pkgconfig` and `$HOME/iPhoneOS-arm64/lib/pkgconfig`.
245
246 OpenSSL also uses a custom configuration file called `15-ios.conf`. It is a copy of the OpenSSL's project file and located at `contrib/ios/15-ios.conf`. The LDNS version is copied to the OpenSSL source files after unpacking the OpenSSL distribution. The changes mean LDNS's `15-ios.conf` will only work with LDNS and a properly set environment.
247
248 OpenSSL is configured with `no-engine`. Engines require dynamic loading so engines are disabled permanently in `15-ios.conf`.
249
250 ### iOS build
251
252 Finally, once OpenSSL are built, then the Travis script configures and builds LDNS. The full recipe looks as follows.
253
254 ```
255 elif [ "$IOS" = "yes" ]; then
256   export AUTOTOOLS_BUILD="$(./config.guess)"
257   export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig"
258   source ./contrib/ios/setenv_ios.sh
259   ./contrib/ios/install_openssl.sh
260   ./contrib/ios/bootstrap_ldns.sh
261   ./configure \
262     --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \
263     --prefix="$IOS_PREFIX" \
264     --with-ssl="$IOS_PREFIX" --disable-gost \
265     --with-drill --with-examples
266   make -j 2
267   make install
268 ```
269
270 Travis only smoke tests an iOS build using a compile, link and install. The self tests are not run. TODO: figure out how to fire up an simulator, push the tests to the device and run them.
271
272 ### iOS flags
273
274 `contrib/ios/setenv_ios.sh` uses specific flags for `CFLAGS` and `CXXFLAGS`. They are taken from Xcode, so we consider them the official flag set. It is important to use the same flags across projects to avoid subtle problems due to mixing and matching different flags.