2018-02-21 14:28:25 +00:00
|
|
|
ROUTINE DEVELOPMENT
|
|
|
|
|
|
|
|
Default:
|
|
|
|
|
|
|
|
./configure --enable-werror --disable-shared
|
|
|
|
|
|
|
|
Debugging:
|
|
|
|
|
|
|
|
./configure CFLAGS="-g" CXXFLAGS="-g" --enable-werror --disable-shared
|
|
|
|
|
|
|
|
Memory checks:
|
|
|
|
|
2018-12-17 16:51:38 +00:00
|
|
|
./configure CFLAGS="-fsanitize=address -fsanitize=undefined -g" \
|
|
|
|
CXXFLAGS="-fsanitize=address -fsanitize=undefined -g" \
|
|
|
|
LDFLAGS="-fsanitize=address -fsanitize=undefined" \
|
2018-02-21 14:28:25 +00:00
|
|
|
--enable-werror --disable-shared
|
|
|
|
|
|
|
|
|
|
|
|
CODING RULES
|
|
|
|
|
|
|
|
* Avoid atoi. Use QUtil::string_to_int instead. It does
|
|
|
|
overflow/underflow checking.
|
|
|
|
|
|
|
|
* Remember to avoid using `operator[]` with `std::string` or
|
|
|
|
`std::vector`. Instead, use `at()`. See README-hardening.md for
|
|
|
|
details.
|
|
|
|
|
|
|
|
|
|
|
|
RELEASE PREPARATION
|
|
|
|
|
|
|
|
* Each year, update copyright notices. Just do a case-insensitive
|
|
|
|
search for copyright. Don't forget copyright in manual. Also update
|
2019-01-07 12:54:55 +00:00
|
|
|
debian copyright in debian package. Last updated: 2019.
|
2018-02-21 14:28:25 +00:00
|
|
|
|
2017-08-22 17:23:49 +00:00
|
|
|
* Check all open issues in the sourceforge trackers and on github.
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
* Check `TODO` file to make sure all planned items for the release are
|
|
|
|
done or retargeted.
|
|
|
|
|
|
|
|
* Run a spelling checker over the source code to catch errors in
|
|
|
|
variable names, strings, and comments.
|
|
|
|
|
2019-01-07 12:56:46 +00:00
|
|
|
ispell -p ispell-words **/*.hh **/*.cc manual/* ChangeLog README*
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
* If needed, run large file and image comparison tests. Configure
|
|
|
|
options:
|
|
|
|
|
|
|
|
--enable-test-compare-images --with-large-file-test-path=/path
|
|
|
|
|
|
|
|
For Windows, use a Windows style path, not an MSYS path for large files.
|
|
|
|
|
2018-08-16 15:20:35 +00:00
|
|
|
* Test with clang. Pass `CC=clang CXX=clang++` to `./configure`. Test
|
|
|
|
with newer version of gcc if available.
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
* Test build on a mac.
|
|
|
|
|
|
|
|
* Test with address sanitizer as described above.
|
|
|
|
|
|
|
|
* A small handful of additional files have been taken from autotools
|
|
|
|
programs. These should probably be updated from time to time.
|
|
|
|
|
|
|
|
* `config.guess`, `config.sub`, `ltmain.sh`, and the `m4` directory:
|
|
|
|
these were created by running `libtoolize -c`. To update, run
|
|
|
|
`libtoolize -f -c` or remove the files and rerun `libtoolize`.
|
|
|
|
|
|
|
|
* Other files copied as indicated:
|
|
|
|
```
|
|
|
|
cp /usr/share/automake-1.11/install-sh .
|
|
|
|
cp /usr/share/automake-1.11/mkinstalldirs .
|
|
|
|
```
|
|
|
|
|
|
|
|
The entire contents of the `m4` directory came from `libtool.m4`. If
|
|
|
|
we had some additional local parts, we could also add those to the
|
|
|
|
`m4` directory. In order for this to work, it is necessary to run
|
|
|
|
`aclocal -I m4` before running `autoheader` and `autoconf`. The
|
|
|
|
`autogen.sh` script handles this.
|
|
|
|
|
|
|
|
* If any interfaces were added or changed, check C API to see whether
|
|
|
|
changes are appropriate there as well. If necessary, review the
|
|
|
|
casting policy in the manual, and ensure that integer types are
|
|
|
|
properly handled.
|
|
|
|
|
|
|
|
* Increment shared library version information as needed (`LT_*` in
|
|
|
|
`configure.ac`)
|
|
|
|
|
|
|
|
* Test for binary compatibility:
|
|
|
|
* Check out the last release
|
|
|
|
* ./autogen.sh && ./configure --enable-werror && make -j$(nproc)
|
|
|
|
* Check out the current version
|
|
|
|
* ./autogen.sh && ./configure --enable-werror && make -j$(nproc) build_libqpdf
|
|
|
|
* Checkout the last release
|
2018-06-23 01:12:26 +00:00
|
|
|
* make -k check NO_REBUILD=1
|
|
|
|
|
|
|
|
* Update release notes in manual. Look at diffs and ChangeLog. Update
|
|
|
|
release date in `manual/qpdf-manual.xml`. Remember to ensure that
|
|
|
|
the entities at the top of the document are consistent with the
|
|
|
|
release notes for both version and release date.
|
2018-02-21 14:28:25 +00:00
|
|
|
|
2017-08-22 17:23:49 +00:00
|
|
|
* Make sure version numbers are consistent in the following locations:
|
|
|
|
* configure.ac
|
|
|
|
* libqpdf/QPDF.cc
|
|
|
|
* manual/qpdf-manual.xml
|
|
|
|
`make_dist` verifies this consistency.
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
* Add a release entry to ChangeLog.
|
|
|
|
|
|
|
|
|
|
|
|
CREATING A RELEASE
|
|
|
|
|
2018-10-13 16:24:46 +00:00
|
|
|
* Push to master. The azure pipeline will create an artifact called
|
|
|
|
distribution which will contain all the distribution files. Download
|
|
|
|
these, verify the checksums from the job output, rename to remove
|
|
|
|
-ci from the names, and copy to the release archive area.
|
2018-02-25 14:27:14 +00:00
|
|
|
|
2018-10-13 16:24:46 +00:00
|
|
|
* Sign the source distribution:
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
version=x.y.z
|
2018-10-13 16:24:46 +00:00
|
|
|
gpg --detach-sign --armor qpdf-$version.tar.gz
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
* Build and test the debian package
|
|
|
|
|
|
|
|
* Sign the releases. The release archive area should contain the
|
|
|
|
Windows binaries, the AppImage, the source tarball, and the source
|
|
|
|
tarball signature.
|
|
|
|
|
|
|
|
\rm -f *.{md5,sha1,sha512}
|
|
|
|
files=(*)
|
|
|
|
for i in md5 sha1 sha512; do
|
|
|
|
${i}sum $files >| qpdf-$version.$i
|
|
|
|
gpg --clearsign --armor qpdf-$version.$i
|
|
|
|
mv qpdf-$version.$i.asc qpdf-$version.$i
|
|
|
|
done
|
2018-02-25 14:27:14 +00:00
|
|
|
chmod 444 *
|
|
|
|
chmod 555 *.AppImage
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
* When creating releases on github and sourceforge, remember to copy
|
|
|
|
`README-what-to-download.md` separately onto the download area if
|
|
|
|
needed.
|
|
|
|
|
2019-01-07 14:08:41 +00:00
|
|
|
* Ensure that the master branch has been to github. The rev-parse
|
|
|
|
command below should show the same commit hash for all its
|
|
|
|
arguments. Create and push a signed tag. This should be run with
|
|
|
|
HEAD pointing to the tip of master.
|
2018-02-25 14:27:14 +00:00
|
|
|
|
2019-01-07 14:08:41 +00:00
|
|
|
git rev-parse master upstream/master @
|
|
|
|
git tag -s release-qpdf-$version @ -m"qpdf $version"
|
2018-02-25 14:27:14 +00:00
|
|
|
git push upstream release-qpdf-$version
|
|
|
|
|
2019-01-07 14:08:41 +00:00
|
|
|
* In Azure Pipelines, retain the build that was used to generate the
|
|
|
|
release.
|
|
|
|
|
2018-02-21 14:28:25 +00:00
|
|
|
* Create a github release after pushing the tag. `gcurl` is an alias
|
|
|
|
that includes the auth token.
|
|
|
|
|
|
|
|
# Create release
|
2019-01-07 14:08:41 +00:00
|
|
|
TOKEN=$(cat ~/.github-token)
|
|
|
|
function gcurl() { curl -H "Authorization: token $TOKEN" ${1+"$@"} }
|
2018-02-21 14:28:25 +00:00
|
|
|
url=$(gcurl -s -XPOST https://api.github.com/repos/qpdf/qpdf/releases -d'{"tag_name": "release-qpdf-'$version'", "name": "qpdf '$version'", "draft": true}' | jq -r '.url')
|
|
|
|
|
|
|
|
# Get upload url
|
|
|
|
upload_url=$(gcurl -s $url | jq -r '.upload_url' | sed -E -e 's/\{.*\}//')
|
|
|
|
echo $upload_url
|
|
|
|
|
|
|
|
# Upload all the files. You can add a label attribute too, which
|
|
|
|
# overrides the name.
|
|
|
|
for i in *; do
|
|
|
|
mime=$(file -b --mime-type $i)
|
|
|
|
gcurl -H "Content-Type: $mime" --data-binary @$i "$upload_url?name=$i"
|
|
|
|
done
|
|
|
|
|
|
|
|
If needed, go onto github and make any manual updates such as
|
|
|
|
indicating a pre-release, adding release notes, etc.
|
|
|
|
|
|
|
|
# Publish release
|
|
|
|
gcurl -XPOST $url -d'{"draft": false}'
|
|
|
|
|
|
|
|
* Upload files to sourceforge. Make the source package the default for
|
|
|
|
all but Windows, and make the 32-bit mingw build the default for
|
|
|
|
Windows. Publish a news item manually on sourceforge.
|
|
|
|
|
|
|
|
* Update the web page to indicate the new version and to put the new
|
|
|
|
documentation in the `files` subdirectory of the website on
|
|
|
|
sourceforge.net.
|
|
|
|
|
|
|
|
* Email the qpdf-announce list.
|
|
|
|
|
|
|
|
|
|
|
|
OTHER NOTES
|
|
|
|
|
|
|
|
To construct a source distribution from a pristine checkout,
|
|
|
|
`make_dist` does the following:
|
|
|
|
|
|
|
|
./configure --enable-doc-maintenance --enable-werror
|
|
|
|
make build_manual
|
|
|
|
make distclean
|
|
|
|
|
|
|
|
To create a source release of external libs, do an export from the
|
|
|
|
version control system into a directory called `qpdf-external-libs`
|
|
|
|
and just make a zip file of the result called
|
|
|
|
`qpdf-external-libs-src.zip`. See the README.txt file there for
|
|
|
|
information on creating binary external libs releases. Run this from
|
|
|
|
the external-libs repository:
|
|
|
|
|
|
|
|
git archive --prefix=external-libs/ HEAD . | (cd /tmp; tar xf -)
|
|
|
|
cd /tmp
|
|
|
|
zip -r qpdf-external-libs-src.zip external-libs
|
|
|
|
|
|
|
|
When releasing on sourceforge, `external-libs` distributions go in
|
|
|
|
`external-libs/yyyymmdd`, and qpdf distributions go in `qpdf/vvv`.
|
|
|
|
|
2018-02-25 14:27:14 +00:00
|
|
|
For local iteration on the AppImage generation, follow the release
|
|
|
|
procedures for building the AppImage, but instead of passing git clone
|
|
|
|
options to the docker command, copy qpdf to /tmp/build. You can also
|
|
|
|
pass -e SKIP_TESTS=1 to docker to skip the test suite, useful for
|
|
|
|
rapid iteration. Set up /tmp/build as in the release process.
|
|
|
|
|
|
|
|
cp -a $PWD /tmp/build
|
|
|
|
docker run --privileged -ti --rm -e SKIP_TESTS=1 -v /tmp/build:/tmp/build qpdfbuild
|
|
|
|
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
GENERAL BUILD STUFF
|
|
|
|
|
|
|
|
QPDF uses autoconf and libtool but does not use automake. The only
|
|
|
|
files distributed with the qpdf source distribution that are not
|
|
|
|
controlled are `configure`, `libqpdf/qpdf/qpdf-config.h.in`,
|
|
|
|
`aclocal.m4`, and some documentation. See above for the steps required
|
|
|
|
to prepare a source distribution.
|
|
|
|
|
|
|
|
If building or editing documentation, configure with
|
|
|
|
`--enable-doc-maintenance`. This will ensure that all tools or files
|
|
|
|
required to validate and build documentation are available.
|
|
|
|
|
2018-10-11 21:23:31 +00:00
|
|
|
If you want to run `make maintainer-clean` or `make distclean` and you
|
|
|
|
haven't run `./configure`, you can pass `CLEAN=1` to make on the
|
|
|
|
command line to prevent it from complaining about configure not having
|
|
|
|
been run.
|
2018-02-21 14:28:25 +00:00
|
|
|
|
|
|
|
If you want to run checks without rerunning the build, pass
|
|
|
|
`NO_REBUILD=1` to make. This can be useful for special testing
|
|
|
|
scenarios such as validation of memory fixes or binary compatibility.
|
|
|
|
|
|
|
|
|
|
|
|
LOCAL WINDOWS TESTING PROCEDURE
|
2015-05-24 20:46:36 +00:00
|
|
|
|
|
|
|
This is what I do for routine testing on Windows.
|
|
|
|
|
2018-10-11 21:23:31 +00:00
|
|
|
From Windows, git clone from my Linux clone, and unzip
|
|
|
|
`external-libs`.
|
2015-05-24 20:46:36 +00:00
|
|
|
|
2018-02-21 14:28:25 +00:00
|
|
|
Look at `make_windows_releases`. Set up path the same way and run
|
|
|
|
whichever `./config-*` is appropriate for whichever compiler I need to
|
|
|
|
test with. Start one of the Visual Studio native compiler shells, and
|
|
|
|
from there, run one of the msys shells. The Visual Studio step is not
|
|
|
|
necessary if just building with mingw.
|