14543ef51SXin LI[](https://github.com/libexpat/libexpat/actions/workflows/linux.yml) 20a48773fSEric van Gyzen[](https://ci.appveyor.com/project/libexpat/libexpat) 36b2c1e49SXin LI[](https://repology.org/metapackage/expat/versions) 4cc68614dSXin LI[](https://sourceforge.net/projects/expat/files/) 5cc68614dSXin LI[](https://github.com/libexpat/libexpat/releases) 6*fe927888SPhilip Paeps[](https://www.bestpractices.dev/projects/10205) 70a48773fSEric van Gyzen 8ffd294a1SEnji Cooper> [!CAUTION] 9ffd294a1SEnji Cooper> 10ffd294a1SEnji Cooper> Expat is **understaffed** and without funding. 11ffd294a1SEnji Cooper> There is a [call for help with details](https://github.com/libexpat/libexpat/blob/master/expat/Changes) 12ffd294a1SEnji Cooper> at the top of the `Changes` file. 130a48773fSEric van Gyzen 14ffd294a1SEnji Cooper 15*fe927888SPhilip Paeps# Expat, Release 2.7.1 160a48773fSEric van Gyzen 174543ef51SXin LIThis is Expat, a C99 library for parsing 184543ef51SXin LI[XML 1.0 Fourth Edition](https://www.w3.org/TR/2006/REC-xml-20060816/), started by 19cc68614dSXin LI[James Clark](https://en.wikipedia.org/wiki/James_Clark_%28programmer%29) in 1997. 200a48773fSEric van GyzenExpat is a stream-oriented XML parser. This means that you register 210a48773fSEric van Gyzenhandlers with the parser before starting the parse. These handlers 220a48773fSEric van Gyzenare called when the parser discovers the associated structures in the 230a48773fSEric van Gyzendocument being parsed. A start tag is an example of the kind of 240a48773fSEric van Gyzenstructures for which you may register handlers. 250a48773fSEric van Gyzen 26*fe927888SPhilip PaepsExpat supports the following C99 compilers: 27cc68614dSXin LI 28*fe927888SPhilip Paeps- GNU GCC >=4.5 (for use from C) or GNU GCC >=4.8.1 (for use from C++) 296b2c1e49SXin LI- LLVM Clang >=3.5 30ffd294a1SEnji Cooper- Microsoft Visual Studio >=16.0/2019 (rolling `${today} minus 5 years`) 316b2c1e49SXin LI 32cc68614dSXin LIWindows users can use the 33cc68614dSXin LI[`expat-win32bin-*.*.*.{exe,zip}` download](https://github.com/libexpat/libexpat/releases), 34cc68614dSXin LIwhich includes both pre-compiled libraries and executables, and source code for 350a48773fSEric van Gyzendevelopers. 360a48773fSEric van Gyzen 370a48773fSEric van GyzenExpat is [free software](https://www.gnu.org/philosophy/free-sw.en.html). 380a48773fSEric van GyzenYou may copy, distribute, and modify it under the terms of the License 390a48773fSEric van Gyzencontained in the file 400a48773fSEric van Gyzen[`COPYING`](https://github.com/libexpat/libexpat/blob/master/expat/COPYING) 410a48773fSEric van Gyzendistributed with this package. 420a48773fSEric van GyzenThis license is the same as the MIT/X Consortium license. 430a48773fSEric van Gyzen 44cc68614dSXin LI 45cc68614dSXin LI## Using libexpat in your CMake-Based Project 46cc68614dSXin LI 47908f215eSXin LIThere are three documented ways of using libexpat with CMake: 48cc68614dSXin LI 49908f215eSXin LI### a) `find_package` with Module Mode 50cc68614dSXin LI 51cc68614dSXin LIThis approach leverages CMake's own [module `FindEXPAT`](https://cmake.org/cmake/help/latest/module/FindEXPAT.html). 52cc68614dSXin LI 53cc68614dSXin LINotice the *uppercase* `EXPAT` in the following example: 54cc68614dSXin LI 55cc68614dSXin LI```cmake 56*fe927888SPhilip Paepscmake_minimum_required(VERSION 3.10) 57cc68614dSXin LI 58cc68614dSXin LIproject(hello VERSION 1.0.0) 59cc68614dSXin LI 60cc68614dSXin LIfind_package(EXPAT 2.2.8 MODULE REQUIRED) 61cc68614dSXin LI 62cc68614dSXin LIadd_executable(hello 63cc68614dSXin LI hello.c 64cc68614dSXin LI) 65cc68614dSXin LI 66cc68614dSXin LItarget_link_libraries(hello PUBLIC EXPAT::EXPAT) 67cc68614dSXin LI``` 68cc68614dSXin LI 69908f215eSXin LI### b) `find_package` with Config Mode 70cc68614dSXin LI 71cc68614dSXin LIThis approach requires files from… 72cc68614dSXin LI 73cc68614dSXin LI- libexpat >=2.2.8 where packaging uses the CMake build system 74cc68614dSXin LIor 75cc68614dSXin LI- libexpat >=2.3.0 where packaging uses the GNU Autotools build system 76cc68614dSXin LI on Linux 77cc68614dSXin LIor 78cc68614dSXin LI- libexpat >=2.4.0 where packaging uses the GNU Autotools build system 79cc68614dSXin LI on macOS or MinGW. 80cc68614dSXin LI 81cc68614dSXin LINotice the *lowercase* `expat` in the following example: 82cc68614dSXin LI 83cc68614dSXin LI```cmake 84*fe927888SPhilip Paepscmake_minimum_required(VERSION 3.10) 85cc68614dSXin LI 86cc68614dSXin LIproject(hello VERSION 1.0.0) 87cc68614dSXin LI 88cc68614dSXin LIfind_package(expat 2.2.8 CONFIG REQUIRED char dtd ns) 89cc68614dSXin LI 90cc68614dSXin LIadd_executable(hello 91cc68614dSXin LI hello.c 92cc68614dSXin LI) 93cc68614dSXin LI 94cc68614dSXin LItarget_link_libraries(hello PUBLIC expat::expat) 95cc68614dSXin LI``` 96cc68614dSXin LI 97908f215eSXin LI### c) The `FetchContent` module 98908f215eSXin LI 99908f215eSXin LIThis approach — as demonstrated below — requires CMake >=3.18 for both the 100908f215eSXin LI[`FetchContent` module](https://cmake.org/cmake/help/latest/module/FetchContent.html) 101908f215eSXin LIand its support for the `SOURCE_SUBDIR` option to be available. 102908f215eSXin LI 103908f215eSXin LIPlease note that: 104908f215eSXin LI- Use of the `FetchContent` module with *non-release* SHA1s or `master` 105908f215eSXin LI of libexpat is neither advised nor considered officially supported. 106908f215eSXin LI- Pinning to a specific commit is great for robust CI. 107908f215eSXin LI- Pinning to a specific commit needs updating every time there is a new 108908f215eSXin LI release of libexpat — either manually or through automation —, 109908f215eSXin LI to not miss out on libexpat security updates. 110908f215eSXin LI 111908f215eSXin LIFor an example that pulls in libexpat via Git: 112908f215eSXin LI 113908f215eSXin LI```cmake 114908f215eSXin LIcmake_minimum_required(VERSION 3.18) 115908f215eSXin LI 116908f215eSXin LIinclude(FetchContent) 117908f215eSXin LI 118908f215eSXin LIproject(hello VERSION 1.0.0) 119908f215eSXin LI 120908f215eSXin LIFetchContent_Declare( 121908f215eSXin LI expat 122908f215eSXin LI GIT_REPOSITORY https://github.com/libexpat/libexpat/ 123908f215eSXin LI GIT_TAG 000000000_GIT_COMMIT_SHA1_HERE_000000000 # i.e. Git tag R_0_Y_Z 124908f215eSXin LI SOURCE_SUBDIR expat/ 125908f215eSXin LI) 126908f215eSXin LI 127908f215eSXin LIFetchContent_MakeAvailable(expat) 128908f215eSXin LI 129908f215eSXin LIadd_executable(hello 130908f215eSXin LI hello.c 131908f215eSXin LI) 132908f215eSXin LI 133908f215eSXin LItarget_link_libraries(hello PUBLIC expat) 134908f215eSXin LI``` 135908f215eSXin LI 136cc68614dSXin LI 137cc68614dSXin LI## Building from a Git Clone 138cc68614dSXin LI 1390a48773fSEric van GyzenIf you are building Expat from a check-out from the 1400a48773fSEric van Gyzen[Git repository](https://github.com/libexpat/libexpat/), 1410a48773fSEric van Gyzenyou need to run a script that generates the configure script using the 1420a48773fSEric van GyzenGNU autoconf and libtool tools. To do this, you need to have 1430a48773fSEric van Gyzenautoconf 2.58 or newer. Run the script like this: 1440a48773fSEric van Gyzen 1450a48773fSEric van Gyzen```console 1460a48773fSEric van Gyzen./buildconf.sh 1470a48773fSEric van Gyzen``` 1480a48773fSEric van Gyzen 1490a48773fSEric van GyzenOnce this has been done, follow the same instructions as for building 1500a48773fSEric van Gyzenfrom a source distribution. 1510a48773fSEric van Gyzen 152cc68614dSXin LI 153cc68614dSXin LI## Building from a Source Distribution 154cc68614dSXin LI 155cc68614dSXin LI### a) Building with the configure script (i.e. GNU Autotools) 156cc68614dSXin LI 1570a48773fSEric van GyzenTo build Expat from a source distribution, you first run the 1580a48773fSEric van Gyzenconfiguration shell script in the top level distribution directory: 1590a48773fSEric van Gyzen 1600a48773fSEric van Gyzen```console 1610a48773fSEric van Gyzen./configure 1620a48773fSEric van Gyzen``` 1630a48773fSEric van Gyzen 1640a48773fSEric van GyzenThere are many options which you may provide to configure (which you 1650a48773fSEric van Gyzencan discover by running configure with the `--help` option). But the 1660a48773fSEric van Gyzenone of most interest is the one that sets the installation directory. 1670a48773fSEric van GyzenBy default, the configure script will set things up to install 1680a48773fSEric van Gyzenlibexpat into `/usr/local/lib`, `expat.h` into `/usr/local/include`, and 1690a48773fSEric van Gyzen`xmlwf` into `/usr/local/bin`. If, for example, you'd prefer to install 1700a48773fSEric van Gyzeninto `/home/me/mystuff/lib`, `/home/me/mystuff/include`, and 1710a48773fSEric van Gyzen`/home/me/mystuff/bin`, you can tell `configure` about that with: 1720a48773fSEric van Gyzen 1730a48773fSEric van Gyzen```console 1740a48773fSEric van Gyzen./configure --prefix=/home/me/mystuff 1750a48773fSEric van Gyzen``` 1760a48773fSEric van Gyzen 1770a48773fSEric van GyzenAnother interesting option is to enable 64-bit integer support for 1780a48773fSEric van Gyzenline and column numbers and the over-all byte index: 1790a48773fSEric van Gyzen 1800a48773fSEric van Gyzen```console 1810a48773fSEric van Gyzen./configure CPPFLAGS=-DXML_LARGE_SIZE 1820a48773fSEric van Gyzen``` 1830a48773fSEric van Gyzen 1840a48773fSEric van GyzenHowever, such a modification would be a breaking change to the ABI 1850a48773fSEric van Gyzenand is therefore not recommended for general use — e.g. as part of 1860a48773fSEric van Gyzena Linux distribution — but rather for builds with special requirements. 1870a48773fSEric van Gyzen 1880a48773fSEric van GyzenAfter running the configure script, the `make` command will build 1890a48773fSEric van Gyzenthings and `make install` will install things into their proper 1900a48773fSEric van Gyzenlocation. Have a look at the `Makefile` to learn about additional 1910a48773fSEric van Gyzen`make` options. Note that you need to have write permission into 1920a48773fSEric van Gyzenthe directories into which things will be installed. 1930a48773fSEric van Gyzen 1940a48773fSEric van GyzenIf you are interested in building Expat to provide document 1950a48773fSEric van Gyzeninformation in UTF-16 encoding rather than the default UTF-8, follow 1960a48773fSEric van Gyzenthese instructions (after having run `make distclean`). 1970a48773fSEric van GyzenPlease note that we configure with `--without-xmlwf` as xmlwf does not 1980a48773fSEric van Gyzensupport this mode of compilation (yet): 1990a48773fSEric van Gyzen 2000a48773fSEric van Gyzen1. Mass-patch `Makefile.am` files to use `libexpatw.la` for a library name: 2010a48773fSEric van Gyzen <br/> 202ffd294a1SEnji Cooper `find . -name Makefile.am -exec sed 2030a48773fSEric van Gyzen -e 's,libexpat\.la,libexpatw.la,' 2040a48773fSEric van Gyzen -e 's,libexpat_la,libexpatw_la,' 205ffd294a1SEnji Cooper -i.bak {} +` 2060a48773fSEric van Gyzen 2070a48773fSEric van Gyzen1. Run `automake` to re-write `Makefile.in` files:<br/> 2080a48773fSEric van Gyzen `automake` 2090a48773fSEric van Gyzen 2100a48773fSEric van Gyzen1. For UTF-16 output as unsigned short (and version/error strings as char), 2110a48773fSEric van Gyzen run:<br/> 2120a48773fSEric van Gyzen `./configure CPPFLAGS=-DXML_UNICODE --without-xmlwf`<br/> 2130a48773fSEric van Gyzen For UTF-16 output as `wchar_t` (incl. version/error strings), run:<br/> 2140a48773fSEric van Gyzen `./configure CFLAGS="-g -O2 -fshort-wchar" CPPFLAGS=-DXML_UNICODE_WCHAR_T 2150a48773fSEric van Gyzen --without-xmlwf` 2160a48773fSEric van Gyzen <br/>Note: The latter requires libc compiled with `-fshort-wchar`, as well. 2170a48773fSEric van Gyzen 2180a48773fSEric van Gyzen1. Run `make` (which excludes xmlwf). 2190a48773fSEric van Gyzen 2200a48773fSEric van Gyzen1. Run `make install` (again, excludes xmlwf). 2210a48773fSEric van Gyzen 2220a48773fSEric van GyzenUsing `DESTDIR` is supported. It works as follows: 2230a48773fSEric van Gyzen 2240a48773fSEric van Gyzen```console 2250a48773fSEric van Gyzenmake install DESTDIR=/path/to/image 2260a48773fSEric van Gyzen``` 2270a48773fSEric van Gyzen 2280a48773fSEric van Gyzenoverrides the in-makefile set `DESTDIR`, because variable-setting priority is 2290a48773fSEric van Gyzen 2300a48773fSEric van Gyzen1. commandline 2310a48773fSEric van Gyzen1. in-makefile 2320a48773fSEric van Gyzen1. environment 2330a48773fSEric van Gyzen 2340a48773fSEric van GyzenNote: This only applies to the Expat library itself, building UTF-16 versions 2350a48773fSEric van Gyzenof xmlwf and the tests is currently not supported. 2360a48773fSEric van Gyzen 2370a48773fSEric van GyzenWhen using Expat with a project using autoconf for configuration, you 2380a48773fSEric van Gyzencan use the probing macro in `conftools/expat.m4` to determine how to 2390a48773fSEric van Gyzeninclude Expat. See the comments at the top of that file for more 2400a48773fSEric van Gyzeninformation. 2410a48773fSEric van Gyzen 2420a48773fSEric van GyzenA reference manual is available in the file `doc/reference.html` in this 2430a48773fSEric van Gyzendistribution. 2446b2c1e49SXin LI 2456b2c1e49SXin LI 246cc68614dSXin LI### b) Building with CMake 247cc68614dSXin LI 248cc68614dSXin LIThe CMake build system is still *experimental* and may replace the primary 2496b2c1e49SXin LIbuild system based on GNU Autotools at some point when it is ready. 250cc68614dSXin LI 251cc68614dSXin LI 252cc68614dSXin LI#### Available Options 253cc68614dSXin LI 2546b2c1e49SXin LIFor an idea of the available (non-advanced) options for building with CMake: 2556b2c1e49SXin LI 2566b2c1e49SXin LI```console 2576b2c1e49SXin LI# rm -f CMakeCache.txt ; cmake -D_EXPAT_HELP=ON -LH . | grep -B1 ':.*=' | sed 's,^--$,,' 2586b2c1e49SXin LI// Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel ... 2596b2c1e49SXin LICMAKE_BUILD_TYPE:STRING= 2606b2c1e49SXin LI 2616b2c1e49SXin LI// Install path prefix, prepended onto install directories. 2626b2c1e49SXin LICMAKE_INSTALL_PREFIX:PATH=/usr/local 2636b2c1e49SXin LI 2646b2c1e49SXin LI// Path to a program. 2656b2c1e49SXin LIDOCBOOK_TO_MAN:FILEPATH=/usr/bin/docbook2x-man 2666b2c1e49SXin LI 26771f0c44aSXin LI// Build man page for xmlwf 2686b2c1e49SXin LIEXPAT_BUILD_DOCS:BOOL=ON 2696b2c1e49SXin LI 27071f0c44aSXin LI// Build the examples for expat library 2716b2c1e49SXin LIEXPAT_BUILD_EXAMPLES:BOOL=ON 2726b2c1e49SXin LI 27371f0c44aSXin LI// Build fuzzers for the expat library 2746b2c1e49SXin LIEXPAT_BUILD_FUZZERS:BOOL=OFF 2756b2c1e49SXin LI 27671f0c44aSXin LI// Build pkg-config file 277cc68614dSXin LIEXPAT_BUILD_PKGCONFIG:BOOL=ON 278cc68614dSXin LI 27971f0c44aSXin LI// Build the tests for expat library 2806b2c1e49SXin LIEXPAT_BUILD_TESTS:BOOL=ON 2816b2c1e49SXin LI 28271f0c44aSXin LI// Build the xmlwf tool for expat library 2836b2c1e49SXin LIEXPAT_BUILD_TOOLS:BOOL=ON 2846b2c1e49SXin LI 2856b2c1e49SXin LI// Character type to use (char|ushort|wchar_t) [default=char] 2866b2c1e49SXin LIEXPAT_CHAR_TYPE:STRING=char 2876b2c1e49SXin LI 28871f0c44aSXin LI// Install expat files in cmake install target 2896b2c1e49SXin LIEXPAT_ENABLE_INSTALL:BOOL=ON 2906b2c1e49SXin LI 2916b2c1e49SXin LI// Use /MT flag (static CRT) when compiling in MSVC 2926b2c1e49SXin LIEXPAT_MSVC_STATIC_CRT:BOOL=OFF 2936b2c1e49SXin LI 294*fe927888SPhilip Paeps// Build fuzzers via OSS-Fuzz for the expat library 295cc68614dSXin LIEXPAT_OSSFUZZ_BUILD:BOOL=OFF 296cc68614dSXin LI 29771f0c44aSXin LI// Build a shared expat library 2986b2c1e49SXin LIEXPAT_SHARED_LIBS:BOOL=ON 2996b2c1e49SXin LI 3006b2c1e49SXin LI// Treat all compiler warnings as errors 3016b2c1e49SXin LIEXPAT_WARNINGS_AS_ERRORS:BOOL=OFF 3026b2c1e49SXin LI 3036b2c1e49SXin LI// Make use of getrandom function (ON|OFF|AUTO) [default=AUTO] 3046b2c1e49SXin LIEXPAT_WITH_GETRANDOM:STRING=AUTO 3056b2c1e49SXin LI 30671f0c44aSXin LI// Utilize libbsd (for arc4random_buf) 3076b2c1e49SXin LIEXPAT_WITH_LIBBSD:BOOL=OFF 3086b2c1e49SXin LI 3096b2c1e49SXin LI// Make use of syscall SYS_getrandom (ON|OFF|AUTO) [default=AUTO] 3106b2c1e49SXin LIEXPAT_WITH_SYS_GETRANDOM:STRING=AUTO 3116b2c1e49SXin LI``` 312