├── data
├── apache
│ ├── 000-default.conf.in
│ ├── default-ssl.conf.in
│ └── apache2.conf.in
└── build-launcher.sh.in
├── include
├── build-source-autotools.sh
├── build-source-config.sh
├── build-source-flatpak.sh
└── build-source.sh
├── README
├── extra
└── irc-notify.py
└── COPYING
/data/apache/000-default.conf.in:
--------------------------------------------------------------------------------
1 |
2 | ServerAdmin webmaster@localhost
3 | DocumentRoot @@SITE_ROOT@@
4 |
5 | ErrorLog ${APACHE_LOG_DIR}/error.log
6 | CustomLog ${APACHE_LOG_DIR}/access.log combined
7 |
8 |
--------------------------------------------------------------------------------
/data/apache/default-ssl.conf.in:
--------------------------------------------------------------------------------
1 |
2 |
3 | ServerAdmin webmaster@localhost
4 |
5 | DocumentRoot @@SITE_ROOT@@
6 |
7 | ErrorLog ${APACHE_LOG_DIR}/error.log
8 | CustomLog ${APACHE_LOG_DIR}/access.log combined
9 |
10 | SSLEngine on
11 |
12 | SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
13 | SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
14 |
15 |
16 | SSLOptions +StdEnvVars
17 |
18 |
19 | SSLOptions +StdEnvVars
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/data/apache/apache2.conf.in:
--------------------------------------------------------------------------------
1 | Mutex file:${APACHE_LOCK_DIR} default
2 | PidFile ${APACHE_PID_FILE}
3 | Timeout 300
4 | KeepAlive On
5 | MaxKeepAliveRequests 100
6 | KeepAliveTimeout 5
7 | User ${APACHE_RUN_USER}
8 | Group ${APACHE_RUN_GROUP}
9 | HostnameLookups Off
10 | ErrorLog ${APACHE_LOG_DIR}/error.log
11 | LogLevel warn
12 | IncludeOptional mods-enabled/*.load
13 | IncludeOptional mods-enabled/*.conf
14 | Include ports.conf
15 | AccessFileName .htaccess
16 |
17 | Require all denied
18 |
19 | LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
20 | LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
21 | LogFormat "%h %l %u %t \"%r\" %>s %O" common
22 | LogFormat "%{Referer}i -> %U" referer
23 | LogFormat "%{User-agent}i" agent
24 | IncludeOptional conf-enabled/*.conf
25 | IncludeOptional sites-enabled/*.conf
26 |
27 | Options FollowSymLinks
28 | AllowOverride None
29 | Require all denied
30 |
31 |
32 | Options Indexes FollowSymLinks
33 | AllowOverride None
34 | Require all granted
35 |
36 |
--------------------------------------------------------------------------------
/include/build-source-autotools.sh:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2016 Endless Mobile, Inc.
2 | # Author: Tristan Van Berkom
3 | #
4 | # This program is free software; you can redistribute it and/or
5 | # modify it under the terms of the GNU Lesser General Public
6 | # License as published by the Free Software Foundation; either
7 | # version 2 of the License, or (at your option) any later version.
8 | #
9 | # This library is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | # Lesser General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU Lesser General Public
15 | # License along with this library. If not, see .
16 |
17 | # A build source to build an autotools
18 | # package and install it into "${build_source_prefix}
19 | function buildInstallAutotools() {
20 | local module=$1
21 | local changed=$2
22 | local archdir="${build_source_build}/${build_source_arch}"
23 | local moduledir="${archdir}/${module}"
24 |
25 | # No need to re-autogen and build if the gits didnt change
26 | if [ "${changed}" -eq "0" ]; then
27 | echo "Module ${module} is up to date, not rebuilding"
28 | return
29 | fi
30 |
31 | export PKG_CONFIG_PATH="${build_source_prefix}/lib/pkgconfig:${PKG_CONFIG_PATH}"
32 | export PATH="${build_source_prefix}/bin:${PATH}"
33 |
34 | cd "${moduledir}" || dienow
35 | echo "Configuring ${module}"
36 | ./autogen.sh --prefix="${build_source_prefix}" --with-systemdsystemunitdir="${build_source_prefix}" BASH_COMPLETIONSDIR="${build_source_prefix}/share/bash-completion" || dienow
37 | echo "Building ${module}"
38 | make -j8 || dienow
39 | echo "Installing ${module}"
40 | make install || dienow
41 | return 0
42 | }
43 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | A collection of build scripts for building flatpak SDKs and app bundles
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 |
4 |
5 | Configure
6 | ~~~~~~~~~
7 | To configure the behavior of a build, either edit the build.conf file
8 | at the top level or make an alternative copy which can be supplied
9 | to the build tooling with a --config argument.
10 |
11 | The configuration file lets you define which branches of which
12 | repositories should be built.
13 |
14 |
15 | Build
16 | ~~~~~
17 | To launch a build of the entire stack, use the build-payload.sh script.
18 |
19 | This will checkout all the relevant sources and run the build starting
20 | with the base runtimes, followed by the SDKs and finally the apps. If it
21 | is not the first time you are building in the given work directory, then
22 | the repositories will be updated and some redundant rebuilding is avoided.
23 |
24 |
25 | Setup
26 | ~~~~~
27 | To setup a build, use the build-setup.sh script. This script sets up your
28 | build machine and as such will issue some commands with sudo and prompt
29 | for your password.
30 |
31 | The build-setup.sh script performs the following steps:
32 |
33 | o Installs all required host tooling using the package manager,
34 | currently this is only well tested on Ubuntu 16.04 installations
35 | but is also known to work on Debian stretch - support will need
36 | to be added for rpm based distros.
37 |
38 | o Downloads, compiles and installs flatpak and some dependencies from
39 | their respective git repositories (flatpak and ostree are not available
40 | as packages at the time of writing this).
41 |
42 | o Sets up a cron job to automatically run the build, running the build.
43 |
44 | This script can be run multiple times safely. Running the build-setup.sh script
45 | on a build machine that is already setup will result in system dependencies
46 | being upgraded and flatpak modules to be refreshed and possibly rebuilt.
47 |
--------------------------------------------------------------------------------
/include/build-source-config.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright (C) 2016 Endless Mobile, Inc.
3 | # Author: Tristan Van Berkom
4 | #
5 | # This program is free software; you can redistribute it and/or
6 | # modify it under the terms of the GNU Lesser General Public
7 | # License as published by the Free Software Foundation; either
8 | # version 2 of the License, or (at your option) any later version.
9 | #
10 | # This library is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Lesser General Public
16 | # License along with this library. If not, see .
17 |
18 | #
19 | # Declare arrays used in the config file
20 | #
21 |
22 | # IRC target associative arrays
23 | declare -A IRC_TARGET_SERVER
24 | declare -A IRC_TARGET_PORT
25 | declare -A IRC_TARGET_CHANNEL
26 | declare -A IRC_TARGET_NICK
27 | declare -A IRC_TARGET_JOIN
28 | declare -A IRC_TARGET_FILTER
29 |
30 | REMOTES_LIST=()
31 | declare -A REMOTES_FLATPAKREPO
32 | declare -A REMOTES_ARGS
33 |
34 | BASE_DEP_LIST=()
35 | declare -A BASE_DEP_REMOTE
36 | declare -A BASE_DEP_REFS
37 |
38 | # Various build type lists and their
39 | # corresponding associative arrays
40 | BASE_SDK_LIST=()
41 | declare -A BASE_SDK_REPO
42 | declare -A BASE_SDK_REPO_SUFFIX
43 | declare -A BASE_SDK_BRANCH
44 | declare -A BASE_SDK_VERSION
45 | declare -A BASE_SDK_ASSETS
46 | declare -A BASE_SDK_IRC_TARGETS
47 |
48 | SDK_LIST=()
49 | declare -A SDK_REPO
50 | declare -A SDK_REPO_SUFFIX
51 | declare -A SDK_BRANCH
52 | declare -A SDK_VERSION
53 | declare -A SDK_ASSETS
54 | declare -A SDK_EXTRA_TARGETS
55 | declare -A SDK_IRC_TARGETS
56 |
57 | APP_LIST=()
58 | declare -A APP_REPO
59 | declare -A APP_REPO_SUFFIX
60 | declare -A APP_BRANCH
61 | declare -A APP_VERSION
62 | declare -A APP_ASSETS
63 | declare -A APP_IRC_TARGETS
64 | declare -A APP_BUILDER_ARGS
65 |
66 | # Source the actual config which will populate the arrays
67 | . ${arg_config}
68 |
--------------------------------------------------------------------------------
/data/build-launcher.sh.in:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright (C) 2016 Endless Mobile, Inc.
3 | # Author: Tristan Van Berkom
4 | #
5 | # This program is free software; you can redistribute it and/or
6 | # modify it under the terms of the GNU Lesser General Public
7 | # License as published by the Free Software Foundation; either
8 | # version 2 of the License, or (at your option) any later version.
9 | #
10 | # This library is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Lesser General Public
16 | # License along with this library. If not, see .
17 |
18 |
19 | # Begin exclusive locking, this will abort the build for --interval
20 | # invocations or block for --schedule invocations
21 | exec 201> @@WORKDIR@@/build_lock
22 | if ! flock @@FLOCKNOBLOCK@@ 201 ; then
23 | exit 1
24 | fi
25 |
26 | # Make sure flatpack and ostree are available in the cron job's PATH
27 | # also ensure the LD_LIBRARY_PATH is setup in case we built our tooling
28 | # into a non-standard prefix
29 | export PATH=@@PREFIX@@/bin:$PATH
30 | export LD_LIBRARY_PATH=@@PREFIX@@/lib:$LD_LIBRARY_PATH
31 |
32 | # Install the runtimes under the work dir rather than in ~/.local/share/
33 | export XDG_DATA_HOME=@@WORKDIR@@/share
34 |
35 | logdir=@@WORKDIR@@/export/logs/build-$(date +%Y-%m-%d-%H%M%S)
36 | logfile=${logdir}/build.txt
37 |
38 | mkdir -p "${logdir}"
39 |
40 | echo "====================================================" >> $logfile
41 | echo "Starting build at `date`" >> $logfile
42 | echo "====================================================" >> $logfile
43 |
44 | unconditional_arg=@@UNCONDITIONAL@@
45 |
46 | # Just manually time it in seconds
47 | #
48 | # We use a low priority for the build process to ensure that
49 | # apache's serving of logs and build results has priority over the builds.
50 | startime=$(date +%s)
51 | nice -n10 ionice -c2 @@TOPDIR@@/build-payload.sh \
52 | --workdir @@WORKDIR@@ --config @@CONFIG@@ \
53 | --headroom @@HEADROOMGB@@ --logdir ${logdir} \
54 | ${unconditional_arg} >> $logfile 2>&1
55 | error_code=$?
56 | endtime=$(date +%s)
57 |
58 | seconds=$((endtime-startime))
59 | duration=$((seconds/86400))" days "$(date -d "1970-01-01 + $seconds seconds" "+%H hours %M minutes %S seconds")
60 |
61 | echo "====================================================" >> $logfile
62 | if [ "${error_code}" -eq "0" ]; then
63 | echo "Build completed successfully in: $duration" >> $logfile
64 | echo "====================================================" >> $logfile
65 | if [ $(ls -Aq1 ${logdir} | wc -l) -le 1 ]; then
66 | # The directory has only the build.txt file, and there were no errors, lets
67 | # remove the entire directory, because its not interesting. We do it manually
68 | # instead of recursively in case something raced and created a logfile.
69 | # We still log this operation in case someone is tailing the file.
70 | echo "No builds were issued, removing log dir" >> $logfile
71 | rm ${logfile}
72 | rm -d ${logdir}
73 | fi
74 | else
75 | echo "Build failed in: $duration" >> $logfile
76 | echo "====================================================" >> $logfile
77 | fi
78 |
79 |
80 | # End exclusive lock
81 | exec 201>&-
82 |
--------------------------------------------------------------------------------
/extra/irc-notify.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | # Copyright (C) 2016 Endless Mobile, Inc.
3 | # Author: Tristan Van Berkom
4 | #
5 | # This program is free software; you can redistribute it and/or
6 | # modify it under the terms of the GNU Lesser General Public
7 | # License as published by the Free Software Foundation; either
8 | # version 2 of the License, or (at your option) any later version.
9 | #
10 | # This library is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Lesser General Public
16 | # License along with this library. If not, see .
17 |
18 |
19 | #
20 | # This is not a bot, only a very simple script to send a message to an
21 | # IRC channel and then quit.
22 | #
23 | import sys
24 | import argparse
25 | from twisted.internet import defer, endpoints, protocol, reactor, task
26 | from twisted.python import log
27 | from twisted.words.protocols import irc
28 |
29 | GREEN = 3
30 | RED = 4
31 | def irc_color(code, S):
32 | return "\x03%d%s\x03" % (code, S)
33 |
34 | class FlatpakIRCProtocol(irc.IRCClient):
35 |
36 | def __init__(self):
37 | global args
38 | self.nickname = args.nick
39 | self.deferred = defer.Deferred()
40 |
41 | def connectionLost(self, reason):
42 | # TODO: Check if we lost the connection because we quit,
43 | # if it's another error we should ensure an error status is returned.
44 | reactor.stop()
45 |
46 | def signedOn(self):
47 | global args
48 | for channel in self.factory.channels:
49 | if args.join:
50 | self.join(channel)
51 |
52 | if args.type == 'success':
53 | self.msg(channel, irc_color (GREEN, args.message))
54 | elif args.type == 'fail':
55 | self.msg(channel, irc_color (RED, args.message))
56 | else:
57 | self.msg(channel, args.message)
58 |
59 | self.quit()
60 |
61 | def _showError(self, failure):
62 | return failure.getErrorMessage()
63 |
64 |
65 | class FlatpakIRCFactory(protocol.ReconnectingClientFactory):
66 | def __init__(self):
67 | global args
68 | self.protocol = FlatpakIRCProtocol
69 | self.channels = [ args.channel ]
70 |
71 | def main(reactor, description):
72 | endpoint = endpoints.clientFromString(reactor, description)
73 | factory = FlatpakIRCFactory()
74 | d = endpoint.connect(factory)
75 | d.addCallback(lambda protocol: protocol.deferred)
76 | return d
77 |
78 | # Copy of task.react, because it doesn't exist in RHEL7 version of twisted
79 | def task_react(task, main, argv=(), _reactor=None):
80 | if _reactor is None:
81 | from twisted.internet import reactor as _reactor
82 | finished = main(_reactor, *argv)
83 | codes = [0]
84 | stopping = []
85 |
86 | _reactor.addSystemEventTrigger('before', 'shutdown', stopping.append, True)
87 |
88 | def stop(result, stopReactor):
89 | if stopReactor:
90 | try:
91 | _reactor.stop()
92 | except ReactorNotRunning:
93 | pass
94 |
95 | if isinstance(result, Failure):
96 | if result.check(SystemExit) is not None:
97 | code = result.value.code
98 | else:
99 | log.err(result, "main function encountered error")
100 | code = 1
101 | codes[0] = code
102 |
103 | def cbFinish(result):
104 | if stopping:
105 | stop(result, False)
106 | else:
107 | _reactor.callWhenRunning(stop, result, True)
108 |
109 | finished.addBoth(cbFinish)
110 | _reactor.run()
111 | sys.exit(codes[0])
112 |
113 | if __name__ == '__main__':
114 | parser = argparse.ArgumentParser()
115 | parser.add_argument ('-s', dest='server', required=True,
116 | help="The IRC server to connect to")
117 | parser.add_argument ('-p', dest='port', default='6667',
118 | help="The port to connect to (default: 6667)")
119 | parser.add_argument ('-c', dest='channel', required=True,
120 | help="The channel to announce in")
121 | parser.add_argument ('-n', dest='nick', required=True,
122 | help="The nickname to use")
123 | parser.add_argument ('-t', dest='type', default='regular', choices=['success', 'fail', 'regular'],
124 | help="Type of message to send")
125 | parser.add_argument ('--nojoin', dest='join', action='store_false',
126 | help="Send the message to channel without joining")
127 | parser.add_argument ('message')
128 | args = parser.parse_args()
129 |
130 | connect_str = 'tcp:' + args.server + ':' + args.port
131 | log.startLogging(sys.stderr)
132 | task_react(task, main, [ connect_str ])
133 |
--------------------------------------------------------------------------------
/include/build-source-flatpak.sh:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2016 Endless Mobile, Inc.
2 | # Author: Tristan Van Berkom
3 | #
4 | # This program is free software; you can redistribute it and/or
5 | # modify it under the terms of the GNU Lesser General Public
6 | # License as published by the Free Software Foundation; either
7 | # version 2 of the License, or (at your option) any later version.
8 | #
9 | # This library is distributed in the hope that it will be useful,
10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | # Lesser General Public License for more details.
13 | #
14 | # You should have received a copy of the GNU Lesser General Public
15 | # License along with this library. If not, see .
16 |
17 | # A build source to build a few known
18 | # types of flatpak related repository structures
19 |
20 | flatpak_remote_args="--user --no-gpg-verify"
21 | flatpak_install_args="--user"
22 | flatpak_subdir=".flatpak-builder"
23 | flatpak_build_subdir="${flatpak_subdir}/build"
24 |
25 | #
26 | # Ensures a remote exists and points to
27 | # the common repo
28 | #
29 | function flatpakEnsureRemote() {
30 | local repo_suffix=$1
31 | local flatpak_repo="${build_source_workdir}/export/repo${repo_suffix}"
32 | local flatpak_remote="builds${repo_suffix}"
33 |
34 | local error_code
35 | local repo_url="file://${flatpak_repo}"
36 |
37 | echo "Ensuring the global remote exists and points to: ${repo_url}"
38 | flatpak remote-add ${flatpak_remote_args} ${flatpak_remote} ${repo_url} > /dev/null 2>&1
39 | error_code=$?
40 |
41 | # If it errors, assume it's because it exists
42 | if [ "${error_code}" -ne "0" ]; then
43 | flatpak remote-modify ${flatpak_remote_args} ${flatpak_remote} --url ${repo_url} > /dev/null 2>&1
44 | error_code=$?
45 |
46 | # If it exists, just update it's remote uri
47 | if [ "${error_code}" -ne "0" ]; then
48 |
49 | # This shouldnt happen
50 | dienow "Failed to ensure our global remote at: ${repo_url}"
51 | fi
52 | fi
53 | }
54 |
55 | #
56 | # Installs an asset into the remote
57 | # $1 The asset to install
58 | # $2 The version/branch to install
59 | #
60 | function flatpakInstallAsset() {
61 | local asset=$1
62 | local branch=$2
63 | local repo_suffix=$3
64 | local flatpak_remote="builds${repo_suffix}"
65 | local error_code
66 |
67 | echo "Installing asset ${asset} at branch ${branch} to repo${repo_suffix}"
68 |
69 | local arch_arg="--arch=${build_source_arch}"
70 |
71 | # We both install (which is skipped if already installed) and update
72 | flatpak install -y ${flatpak_install_args} ${arch_arg} ${flatpak_remote} ${asset}//${branch} || \
73 | dienow "Failed to install: ${asset}/${branch} from remote ${flatpak_remote}"
74 |
75 | flatpak update -y ${flatpak_install_args} ${arch_arg} ${asset}//${branch} || \
76 | dienow "Failed to update: ${asset}/${branch} from remote ${flatpak_remote}"
77 | }
78 |
79 | function composeGpgArgs() {
80 | if [ ! -z "${BUILD_GPG_KEY}" ]; then
81 | if [ ! -z "${BUILD_GPG_HOMEDIR}" ]; then
82 | echo "--gpg-sign=${BUILD_GPG_KEY} --gpg-homedir=${BUILD_GPG_HOMEDIR}"
83 | else
84 | echo "--gpg-sign=${BUILD_GPG_KEY}"
85 | fi
86 | fi
87 | }
88 |
89 | #############################################
90 | # freedesktop-sdk-base #
91 | #############################################
92 | function buildInstallFlatpakBase() {
93 | local module=$1
94 | local changed=$2
95 | local assets=(${BASE_SDK_ASSETS["${module}"]})
96 | local version=${BASE_SDK_VERSION["${module}"]}
97 | local repo_suffix=${BASE_SDK_REPO_SUFFIX["${module}"]}
98 | local flatpak_repo="${build_source_workdir}/export/repo${repo_suffix}"
99 | local flatpak_remote="builds${repo_suffix}"
100 | local branch=${build_source_branches["${module}"]}
101 | local archdir="${build_source_build}/${build_source_arch}"
102 | local moduledir="${archdir}/${module}"
103 | local gpg_arg=$(composeGpgArgs)
104 | local error_code
105 | args=()
106 |
107 | # No need to build the base runtime if the gits didnt change
108 | if [ "${changed}" -eq "0" ]; then
109 | echo "Module ${module} is up to date, not rebuilding"
110 | return
111 | fi
112 |
113 | notifyIrcTarget ${module} "regular" "build-${module}-${build_source_arch}.txt" "Starting runtime build"
114 | cd "${moduledir}" || dienow
115 |
116 | args+=("ARCH=${build_source_arch}")
117 | args+=("REPO=${flatpak_repo}")
118 | if [ ! -z "${gpg_arg}" ]; then
119 | args+=("GPG_ARGS=${gpg_arg}")
120 | fi
121 |
122 | if [ ! -z "${build_source_logdir}" ]; then
123 | make "${args[@]}" > "${build_source_logdir}/build-${module}-${build_source_arch}.txt" 2>&1
124 | else
125 | make "${args[@]}"
126 | fi
127 | error_code=$?
128 |
129 | # Make an announcement
130 | if [ "${error_code}" -ne "0" ]; then
131 | notifyIrcTarget ${module} "fail" "build-${module}-${build_source_arch}.txt" "Runtime build failed"
132 | else
133 | notifyIrcTarget ${module} "success" "build-${module}-${build_source_arch}.txt" "Runtime build success"
134 | fi
135 |
136 | # A runtime build failure is fatal, we can't build anything else without it
137 | # However, we return an error so we can build the other arches
138 | [ "${error_code}" -ne "0" ] && return 1
139 |
140 | # Ensure there is a remote and install
141 | flatpakEnsureRemote ${repo_suffix}
142 | for asset in ${assets[@]}; do
143 | flatpakInstallAsset "${asset}" "${version}" "${repo_suffix}"
144 | done
145 | return 0
146 | }
147 |
148 | #############################################
149 | # SDKS #
150 | #############################################
151 | function buildInstallFlatpakSdk() {
152 | local module=$1
153 | local changed=$2
154 | local assets=(${SDK_ASSETS["${module}"]})
155 | local version=${SDK_VERSION["${module}"]}
156 | local extra_targets=${SDK_EXTRA_TARGETS["${module}"]}
157 | local repo_suffix=${SDK_REPO_SUFFIX["${module}"]}
158 | local flatpak_repo="${build_source_workdir}/export/repo${repo_suffix}"
159 | local flatpak_remote="builds${repo_suffix}"
160 | local branch=${build_source_branches["${module}"]}
161 | local archdir="${build_source_build}/${build_source_arch}"
162 | local moduledir="${archdir}/${module}"
163 | local gpg_arg=$(composeGpgArgs)
164 | local error_code
165 | args=()
166 |
167 | # Bail out if we asked for a conditional build and nothing changed
168 | if ! ${build_source_unconditional}; then
169 | if [ "${changed}" -eq "0" ]; then
170 | echo "Module ${module} is up to date, not rebuilding"
171 | return
172 | fi
173 | fi
174 |
175 | notifyIrcTarget ${module} "regular" "build-${module}-${build_source_arch}.txt" "Starting SDK build"
176 | cd "${moduledir}" || dienow
177 |
178 | args+=("ARCH=${build_source_arch}")
179 | args+=("REPO=${flatpak_repo}")
180 | if [ ! -z "${gpg_arg}" ]; then
181 | args+=("EXPORT_ARGS=${gpg_arg}")
182 | fi
183 |
184 | if [ ! -z "${build_source_logdir}" ]; then
185 | make "${args[@]}" > "${build_source_logdir}/build-${module}-${build_source_arch}.txt" 2>&1
186 | else
187 | make "${args[@]}"
188 | fi
189 | error_code=$?
190 |
191 | if [ "${error_code}" -eq "0" ]; then
192 | # Ensure there is a remote and install
193 | flatpakEnsureRemote ${repo_suffix}
194 | for asset in ${assets[@]}; do
195 | flatpakInstallAsset "${asset}" "${version}" "${repo_suffix}"
196 | done
197 |
198 | for extra_target in ${extra_targets[@]}; do
199 | if [ ! -z "${build_source_logdir}" ]; then
200 | make "${args[@]}" "${extra_target}" >> "${build_source_logdir}/build-${module}-${build_source_arch}.txt" 2>&1
201 | else
202 | make "${args[@]}" "${extra_target}"
203 | fi
204 | error_code=$?
205 | if [ "${error_code}" -ne "0" ]; then break; fi
206 | done
207 | fi
208 |
209 | # Make an announcement if something was built
210 | if [ -d "${moduledir}/sdk" ]; then
211 | if [ "${error_code}" -ne "0" ]; then
212 | notifyIrcTarget ${module} "fail" "build-${module}-${build_source_arch}.txt" "SDK build failed"
213 | else
214 | notifyIrcTarget ${module} "success" "build-${module}-${build_source_arch}.txt" "SDK build success"
215 | fi
216 |
217 | rm -rf "${moduledir}/sdk"
218 | else
219 | notifyIrcTarget ${module} "regular" "build-${module}-${build_source_arch}.txt" "SDK already up to date"
220 | fi
221 |
222 | # Failed builds will accumulate quickly in the build directory, zap em
223 | [ -d "${moduledir}/${flatpak_build_subdir}" ] && rm -rf "${moduledir}/${flatpak_build_subdir}"
224 |
225 | # An SDK build failure is fatal, we can't build the apps without knowing we have the SDK
226 | [ "${error_code}" -ne "0" ] && return 1
227 | return 0
228 | }
229 |
230 | #############################################
231 | # App json collections #
232 | #############################################
233 |
234 | function buildInstallFlatpakApps() {
235 | local module=$1
236 | local changed=$2
237 | local branch=${build_source_branches["${module}"]}
238 | local archdir="${build_source_build}/${build_source_arch}"
239 | local repo_suffix=${APP_REPO_SUFFIX["${module}"]}
240 | local flatpak_repo="${build_source_workdir}/export/repo${repo_suffix}"
241 | local flatpak_remote="builds${repo_suffix}"
242 | local moduledir="${archdir}/${module}"
243 | local app_id=
244 | local app_dir="${moduledir}/app"
245 | local gpg_arg=$(composeGpgArgs)
246 | local error_code
247 | args=()
248 |
249 | # Bail out if we asked for a conditional build and nothing changed
250 | if ! ${build_source_unconditional}; then
251 | args+=("--skip-if-unchanged")
252 | fi
253 |
254 | args+=("--repo=${flatpak_repo}")
255 | args+=("--arch=${build_source_arch}")
256 | args+=("--default-branch=${branch}")
257 | if [ ! -z "${gpg_arg}" ]; then
258 | args+=(${gpg_arg})
259 | fi
260 | if [ ! -z ${APP_BUILDER_ARGS["${module}"]} ]; then
261 | args+=(${APP_BUILDER_ARGS["${module}"]})
262 | fi
263 |
264 | # failing a build here is non-fatal, we want to try to
265 | # build all the apps even if some fail.
266 | cd "${moduledir}" || dienow
267 | for file in *.app; do
268 | app_id=$(basename $file .app)
269 |
270 | rm -rf ${app_dir}
271 |
272 | # We run the irc notification i parallel, because we want
273 | # to avoid doing any notitification at all for the
274 | # continuous case if the json was unchanged
275 | coproc IRCNOTIFY {
276 | # Try to read the error code, but time
277 | # out to check if the app directory
278 | # exists, which means the build has started
279 | while ! read -t 1 error_code; do
280 | if [ -d app ]; then
281 | break; # Build started, lets notify on it
282 | fi
283 | done
284 |
285 | if [ -d app ]; then
286 | notifyIrcTarget ${module} "regular" "build-${module}-${app_id}-${build_source_arch}.txt" "Starting build of '${app_id}'"
287 | fi
288 |
289 | # Wait until the build is done and we have the error code
290 | while [ -z "$error_code" ]; do
291 | read error_code
292 | done
293 |
294 | if [ -d app ]; then
295 | if [ "${error_code}" -ne "0" ]; then
296 | notifyIrcTarget ${module} "fail" "build-${module}-${app_id}-${build_source_arch}.txt" "App '${app_id}' build failed"
297 | else
298 | notifyIrcTarget ${module} "success" "build-${module}-${app_id}-${build_source_arch}.txt" "App '${app_id}' build success"
299 | fi
300 | elif ${build_source_unconditional}; then
301 | notifyIrcTarget ${module} "regular" "build-${module}-${app_id}-${build_source_arch}.txt" "App '${app_id}' already up to date"
302 | fi
303 | }
304 |
305 | if [ ! -z "${build_source_logdir}" ]; then
306 | ./build.sh $file "${args[@]}" > "${build_source_logdir}/build-${module}-${app_id}-${build_source_arch}.txt" 2>&1
307 | else
308 | ./build.sh $file "${args[@]}"
309 | fi
310 | error_code=$?
311 |
312 | # Make an announcement
313 | echo $error_code >&"${IRCNOTIFY[1]}"
314 | wait ${IRCNOTIFY_PID}
315 |
316 | # Error code 42 means we skipped the build due to unchanged file
317 | if [ "${error_code}" -eq "42" ]; then
318 | echo "No changes to app ${app_id} json, removing log"
319 | rm "${build_source_logdir}/build-${module}-${app_id}-${build_source_arch}.txt"
320 | elif [ "${error_code}" -ne "0" ]; then
321 | echo "Build failed: ${module}-${app_id}-${build_source_arch}"
322 | else
323 | echo "Build succeeded: ${module}-${app_id}-${build_source_arch}"
324 | fi
325 |
326 | rm -rf ${app_dir}
327 |
328 | # Failed builds will accumulate quickly in the build directory, zap em
329 | [ -d "${moduledir}/${flatpak_build_subdir}" ] && rm -rf "${moduledir}/${flatpak_build_subdir}"
330 | done
331 | return 0
332 | }
333 |
--------------------------------------------------------------------------------
/include/build-source.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Copyright (C) 2016 Endless Mobile, Inc.
3 | # Author: Tristan Van Berkom
4 | #
5 | # This program is free software; you can redistribute it and/or
6 | # modify it under the terms of the GNU Lesser General Public
7 | # License as published by the Free Software Foundation; either
8 | # version 2 of the License, or (at your option) any later version.
9 | #
10 | # This library is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 | # Lesser General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU Lesser General Public
16 | # License along with this library. If not, see .
17 |
18 |
19 | # An ordered table of sources with abstract
20 | # build functions.
21 | #
22 | build_source_modules=()
23 | declare -A build_source_repos
24 | declare -A build_source_branches
25 | declare -A build_source_funcs
26 | declare -A build_source_irc_targets
27 |
28 | #
29 | # The current module
30 | #
31 | build_source_current=
32 |
33 | #
34 | # Called in build source functions when the build fails
35 | #
36 | function dienow() {
37 | local errmsg=$1
38 |
39 | if [ ! -z "${build_source_current}" ]; then
40 | echo -n "Build of ${build_source_current} failed" 1>&2
41 | else
42 | echo -n "Build failed" 1>&2
43 | fi
44 |
45 | if [ ! -z "$errmsg" ]; then
46 | echo ": $1" 1>&2
47 | else
48 | echo 1>&2
49 | fi
50 |
51 | exit 1
52 | }
53 |
54 | # Checks whether the given word is found
55 | # in the given word list
56 | #
57 | # $1 - The word to check for
58 | # $2 - The word list
59 | #
60 | # Returns 0 (true in bash) if the word was
61 | # found, otherwise 1 (false) if the word was
62 | # not found.
63 | function wordInList() {
64 | local word=$1
65 | local list=($2)
66 |
67 | for iter in ${list[@]}; do
68 |
69 | if [ "${iter}" == "${word}" ]; then
70 | return 0
71 | fi
72 | done
73 |
74 | return 1;
75 | }
76 |
77 | # Checks if the amount of headroom required is
78 | # available on the filesystem where we perform builds
79 | #
80 | # $1 - Amount of desired GB of free space before a build
81 | #
82 | # Returns 0 (bash true) if the required space is available,
83 | # otherwise returns 1 (bash false)
84 | #
85 | function headroomAvailable() {
86 | local headroom_gb=$1
87 | local available_bytes=0
88 | local available_gb=0
89 |
90 | # Get the amount of free blocks * block size (bytes) available
91 | # to a regular user on the filesystem where builds occur.
92 | available_bytes=$(($(stat -f --format="%a*%S" ${build_source_workdir})))
93 |
94 | # Devide down to gigabytes
95 | available_gb=$((${available_bytes} / 1024 / 1024 / 1024))
96 |
97 | if [ $available_gb -lt $headroom_gb ]; then
98 | return 1
99 | fi
100 |
101 | return 0
102 | }
103 |
104 | function cullOstreeRepo() {
105 | for ostree_repo in ${build_source_workdir}/export/repo*; do
106 | if [ -d "${ostree_repo}" ]; then
107 | # Removes all but the latest commits of every existing branch
108 | # in the exported ostree repository (I.e. only keep the latest
109 | # build of everything)
110 | ostree prune --repo=${ostree_repo} --depth=0 --refs-only
111 | fi
112 | done
113 | }
114 |
115 | function purgeLogs() {
116 | local logdir="${build_source_workdir}/export/logs"
117 |
118 | rm -rf "${logdir}"
119 | }
120 |
121 | # Attempt to free space and ensure there
122 | # is enough space to perform the build.
123 | #
124 | # $1 - Amount of desired GB of free space before a build
125 | #
126 | function ensureHeadroomGigabytes() {
127 | local headroom_gb=$1
128 |
129 | if ! headroomAvailable ${headroom_gb}; then
130 |
131 | # First cull the ostree repository
132 | echo "Culling ostree repo for more space"
133 | cullOstreeRepo
134 |
135 | if ! headroomAvailable ${headroom_gb}; then
136 |
137 | # If culling the ostree repo was not enough, go ahead
138 | # and purge the logs as well
139 | echo "Purging logs for more space"
140 | purgeLogs
141 |
142 | if ! headroomAvailable ${headroom_gb}; then
143 | # Build server in need of maintenance, todo: Notify some global IRC target
144 | #
145 | dienow "Build server in need of maintenance, less than ${headroom_gb} GB of free space available before building"
146 | fi
147 | fi
148 | fi
149 | }
150 |
151 | #
152 | # Add a source to the array
153 | # $1 module name to add
154 | # $2 git repository url
155 | # $3 the branch name of the git module
156 | # $4 function to build with, like buildInstallAutotools()
157 | # $5 IRC target id wordlist
158 | #
159 | function buildSourceAdd() {
160 | local module=$1
161 | local repo=$2
162 | local branch=$3
163 | local build_func=$4
164 | local irc_targets=$5
165 |
166 | build_source_modules+=("${module}")
167 | build_source_repos["${module}"]="$repo"
168 | build_source_branches["${module}"]="$branch"
169 | build_source_funcs["${module}"]=${build_func}
170 | build_source_irc_targets["${module}"]="${irc_targets}"
171 | }
172 |
173 | # Reports whether the tip git commit ID has changed
174 | # after a checkout or update, stores the latest commit ID
175 | # in a file
176 | function buildSourceTrackChanges() {
177 | local module=$1
178 | local branch=${build_source_branches["${module}"]}
179 | local archdir="${build_source_build}/${build_source_arch}"
180 | local moduledir="${archdir}/${module}"
181 | local changed=0
182 |
183 | cd "${moduledir}" || dienow
184 |
185 | if [ ! -f "${archdir}/${module}.latest" ]; then
186 | git rev-parse "${branch}" > "${archdir}/${module}.latest"
187 | changed=1
188 | else
189 | git rev-parse "${branch}" > "${archdir}/${module}.new"
190 | if ! diff "${archdir}/${module}.new" "${archdir}/${module}.latest" > /dev/null; then
191 | cat "${archdir}/${module}.new" > "${archdir}/${module}.latest"
192 | changed=1
193 | fi
194 | rm -f "${archdir}/${module}.new"
195 | fi
196 |
197 | return ${changed}
198 | }
199 |
200 | function buildSourceCheckout() {
201 | local module=$1
202 | local branch=${build_source_branches["${module}"]}
203 | local repo=${build_source_repos["${module}"]}
204 | local archdir="${build_source_build}/${build_source_arch}"
205 |
206 | echo "Checking out ${module} from ${repo}"
207 | mkdir -p ${archdir} && cd "${archdir}" || dienow
208 |
209 | git clone ${repo} ${module} || dienow
210 | cd "${module}" || dienow
211 | git checkout ${branch} || dienow
212 |
213 | # Make sure we got the submodules
214 | git submodule init
215 | git submodule update
216 | }
217 |
218 | function buildSourceUpdate() {
219 | local module=$1
220 | local branch=${build_source_branches["${module}"]}
221 | local repo=${build_source_repos["${module}"]}
222 | local archdir="${build_source_build}/${build_source_arch}"
223 | local moduledir="${archdir}/${module}"
224 | local error_code
225 |
226 | echo "Fetching from ${repo}"
227 | cd "${moduledir}" || dienow
228 |
229 | # fetch will not fail in any recoverable way
230 | git fetch || dienow "Failed to fetch from '${repo}'"
231 |
232 | # deactivate submodules during the update
233 | git submodule deinit --force .
234 | error_code=$?
235 |
236 | # if we deactivated any submodules, then we have submodules
237 | if [ "${error_code}" -eq "0" ]; then
238 |
239 | # When a git module changes origin, it needs
240 | # a new checkout, only with --force
241 | if $build_source_force; then
242 | rm -rf "${moduledir}/.git/modules/*"
243 | fi
244 | fi
245 |
246 | # ensure we're on the right branch
247 | git checkout ${branch}
248 | error_code=$?
249 | if [ "${error_code}" -ne "0" ]; then
250 | if $build_source_force; then
251 | git clean -xdf || dienow "Unable to cleanup repository"
252 | git reset --hard ${branch} || dienow "Unable to hard reset repository"
253 | else
254 | dienow "Unable to checkout branch: ${branch} (try --force)"
255 | fi
256 | fi
257 |
258 | # get changes
259 | git pull --ff-only origin ${branch}
260 | error_code=$?
261 | if [ "${error_code}" -ne "0" ]; then
262 | if $build_source_force; then
263 |
264 | # Just nuke it and re-checkout
265 | rm -rf ${moduledir}
266 | buildSourceCheckout ${module}
267 | return
268 | else
269 | dienow "Failed to pull from origin branch: ${branch} (try --force)"
270 | fi
271 | fi
272 |
273 | # Make sure we got the submodules
274 | git submodule init
275 | git submodule update
276 | }
277 |
278 | # Reports exit status 0 if nothing has changed and 1 if the module
279 | # was freshly checked out or changed.
280 | #
281 | function buildSourceDownload() {
282 | local module=$1
283 | local changed=0
284 | local archdir="${build_source_build}/${build_source_arch}"
285 |
286 | build_source_current=${module}
287 |
288 | if [ -d "${archdir}/${module}" ]; then
289 | buildSourceUpdate ${module}
290 | else
291 | buildSourceCheckout ${module}
292 | fi
293 |
294 | # Check if the checkout was changed
295 | buildSourceTrackChanges ${module}
296 | changed=$?
297 |
298 | build_source_current=
299 |
300 | return $changed
301 | }
302 |
303 | #
304 | # Build a source by name, calling it's build_func
305 | # $1 module name to build
306 | # $2 whether the git checkout has changed (0 if unchanged)
307 | #
308 | function buildSourceBuild() {
309 | local module=$1
310 | local changed=$2
311 |
312 | build_source_current=${module}
313 | ${build_source_funcs["${module}"]} "${module}" "${changed}"
314 | build_source_current=
315 | }
316 |
317 | #
318 | # Run the build
319 | #
320 | # $1 - Amount of required disk space for the build, in gigabytes (optional)
321 | #
322 | # If the required disk space is not provided, no cleanup will be attempted
323 | #
324 | function buildSourceRun() {
325 | local headroom_gb=$1
326 | local module
327 | local arch
328 |
329 | if [ ! -z "${headroom_gb}" ]; then
330 | ensureHeadroomGigabytes ${headroom_gb}
331 | fi
332 |
333 | # If an array of build arches is unspecified, then
334 | # default it to ${build_source_arch}.
335 | if ! (( ${#BUILD_ARCHES[@]} )); then
336 | BUILD_ARCHES=(${build_source_arch})
337 | fi
338 |
339 | # If there is no build_source_arch, we are building the native
340 | # tooling and dont require any, just make it a dummy for the loop below
341 | if ! (( ${#BUILD_ARCHES[@]} )); then
342 | BUILD_ARCHES=("dummy")
343 | fi
344 |
345 | # Loop over the arches and set build_source_arch
346 | # for each iteration
347 | for arch in ${BUILD_ARCHES[@]}; do
348 |
349 | # Reset the arch for each iteration
350 | build_source_arch=${arch}
351 |
352 | if [ ! -z "${build_source_target}" ]; then
353 | buildSourceDownload "${build_source_target}"
354 | if ! buildSourceBuild "${build_source_target}" "$?"; then
355 | continue; # Some failures are fatal for the entire arch
356 | fi
357 | else
358 | for module in "${build_source_modules[@]}"; do
359 | buildSourceDownload "${module}"
360 | if ! buildSourceBuild "${module}" "$?"; then
361 | continue; # Some failures are fatal for the entire arch
362 | fi
363 | done
364 | fi
365 | done
366 | }
367 |
368 | #
369 | # Make an IRC announcement for the given module
370 | # $1 module name, as listed in build.conf
371 | # $2 message type, can be one of: regular,success,fail
372 | # $3 build log short name (without ${build_source_logdir})
373 | # $4 message to send
374 | #
375 | # The announcement will be made with the following format:
376 | #
377 | # [ ${module} (${branch}) - ${build_source_arch} ] : Log file location
378 | #
379 | function notifyIrcTarget() {
380 | local module=$1
381 | local message_type=$2
382 | local short_log=$3
383 | local message=$4
384 | local branch=${build_source_branches["${module}"]}
385 | local irc_targets=(${build_source_irc_targets[${module}]})
386 |
387 | # Unconditionally send the message to stdout so it gets into the logs
388 | echo "[ ${module} (${branch}) - ${build_source_arch} ] ${message}: ${short_log}"
389 |
390 | # Just early return if this module is not configured for IRC notifications
391 | if ! (( ${#irc_targets[@]} )); then
392 | echo "No IRC target configured for ${module}, not sending notification"
393 | return
394 | fi
395 |
396 | local full_log=${BUILD_URL}/${build_source_logdir#${build_source_export}}/${short_log}
397 | local full_message="[ ${module} (${branch}) - ${build_source_arch} ] ${message}: ${full_log}"
398 |
399 | for irc_target in ${irc_targets[@]}; do
400 | local irc_server=${IRC_TARGET_SERVER["${irc_target}"]}
401 | local irc_port=${IRC_TARGET_PORT["${irc_target}"]}
402 | local irc_channel=${IRC_TARGET_CHANNEL["${irc_target}"]}
403 | local irc_nick=${IRC_TARGET_NICK["${irc_target}"]}
404 | local irc_join=${IRC_TARGET_JOIN["${irc_target}"]}
405 | local irc_filter=${IRC_TARGET_FILTER["${irc_target}"]}
406 |
407 | # Filter out undesired message types for this IRC target
408 | if ! wordInList "${message_type}" "${irc_filter}"; then
409 | continue
410 | fi
411 |
412 | local args="-s ${irc_server} -p ${irc_port} -c ${irc_channel} -n ${irc_nick} -t ${message_type}"
413 | if [ "${irc_join}" != "yes" ]; then
414 | args=${args}" --nojoin"
415 | fi
416 |
417 | # We block annoyingly because we can launch many of them at the same time otherwise,
418 | # also we redirect to /dev/null just incase one day there is sensitive irc login information
419 | # that would otherwise end up in the master build.log
420 | #
421 | ${topdir}/extra/irc-notify.py ${args} "${full_message}" > /dev/null 2>&1
422 | done
423 | }
424 |
--------------------------------------------------------------------------------
/COPYING:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 2.1, February 1999
3 |
4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc.
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | [This is the first released version of the Lesser GPL. It also counts
10 | as the successor of the GNU Library Public License, version 2, hence
11 | the version number 2.1.]
12 |
13 | Preamble
14 |
15 | The licenses for most software are designed to take away your
16 | freedom to share and change it. By contrast, the GNU General Public
17 | Licenses are intended to guarantee your freedom to share and change
18 | free software--to make sure the software is free for all its users.
19 |
20 | This license, the Lesser General Public License, applies to some
21 | specially designated software packages--typically libraries--of the
22 | Free Software Foundation and other authors who decide to use it. You
23 | can use it too, but we suggest you first think carefully about whether
24 | this license or the ordinary General Public License is the better
25 | strategy to use in any particular case, based on the explanations below.
26 |
27 | When we speak of free software, we are referring to freedom of use,
28 | not price. Our General Public Licenses are designed to make sure that
29 | you have the freedom to distribute copies of free software (and charge
30 | for this service if you wish); that you receive source code or can get
31 | it if you want it; that you can change the software and use pieces of
32 | it in new free programs; and that you are informed that you can do
33 | these things.
34 |
35 | To protect your rights, we need to make restrictions that forbid
36 | distributors to deny you these rights or to ask you to surrender these
37 | rights. These restrictions translate to certain responsibilities for
38 | you if you distribute copies of the library or if you modify it.
39 |
40 | For example, if you distribute copies of the library, whether gratis
41 | or for a fee, you must give the recipients all the rights that we gave
42 | you. You must make sure that they, too, receive or can get the source
43 | code. If you link other code with the library, you must provide
44 | complete object files to the recipients, so that they can relink them
45 | with the library after making changes to the library and recompiling
46 | it. And you must show them these terms so they know their rights.
47 |
48 | We protect your rights with a two-step method: (1) we copyright the
49 | library, and (2) we offer you this license, which gives you legal
50 | permission to copy, distribute and/or modify the library.
51 |
52 | To protect each distributor, we want to make it very clear that
53 | there is no warranty for the free library. Also, if the library is
54 | modified by someone else and passed on, the recipients should know
55 | that what they have is not the original version, so that the original
56 | author's reputation will not be affected by problems that might be
57 | introduced by others.
58 |
59 | Finally, software patents pose a constant threat to the existence of
60 | any free program. We wish to make sure that a company cannot
61 | effectively restrict the users of a free program by obtaining a
62 | restrictive license from a patent holder. Therefore, we insist that
63 | any patent license obtained for a version of the library must be
64 | consistent with the full freedom of use specified in this license.
65 |
66 | Most GNU software, including some libraries, is covered by the
67 | ordinary GNU General Public License. This license, the GNU Lesser
68 | General Public License, applies to certain designated libraries, and
69 | is quite different from the ordinary General Public License. We use
70 | this license for certain libraries in order to permit linking those
71 | libraries into non-free programs.
72 |
73 | When a program is linked with a library, whether statically or using
74 | a shared library, the combination of the two is legally speaking a
75 | combined work, a derivative of the original library. The ordinary
76 | General Public License therefore permits such linking only if the
77 | entire combination fits its criteria of freedom. The Lesser General
78 | Public License permits more lax criteria for linking other code with
79 | the library.
80 |
81 | We call this license the "Lesser" General Public License because it
82 | does Less to protect the user's freedom than the ordinary General
83 | Public License. It also provides other free software developers Less
84 | of an advantage over competing non-free programs. These disadvantages
85 | are the reason we use the ordinary General Public License for many
86 | libraries. However, the Lesser license provides advantages in certain
87 | special circumstances.
88 |
89 | For example, on rare occasions, there may be a special need to
90 | encourage the widest possible use of a certain library, so that it becomes
91 | a de-facto standard. To achieve this, non-free programs must be
92 | allowed to use the library. A more frequent case is that a free
93 | library does the same job as widely used non-free libraries. In this
94 | case, there is little to gain by limiting the free library to free
95 | software only, so we use the Lesser General Public License.
96 |
97 | In other cases, permission to use a particular library in non-free
98 | programs enables a greater number of people to use a large body of
99 | free software. For example, permission to use the GNU C Library in
100 | non-free programs enables many more people to use the whole GNU
101 | operating system, as well as its variant, the GNU/Linux operating
102 | system.
103 |
104 | Although the Lesser General Public License is Less protective of the
105 | users' freedom, it does ensure that the user of a program that is
106 | linked with the Library has the freedom and the wherewithal to run
107 | that program using a modified version of the Library.
108 |
109 | The precise terms and conditions for copying, distribution and
110 | modification follow. Pay close attention to the difference between a
111 | "work based on the library" and a "work that uses the library". The
112 | former contains code derived from the library, whereas the latter must
113 | be combined with the library in order to run.
114 |
115 | GNU LESSER GENERAL PUBLIC LICENSE
116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
117 |
118 | 0. This License Agreement applies to any software library or other
119 | program which contains a notice placed by the copyright holder or
120 | other authorized party saying it may be distributed under the terms of
121 | this Lesser General Public License (also called "this License").
122 | Each licensee is addressed as "you".
123 |
124 | A "library" means a collection of software functions and/or data
125 | prepared so as to be conveniently linked with application programs
126 | (which use some of those functions and data) to form executables.
127 |
128 | The "Library", below, refers to any such software library or work
129 | which has been distributed under these terms. A "work based on the
130 | Library" means either the Library or any derivative work under
131 | copyright law: that is to say, a work containing the Library or a
132 | portion of it, either verbatim or with modifications and/or translated
133 | straightforwardly into another language. (Hereinafter, translation is
134 | included without limitation in the term "modification".)
135 |
136 | "Source code" for a work means the preferred form of the work for
137 | making modifications to it. For a library, complete source code means
138 | all the source code for all modules it contains, plus any associated
139 | interface definition files, plus the scripts used to control compilation
140 | and installation of the library.
141 |
142 | Activities other than copying, distribution and modification are not
143 | covered by this License; they are outside its scope. The act of
144 | running a program using the Library is not restricted, and output from
145 | such a program is covered only if its contents constitute a work based
146 | on the Library (independent of the use of the Library in a tool for
147 | writing it). Whether that is true depends on what the Library does
148 | and what the program that uses the Library does.
149 |
150 | 1. You may copy and distribute verbatim copies of the Library's
151 | complete source code as you receive it, in any medium, provided that
152 | you conspicuously and appropriately publish on each copy an
153 | appropriate copyright notice and disclaimer of warranty; keep intact
154 | all the notices that refer to this License and to the absence of any
155 | warranty; and distribute a copy of this License along with the
156 | Library.
157 |
158 | You may charge a fee for the physical act of transferring a copy,
159 | and you may at your option offer warranty protection in exchange for a
160 | fee.
161 |
162 | 2. You may modify your copy or copies of the Library or any portion
163 | of it, thus forming a work based on the Library, and copy and
164 | distribute such modifications or work under the terms of Section 1
165 | above, provided that you also meet all of these conditions:
166 |
167 | a) The modified work must itself be a software library.
168 |
169 | b) You must cause the files modified to carry prominent notices
170 | stating that you changed the files and the date of any change.
171 |
172 | c) You must cause the whole of the work to be licensed at no
173 | charge to all third parties under the terms of this License.
174 |
175 | d) If a facility in the modified Library refers to a function or a
176 | table of data to be supplied by an application program that uses
177 | the facility, other than as an argument passed when the facility
178 | is invoked, then you must make a good faith effort to ensure that,
179 | in the event an application does not supply such function or
180 | table, the facility still operates, and performs whatever part of
181 | its purpose remains meaningful.
182 |
183 | (For example, a function in a library to compute square roots has
184 | a purpose that is entirely well-defined independent of the
185 | application. Therefore, Subsection 2d requires that any
186 | application-supplied function or table used by this function must
187 | be optional: if the application does not supply it, the square
188 | root function must still compute square roots.)
189 |
190 | These requirements apply to the modified work as a whole. If
191 | identifiable sections of that work are not derived from the Library,
192 | and can be reasonably considered independent and separate works in
193 | themselves, then this License, and its terms, do not apply to those
194 | sections when you distribute them as separate works. But when you
195 | distribute the same sections as part of a whole which is a work based
196 | on the Library, the distribution of the whole must be on the terms of
197 | this License, whose permissions for other licensees extend to the
198 | entire whole, and thus to each and every part regardless of who wrote
199 | it.
200 |
201 | Thus, it is not the intent of this section to claim rights or contest
202 | your rights to work written entirely by you; rather, the intent is to
203 | exercise the right to control the distribution of derivative or
204 | collective works based on the Library.
205 |
206 | In addition, mere aggregation of another work not based on the Library
207 | with the Library (or with a work based on the Library) on a volume of
208 | a storage or distribution medium does not bring the other work under
209 | the scope of this License.
210 |
211 | 3. You may opt to apply the terms of the ordinary GNU General Public
212 | License instead of this License to a given copy of the Library. To do
213 | this, you must alter all the notices that refer to this License, so
214 | that they refer to the ordinary GNU General Public License, version 2,
215 | instead of to this License. (If a newer version than version 2 of the
216 | ordinary GNU General Public License has appeared, then you can specify
217 | that version instead if you wish.) Do not make any other change in
218 | these notices.
219 |
220 | Once this change is made in a given copy, it is irreversible for
221 | that copy, so the ordinary GNU General Public License applies to all
222 | subsequent copies and derivative works made from that copy.
223 |
224 | This option is useful when you wish to copy part of the code of
225 | the Library into a program that is not a library.
226 |
227 | 4. You may copy and distribute the Library (or a portion or
228 | derivative of it, under Section 2) in object code or executable form
229 | under the terms of Sections 1 and 2 above provided that you accompany
230 | it with the complete corresponding machine-readable source code, which
231 | must be distributed under the terms of Sections 1 and 2 above on a
232 | medium customarily used for software interchange.
233 |
234 | If distribution of object code is made by offering access to copy
235 | from a designated place, then offering equivalent access to copy the
236 | source code from the same place satisfies the requirement to
237 | distribute the source code, even though third parties are not
238 | compelled to copy the source along with the object code.
239 |
240 | 5. A program that contains no derivative of any portion of the
241 | Library, but is designed to work with the Library by being compiled or
242 | linked with it, is called a "work that uses the Library". Such a
243 | work, in isolation, is not a derivative work of the Library, and
244 | therefore falls outside the scope of this License.
245 |
246 | However, linking a "work that uses the Library" with the Library
247 | creates an executable that is a derivative of the Library (because it
248 | contains portions of the Library), rather than a "work that uses the
249 | library". The executable is therefore covered by this License.
250 | Section 6 states terms for distribution of such executables.
251 |
252 | When a "work that uses the Library" uses material from a header file
253 | that is part of the Library, the object code for the work may be a
254 | derivative work of the Library even though the source code is not.
255 | Whether this is true is especially significant if the work can be
256 | linked without the Library, or if the work is itself a library. The
257 | threshold for this to be true is not precisely defined by law.
258 |
259 | If such an object file uses only numerical parameters, data
260 | structure layouts and accessors, and small macros and small inline
261 | functions (ten lines or less in length), then the use of the object
262 | file is unrestricted, regardless of whether it is legally a derivative
263 | work. (Executables containing this object code plus portions of the
264 | Library will still fall under Section 6.)
265 |
266 | Otherwise, if the work is a derivative of the Library, you may
267 | distribute the object code for the work under the terms of Section 6.
268 | Any executables containing that work also fall under Section 6,
269 | whether or not they are linked directly with the Library itself.
270 |
271 | 6. As an exception to the Sections above, you may also combine or
272 | link a "work that uses the Library" with the Library to produce a
273 | work containing portions of the Library, and distribute that work
274 | under terms of your choice, provided that the terms permit
275 | modification of the work for the customer's own use and reverse
276 | engineering for debugging such modifications.
277 |
278 | You must give prominent notice with each copy of the work that the
279 | Library is used in it and that the Library and its use are covered by
280 | this License. You must supply a copy of this License. If the work
281 | during execution displays copyright notices, you must include the
282 | copyright notice for the Library among them, as well as a reference
283 | directing the user to the copy of this License. Also, you must do one
284 | of these things:
285 |
286 | a) Accompany the work with the complete corresponding
287 | machine-readable source code for the Library including whatever
288 | changes were used in the work (which must be distributed under
289 | Sections 1 and 2 above); and, if the work is an executable linked
290 | with the Library, with the complete machine-readable "work that
291 | uses the Library", as object code and/or source code, so that the
292 | user can modify the Library and then relink to produce a modified
293 | executable containing the modified Library. (It is understood
294 | that the user who changes the contents of definitions files in the
295 | Library will not necessarily be able to recompile the application
296 | to use the modified definitions.)
297 |
298 | b) Use a suitable shared library mechanism for linking with the
299 | Library. A suitable mechanism is one that (1) uses at run time a
300 | copy of the library already present on the user's computer system,
301 | rather than copying library functions into the executable, and (2)
302 | will operate properly with a modified version of the library, if
303 | the user installs one, as long as the modified version is
304 | interface-compatible with the version that the work was made with.
305 |
306 | c) Accompany the work with a written offer, valid for at
307 | least three years, to give the same user the materials
308 | specified in Subsection 6a, above, for a charge no more
309 | than the cost of performing this distribution.
310 |
311 | d) If distribution of the work is made by offering access to copy
312 | from a designated place, offer equivalent access to copy the above
313 | specified materials from the same place.
314 |
315 | e) Verify that the user has already received a copy of these
316 | materials or that you have already sent this user a copy.
317 |
318 | For an executable, the required form of the "work that uses the
319 | Library" must include any data and utility programs needed for
320 | reproducing the executable from it. However, as a special exception,
321 | the materials to be distributed need not include anything that is
322 | normally distributed (in either source or binary form) with the major
323 | components (compiler, kernel, and so on) of the operating system on
324 | which the executable runs, unless that component itself accompanies
325 | the executable.
326 |
327 | It may happen that this requirement contradicts the license
328 | restrictions of other proprietary libraries that do not normally
329 | accompany the operating system. Such a contradiction means you cannot
330 | use both them and the Library together in an executable that you
331 | distribute.
332 |
333 | 7. You may place library facilities that are a work based on the
334 | Library side-by-side in a single library together with other library
335 | facilities not covered by this License, and distribute such a combined
336 | library, provided that the separate distribution of the work based on
337 | the Library and of the other library facilities is otherwise
338 | permitted, and provided that you do these two things:
339 |
340 | a) Accompany the combined library with a copy of the same work
341 | based on the Library, uncombined with any other library
342 | facilities. This must be distributed under the terms of the
343 | Sections above.
344 |
345 | b) Give prominent notice with the combined library of the fact
346 | that part of it is a work based on the Library, and explaining
347 | where to find the accompanying uncombined form of the same work.
348 |
349 | 8. You may not copy, modify, sublicense, link with, or distribute
350 | the Library except as expressly provided under this License. Any
351 | attempt otherwise to copy, modify, sublicense, link with, or
352 | distribute the Library is void, and will automatically terminate your
353 | rights under this License. However, parties who have received copies,
354 | or rights, from you under this License will not have their licenses
355 | terminated so long as such parties remain in full compliance.
356 |
357 | 9. You are not required to accept this License, since you have not
358 | signed it. However, nothing else grants you permission to modify or
359 | distribute the Library or its derivative works. These actions are
360 | prohibited by law if you do not accept this License. Therefore, by
361 | modifying or distributing the Library (or any work based on the
362 | Library), you indicate your acceptance of this License to do so, and
363 | all its terms and conditions for copying, distributing or modifying
364 | the Library or works based on it.
365 |
366 | 10. Each time you redistribute the Library (or any work based on the
367 | Library), the recipient automatically receives a license from the
368 | original licensor to copy, distribute, link with or modify the Library
369 | subject to these terms and conditions. You may not impose any further
370 | restrictions on the recipients' exercise of the rights granted herein.
371 | You are not responsible for enforcing compliance by third parties with
372 | this License.
373 |
374 | 11. If, as a consequence of a court judgment or allegation of patent
375 | infringement or for any other reason (not limited to patent issues),
376 | conditions are imposed on you (whether by court order, agreement or
377 | otherwise) that contradict the conditions of this License, they do not
378 | excuse you from the conditions of this License. If you cannot
379 | distribute so as to satisfy simultaneously your obligations under this
380 | License and any other pertinent obligations, then as a consequence you
381 | may not distribute the Library at all. For example, if a patent
382 | license would not permit royalty-free redistribution of the Library by
383 | all those who receive copies directly or indirectly through you, then
384 | the only way you could satisfy both it and this License would be to
385 | refrain entirely from distribution of the Library.
386 |
387 | If any portion of this section is held invalid or unenforceable under any
388 | particular circumstance, the balance of the section is intended to apply,
389 | and the section as a whole is intended to apply in other circumstances.
390 |
391 | It is not the purpose of this section to induce you to infringe any
392 | patents or other property right claims or to contest validity of any
393 | such claims; this section has the sole purpose of protecting the
394 | integrity of the free software distribution system which is
395 | implemented by public license practices. Many people have made
396 | generous contributions to the wide range of software distributed
397 | through that system in reliance on consistent application of that
398 | system; it is up to the author/donor to decide if he or she is willing
399 | to distribute software through any other system and a licensee cannot
400 | impose that choice.
401 |
402 | This section is intended to make thoroughly clear what is believed to
403 | be a consequence of the rest of this License.
404 |
405 | 12. If the distribution and/or use of the Library is restricted in
406 | certain countries either by patents or by copyrighted interfaces, the
407 | original copyright holder who places the Library under this License may add
408 | an explicit geographical distribution limitation excluding those countries,
409 | so that distribution is permitted only in or among countries not thus
410 | excluded. In such case, this License incorporates the limitation as if
411 | written in the body of this License.
412 |
413 | 13. The Free Software Foundation may publish revised and/or new
414 | versions of the Lesser General Public License from time to time.
415 | Such new versions will be similar in spirit to the present version,
416 | but may differ in detail to address new problems or concerns.
417 |
418 | Each version is given a distinguishing version number. If the Library
419 | specifies a version number of this License which applies to it and
420 | "any later version", you have the option of following the terms and
421 | conditions either of that version or of any later version published by
422 | the Free Software Foundation. If the Library does not specify a
423 | license version number, you may choose any version ever published by
424 | the Free Software Foundation.
425 |
426 | 14. If you wish to incorporate parts of the Library into other free
427 | programs whose distribution conditions are incompatible with these,
428 | write to the author to ask for permission. For software which is
429 | copyrighted by the Free Software Foundation, write to the Free
430 | Software Foundation; we sometimes make exceptions for this. Our
431 | decision will be guided by the two goals of preserving the free status
432 | of all derivatives of our free software and of promoting the sharing
433 | and reuse of software generally.
434 |
435 | NO WARRANTY
436 |
437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
446 |
447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
456 | DAMAGES.
457 |
458 | END OF TERMS AND CONDITIONS
459 |
460 | How to Apply These Terms to Your New Libraries
461 |
462 | If you develop a new library, and you want it to be of the greatest
463 | possible use to the public, we recommend making it free software that
464 | everyone can redistribute and change. You can do so by permitting
465 | redistribution under these terms (or, alternatively, under the terms of the
466 | ordinary General Public License).
467 |
468 | To apply these terms, attach the following notices to the library. It is
469 | safest to attach them to the start of each source file to most effectively
470 | convey the exclusion of warranty; and each file should have at least the
471 | "copyright" line and a pointer to where the full notice is found.
472 |
473 |
474 | Copyright (C)
475 |
476 | This library is free software; you can redistribute it and/or
477 | modify it under the terms of the GNU Lesser General Public
478 | License as published by the Free Software Foundation; either
479 | version 2.1 of the License, or (at your option) any later version.
480 |
481 | This library is distributed in the hope that it will be useful,
482 | but WITHOUT ANY WARRANTY; without even the implied warranty of
483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
484 | Lesser General Public License for more details.
485 |
486 | You should have received a copy of the GNU Lesser General Public
487 | License along with this library; if not, write to the Free Software
488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
489 |
490 | Also add information on how to contact you by electronic and paper mail.
491 |
492 | You should also get your employer (if you work as a programmer) or your
493 | school, if any, to sign a "copyright disclaimer" for the library, if
494 | necessary. Here is a sample; alter the names:
495 |
496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the
497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker.
498 |
499 | , 1 April 1990
500 | Ty Coon, President of Vice
501 |
502 | That's all there is to it!
503 |
--------------------------------------------------------------------------------