1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
6 <title>How to build lxml from source</title>
7 <link rel="stylesheet" href="style.css" type="text/css" />
8 <script type="text/javascript">
9 function trigger_menu(event) {
10 var sidemenu = document.getElementById("sidemenu");
11 var classes = sidemenu.getAttribute("class");
12 classes = (classes.indexOf(" visible") === -1) ? classes + " visible" : classes.replace(" visible", "");
13 sidemenu.setAttribute("class", classes);
14 event.preventDefault();
15 event.stopPropagation();
17 function hide_menu() {
18 var sidemenu = document.getElementById("sidemenu");
19 var classes = sidemenu.getAttribute("class");
20 if (classes.indexOf(" visible") !== -1) {
21 sidemenu.setAttribute("class", classes.replace(" visible", ""));
24 </script><meta content="width=device-width, initial-scale=1" name="viewport" /></head>
25 <body onclick="hide_menu()">
26 <div class="document" id="how-to-build-lxml-from-source">
27 <div class="sidemenu" id="sidemenu"><div class="menutrigger" onclick="trigger_menu(event)">Menu</div><div class="menu"><ul id="lxml-section"><li><span class="section title">lxml</span><ul class="menu foreign" id="index-menu"><li class="menu title"><a href="index.html">lxml</a><ul class="submenu"><li class="menu item"><a href="index.html#introduction">Introduction</a></li><li class="menu item"><a href="index.html#support-the-project">Support the project</a></li><li class="menu item"><a href="index.html#documentation">Documentation</a></li><li class="menu item"><a href="index.html#download">Download</a></li><li class="menu item"><a href="index.html#mailing-list">Mailing list</a></li><li class="menu item"><a href="index.html#bug-tracker">Bug tracker</a></li><li class="menu item"><a href="index.html#license">License</a></li><li class="menu item"><a href="index.html#old-versions">Old Versions</a></li><li class="menu item"><a href="index.html#legal-notice-for-donations">Legal Notice for Donations</a></li></ul></li></ul><ul class="menu foreign" id="intro-menu"><li class="menu title"><a href="intro.html">Why lxml?</a><ul class="submenu"><li class="menu item"><a href="intro.html#motto">Motto</a></li><li class="menu item"><a href="intro.html#aims">Aims</a></li></ul></li></ul><ul class="menu foreign" id="installation-menu"><li class="menu title"><a href="installation.html">Installing lxml</a><ul class="submenu"><li class="menu item"><a href="installation.html#where-to-get-it">Where to get it</a></li><li class="menu item"><a href="installation.html#requirements">Requirements</a></li><li class="menu item"><a href="installation.html#installation">Installation</a></li><li class="menu item"><a href="installation.html#building-lxml-from-dev-sources">Building lxml from dev sources</a></li><li class="menu item"><a href="installation.html#using-lxml-with-python-libxml2">Using lxml with python-libxml2</a></li><li class="menu item"><a href="installation.html#source-builds-on-ms-windows">Source builds on MS Windows</a></li><li class="menu item"><a href="installation.html#source-builds-on-macos-x">Source builds on MacOS-X</a></li></ul></li></ul><ul class="menu foreign" id="performance-menu"><li class="menu title"><a href="performance.html">Benchmarks and Speed</a><ul class="submenu"><li class="menu item"><a href="performance.html#general-notes">General notes</a></li><li class="menu item"><a href="performance.html#how-to-read-the-timings">How to read the timings</a></li><li class="menu item"><a href="performance.html#parsing-and-serialising">Parsing and Serialising</a></li><li class="menu item"><a href="performance.html#the-elementtree-api">The ElementTree API</a></li><li class="menu item"><a href="performance.html#xpath">XPath</a></li><li class="menu item"><a href="performance.html#a-longer-example">A longer example</a></li><li class="menu item"><a href="performance.html#lxml-objectify">lxml.objectify</a></li></ul></li></ul><ul class="menu foreign" id="compatibility-menu"><li class="menu title"><a href="compatibility.html">ElementTree compatibility of lxml.etree</a></li></ul><ul class="menu foreign" id="FAQ-menu"><li class="menu title"><a href="FAQ.html">lxml FAQ - Frequently Asked Questions</a><ul class="submenu"><li class="menu item"><a href="FAQ.html#general-questions">General Questions</a></li><li class="menu item"><a href="FAQ.html#installation">Installation</a></li><li class="menu item"><a href="FAQ.html#contributing">Contributing</a></li><li class="menu item"><a href="FAQ.html#bugs">Bugs</a></li><li class="menu item"><a href="FAQ.html#id1">Threading</a></li><li class="menu item"><a href="FAQ.html#parsing-and-serialisation">Parsing and Serialisation</a></li><li class="menu item"><a href="FAQ.html#xpath-and-document-traversal">XPath and Document Traversal</a></li></ul></li></ul></li></ul><ul id="Developing with lxml-section"><li><span class="section title">Developing with lxml</span><ul class="menu foreign" id="tutorial-menu"><li class="menu title"><a href="tutorial.html">The lxml.etree Tutorial</a><ul class="submenu"><li class="menu item"><a href="tutorial.html#the-element-class">The Element class</a></li><li class="menu item"><a href="tutorial.html#the-elementtree-class">The ElementTree class</a></li><li class="menu item"><a href="tutorial.html#parsing-from-strings-and-files">Parsing from strings and files</a></li><li class="menu item"><a href="tutorial.html#namespaces">Namespaces</a></li><li class="menu item"><a href="tutorial.html#the-e-factory">The E-factory</a></li><li class="menu item"><a href="tutorial.html#elementpath">ElementPath</a></li></ul></li></ul><ul class="menu foreign" id="api index-menu"><li class="menu title"><a href="api/index.html">API reference</a></li></ul><ul class="menu foreign" id="api-menu"><li class="menu title"><a href="api.html">APIs specific to lxml.etree</a><ul class="submenu"><li class="menu item"><a href="api.html#lxml-etree">lxml.etree</a></li><li class="menu item"><a href="api.html#other-element-apis">Other Element APIs</a></li><li class="menu item"><a href="api.html#trees-and-documents">Trees and Documents</a></li><li class="menu item"><a href="api.html#iteration">Iteration</a></li><li class="menu item"><a href="api.html#error-handling-on-exceptions">Error handling on exceptions</a></li><li class="menu item"><a href="api.html#error-logging">Error logging</a></li><li class="menu item"><a href="api.html#serialisation">Serialisation</a></li><li class="menu item"><a href="api.html#incremental-xml-generation">Incremental XML generation</a></li><li class="menu item"><a href="api.html#cdata">CDATA</a></li><li class="menu item"><a href="api.html#xinclude-and-elementinclude">XInclude and ElementInclude</a></li></ul></li></ul><ul class="menu foreign" id="parsing-menu"><li class="menu title"><a href="parsing.html">Parsing XML and HTML with lxml</a><ul class="submenu"><li class="menu item"><a href="parsing.html#parsers">Parsers</a></li><li class="menu item"><a href="parsing.html#the-target-parser-interface">The target parser interface</a></li><li class="menu item"><a href="parsing.html#the-feed-parser-interface">The feed parser interface</a></li><li class="menu item"><a href="parsing.html#incremental-event-parsing">Incremental event parsing</a></li><li class="menu item"><a href="parsing.html#iterparse-and-iterwalk">iterparse and iterwalk</a></li><li class="menu item"><a href="parsing.html#python-unicode-strings">Python unicode strings</a></li></ul></li></ul><ul class="menu foreign" id="validation-menu"><li class="menu title"><a href="validation.html">Validation with lxml</a><ul class="submenu"><li class="menu item"><a href="validation.html#validation-at-parse-time">Validation at parse time</a></li><li class="menu item"><a href="validation.html#id1">DTD</a></li><li class="menu item"><a href="validation.html#relaxng">RelaxNG</a></li><li class="menu item"><a href="validation.html#xmlschema">XMLSchema</a></li><li class="menu item"><a href="validation.html#id2">Schematron</a></li><li class="menu item"><a href="validation.html#id3">(Pre-ISO-Schematron)</a></li></ul></li></ul><ul class="menu foreign" id="xpathxslt-menu"><li class="menu title"><a href="xpathxslt.html">XPath and XSLT with lxml</a><ul class="submenu"><li class="menu item"><a href="xpathxslt.html#xpath">XPath</a></li><li class="menu item"><a href="xpathxslt.html#xslt">XSLT</a></li></ul></li></ul><ul class="menu foreign" id="objectify-menu"><li class="menu title"><a href="objectify.html">lxml.objectify</a><ul class="submenu"><li class="menu item"><a href="objectify.html#the-lxml-objectify-api">The lxml.objectify API</a></li><li class="menu item"><a href="objectify.html#asserting-a-schema">Asserting a Schema</a></li><li class="menu item"><a href="objectify.html#objectpath">ObjectPath</a></li><li class="menu item"><a href="objectify.html#python-data-types">Python data types</a></li><li class="menu item"><a href="objectify.html#how-data-types-are-matched">How data types are matched</a></li><li class="menu item"><a href="objectify.html#what-is-different-from-lxml-etree">What is different from lxml.etree?</a></li></ul></li></ul><ul class="menu foreign" id="lxmlhtml-menu"><li class="menu title"><a href="lxmlhtml.html">lxml.html</a><ul class="submenu"><li class="menu item"><a href="lxmlhtml.html#parsing-html">Parsing HTML</a></li><li class="menu item"><a href="lxmlhtml.html#html-element-methods">HTML Element Methods</a></li><li class="menu item"><a href="lxmlhtml.html#running-html-doctests">Running HTML doctests</a></li><li class="menu item"><a href="lxmlhtml.html#creating-html-with-the-e-factory">Creating HTML with the E-factory</a></li><li class="menu item"><a href="lxmlhtml.html#working-with-links">Working with links</a></li><li class="menu item"><a href="lxmlhtml.html#forms">Forms</a></li><li class="menu item"><a href="lxmlhtml.html#cleaning-up-html">Cleaning up HTML</a></li><li class="menu item"><a href="lxmlhtml.html#html-diff">HTML Diff</a></li><li class="menu item"><a href="lxmlhtml.html#examples">Examples</a></li></ul></li></ul><ul class="menu foreign" id="cssselect-menu"><li class="menu title"><a href="cssselect.html">lxml.cssselect</a><ul class="submenu"><li class="menu item"><a href="cssselect.html#the-cssselector-class">The CSSSelector class</a></li><li class="menu item"><a href="cssselect.html#the-cssselect-method">The cssselect method</a></li><li class="menu item"><a href="cssselect.html#supported-selectors">Supported Selectors</a></li><li class="menu item"><a href="cssselect.html#namespaces">Namespaces</a></li></ul></li></ul><ul class="menu foreign" id="elementsoup-menu"><li class="menu title"><a href="elementsoup.html">BeautifulSoup Parser</a><ul class="submenu"><li class="menu item"><a href="elementsoup.html#parsing-with-the-soupparser">Parsing with the soupparser</a></li><li class="menu item"><a href="elementsoup.html#entity-handling">Entity handling</a></li><li class="menu item"><a href="elementsoup.html#using-soupparser-as-a-fallback">Using soupparser as a fallback</a></li><li class="menu item"><a href="elementsoup.html#using-only-the-encoding-detection">Using only the encoding detection</a></li></ul></li></ul><ul class="menu foreign" id="html5parser-menu"><li class="menu title"><a href="html5parser.html">html5lib Parser</a><ul class="submenu"><li class="menu item"><a href="html5parser.html#differences-to-regular-html-parsing">Differences to regular HTML parsing</a></li><li class="menu item"><a href="html5parser.html#function-reference">Function Reference</a></li></ul></li></ul></li></ul><ul id="Extending lxml-section"><li><span class="section title">Extending lxml</span><ul class="menu foreign" id="resolvers-menu"><li class="menu title"><a href="resolvers.html">Document loading and URL resolving</a><ul class="submenu"><li class="menu item"><a href="resolvers.html#xml-catalogs">XML Catalogs</a></li><li class="menu item"><a href="resolvers.html#uri-resolvers">URI Resolvers</a></li><li class="menu item"><a href="resolvers.html#document-loading-in-context">Document loading in context</a></li><li class="menu item"><a href="resolvers.html#i-o-access-control-in-xslt">I/O access control in XSLT</a></li></ul></li></ul><ul class="menu foreign" id="extensions-menu"><li class="menu title"><a href="extensions.html">Python extensions for XPath and XSLT</a><ul class="submenu"><li class="menu item"><a href="extensions.html#xpath-extension-functions">XPath Extension functions</a></li><li class="menu item"><a href="extensions.html#xslt-extension-elements">XSLT extension elements</a></li></ul></li></ul><ul class="menu foreign" id="element classes-menu"><li class="menu title"><a href="element_classes.html">Using custom Element classes in lxml</a><ul class="submenu"><li class="menu item"><a href="element_classes.html#background-on-element-proxies">Background on Element proxies</a></li><li class="menu item"><a href="element_classes.html#element-initialization">Element initialization</a></li><li class="menu item"><a href="element_classes.html#setting-up-a-class-lookup-scheme">Setting up a class lookup scheme</a></li><li class="menu item"><a href="element_classes.html#generating-xml-with-custom-classes">Generating XML with custom classes</a></li><li class="menu item"><a href="element_classes.html#id1">Implementing namespaces</a></li></ul></li></ul><ul class="menu foreign" id="sax-menu"><li class="menu title"><a href="sax.html">Sax support</a><ul class="submenu"><li class="menu item"><a href="sax.html#building-a-tree-from-sax-events">Building a tree from SAX events</a></li><li class="menu item"><a href="sax.html#producing-sax-events-from-an-elementtree-or-element">Producing SAX events from an ElementTree or Element</a></li><li class="menu item"><a href="sax.html#interfacing-with-pulldom-minidom">Interfacing with pulldom/minidom</a></li></ul></li></ul><ul class="menu foreign" id="capi-menu"><li class="menu title"><a href="capi.html">The public C-API of lxml.etree</a><ul class="submenu"><li class="menu item"><a href="capi.html#passing-generated-trees-through-python">Passing generated trees through Python</a></li><li class="menu item"><a href="capi.html#writing-external-modules-in-cython">Writing external modules in Cython</a></li><li class="menu item"><a href="capi.html#writing-external-modules-in-c">Writing external modules in C</a></li></ul></li></ul></li></ul><ul id="Developing lxml-section"><li><span class="section title">Developing lxml</span><ul class="menu current" id="build-menu"><li class="menu title"><a href="build.html">How to build lxml from source</a><ul class="submenu"><li class="menu item"><a href="build.html#cython">Cython</a></li><li class="menu item"><a href="build.html#github-git-and-hg">Github, git and hg</a></li><li class="menu item"><a href="build.html#building-the-sources">Building the sources</a></li><li class="menu item"><a href="build.html#running-the-tests-and-reporting-errors">Running the tests and reporting errors</a></li><li class="menu item"><a href="build.html#building-an-egg-or-wheel">Building an egg or wheel</a></li><li class="menu item"><a href="build.html#building-lxml-on-macos-x">Building lxml on MacOS-X</a></li><li class="menu item"><a href="build.html#static-linking-on-windows">Static linking on Windows</a></li><li class="menu item"><a href="build.html#building-debian-packages-from-svn-sources">Building Debian packages from SVN sources</a></li></ul></li></ul><ul class="menu foreign" id="lxml source howto-menu"><li class="menu title"><a href="lxml-source-howto.html">How to read the source of lxml</a><ul class="submenu"><li class="menu item"><a href="lxml-source-howto.html#what-is-cython">What is Cython?</a></li><li class="menu item"><a href="lxml-source-howto.html#where-to-start">Where to start?</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-etree">lxml.etree</a></li><li class="menu item"><a href="lxml-source-howto.html#python-modules">Python modules</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-objectify">lxml.objectify</a></li><li class="menu item"><a href="lxml-source-howto.html#lxml-html">lxml.html</a></li></ul></li></ul><ul class="menu foreign" id="changes 4 4 3-menu"><li class="menu title"><a href="changes-4.4.3.html">Release Changelog</a></li></ul><ul class="menu foreign" id="credits-menu"><li class="menu title"><a href="credits.html">Credits</a><ul class="submenu"><li class="menu item"><a href="credits.html#main-contributors">Main contributors</a></li><li class="menu item"><a href="credits.html#special-thanks-goes-to">Special thanks goes to:</a></li></ul></li></ul></li><li><a href="/sitemap.html">Sitemap</a></li></ul></div></div><h1 class="title">How to build lxml from source</h1>
29 <p>To build lxml from source, you need libxml2 and libxslt properly
30 installed, <em>including the header files</em>. These are likely shipped in
31 separate <tt class="docutils literal"><span class="pre">-dev</span></tt> or <tt class="docutils literal"><span class="pre">-devel</span></tt> packages like <tt class="docutils literal"><span class="pre">libxml2-dev</span></tt>, which
32 you must install before trying to build lxml.</p>
33 <div class="contents topic" id="contents">
34 <p class="topic-title first">Contents</p>
36 <li><a class="reference internal" href="#cython" id="id2">Cython</a></li>
37 <li><a class="reference internal" href="#github-git-and-hg" id="id3">Github, git and hg</a></li>
38 <li><a class="reference internal" href="#building-the-sources" id="id4">Building the sources</a></li>
39 <li><a class="reference internal" href="#running-the-tests-and-reporting-errors" id="id5">Running the tests and reporting errors</a></li>
40 <li><a class="reference internal" href="#building-an-egg-or-wheel" id="id6">Building an egg or wheel</a></li>
41 <li><a class="reference internal" href="#building-lxml-on-macos-x" id="id7">Building lxml on MacOS-X</a></li>
42 <li><a class="reference internal" href="#static-linking-on-windows" id="id8">Static linking on Windows</a></li>
43 <li><a class="reference internal" href="#building-debian-packages-from-svn-sources" id="id9">Building Debian packages from SVN sources</a></li>
46 <div class="section" id="cython">
48 <p>The lxml.etree and lxml.objectify modules are written in <a class="reference external" href="http://cython.org">Cython</a>.
49 Since we distribute the Cython-generated .c files with lxml releases,
50 however, you do not need Cython to build lxml from the normal release
51 sources. We even encourage you to <em>not install Cython</em> for a normal
52 release build, as the generated C code can vary quite heavily between
53 Cython versions, which may or may not generate correct code for lxml.
54 The pre-generated release sources were tested and therefore are known
56 <p>So, if you want a reliable build of lxml, we suggest to a) use a
57 source release of lxml and b) disable or uninstall Cython for the
59 <p><em>Only</em> if you are interested in building lxml from a checkout of the
60 developer sources (e.g. to test a bug fix that has not been release
61 yet) or if you want to be an lxml developer, then you do need a
62 working Cython installation. You can use <a class="reference external" href="http://pypi.python.org/pypi/pip">pip</a> to install it:</p>
63 <pre class="literal-block">
64 pip install -r requirements.txt
66 <p><a class="reference external" href="https://github.com/lxml/lxml/blob/master/requirements.txt">https://github.com/lxml/lxml/blob/master/requirements.txt</a></p>
67 <p>lxml currently requires at least Cython 0.26.1, later release versions
68 should work as well. For Python 3.7 support, at least Cython 0.29 is
71 <div class="section" id="github-git-and-hg">
72 <h1>Github, git and hg</h1>
73 <p>The lxml package is developed in a repository on <a class="reference external" href="https://github.com/lxml/">Github</a> using
74 <a class="reference external" href="http://mercurial.selenic.com/">Mercurial</a> and the <a class="reference external" href="http://hg-git.github.com/">hg-git</a> plugin. You can retrieve the current
75 developer version using:</p>
76 <pre class="literal-block">
77 hg clone git+ssh://git@github.com/lxml/lxml.git lxml
80 <pre class="literal-block">
81 git clone ssh://git@github.com/lxml/lxml.git lxml
83 <p>This will create a directory <tt class="docutils literal">lxml</tt> and download the source into it,
84 including the complete development history. Don't be afraid, the
85 repository download is fairly quick. You can also browse the
86 <a class="reference external" href="https://github.com/lxml/lxml">lxml repository</a> through the web or download a ZIP archive with the
87 <a class="reference external" href="https://github.com/lxml/lxml/archive/master.zip">latest master branch</a>.</p>
89 <div class="section" id="building-the-sources">
90 <h1>Building the sources</h1>
91 <p>Clone the source repository as described above (or download
92 the <a class="reference external" href="https://github.com/lxml/lxml/tarball/master">source tar-ball</a> and unpack it) and then type:</p>
93 <pre class="literal-block">
97 <pre class="literal-block">
98 python setup.py bdist_egg # requires 'setuptools' or 'distribute'
100 <p>To (re-)build the C sources with Cython, you must additionally pass the
101 option <tt class="docutils literal"><span class="pre">--with-cython</span></tt>:</p>
102 <pre class="literal-block">
103 python setup.py build --with-cython
105 <p>If you want to test lxml from the source directory, it is better to build it
106 in-place like this:</p>
107 <pre class="literal-block">
108 python setup.py build_ext -i --with-cython
110 <p>or, in Unix-like environments:</p>
111 <pre class="literal-block">
114 <p>To speed up the build in test environments (e.g. on a continuous
115 integration server), set the <tt class="docutils literal">CFLAGS</tt> environment variable to
116 disable C compiler optimisations (e.g. "-O0" for gcc, that's
117 minus-oh-zero), for example:</p>
118 <pre class="literal-block">
119 CFLAGS="-O0" make inplace
121 <p>If you get errors about missing header files (e.g. <tt class="docutils literal">Python.h</tt> or
122 <tt class="docutils literal">libxml/xmlversion.h</tt>) then you need to make sure the development
123 packages of Python, libxml2 and libxslt are properly installed. On
124 Linux distributions, they are usually called something like
125 <tt class="docutils literal"><span class="pre">libxml2-dev</span></tt> or <tt class="docutils literal"><span class="pre">libxslt-devel</span></tt>. If these packages were
126 installed in non-standard places, try passing the following option to
127 setup.py to make sure the right config is found:</p>
128 <pre class="literal-block">
129 python setup.py build --with-xslt-config=/path/to/xslt-config
131 <p>There are also env vars to allow overriding the config tool:</p>
132 <pre class="literal-block">
133 env XML2_CONFIG=/path/to/xml2-config python build
135 <p>You may also use <tt class="docutils literal"><span class="pre">pkg-config</span></tt> as the tools:</p>
136 <pre class="literal-block">
137 env XSLT_CONFIG="pkg-config libxslt" python setup.py build
139 <p>If this doesn't help, you may have to add the location of the header
140 files to the include path like:</p>
141 <pre class="literal-block">
142 python setup.py build_ext -i -I /usr/include/libxml2
144 <p>where the file is in <tt class="docutils literal">/usr/include/libxml2/libxml/xmlversion.h</tt></p>
145 <p>To use lxml.etree in-place, you can place lxml's <tt class="docutils literal">src</tt> directory
146 on your Python module search path (PYTHONPATH) and then import
147 <tt class="docutils literal">lxml.etree</tt> to play with it:</p>
148 <pre class="literal-block">
150 # PYTHONPATH=src python
152 Type "help", "copyright", "credits" or "license" for more information.
153 >>> from lxml import etree
156 <p>To make sure everything gets recompiled cleanly after changes, you can
157 run <tt class="docutils literal">make clean</tt> or delete the file <tt class="docutils literal">src/lxml/etree.c</tt>.</p>
159 <div class="section" id="running-the-tests-and-reporting-errors">
160 <h1>Running the tests and reporting errors</h1>
161 <p>The source distribution (tgz) and the source repository contain a test
162 suite for lxml. You can run it from the top-level directory:</p>
163 <pre class="literal-block">
166 <p>Note that the test script only tests the in-place build (see distutils
167 building above), as it searches the <tt class="docutils literal">src</tt> directory. You can use the
168 following one-step command to trigger an in-place build and test it:</p>
169 <pre class="literal-block">
172 <p>This also runs the ElementTree and cElementTree compatibility tests. To call
173 them separately, make sure you have lxml on your PYTHONPATH first, then run:</p>
174 <pre class="literal-block">
178 <pre class="literal-block">
181 <p>If the tests give failures, errors, or worse, segmentation faults, we'd really
182 like to know. Please contact us on the <a class="reference external" href="http://lxml.de/mailinglist/">mailing list</a>, and please specify
183 the version of lxml, libxml2, libxslt and Python you were using, as well as
184 your operating system type (Linux, Windows, MacOS-X, ...).</p>
186 <div class="section" id="building-an-egg-or-wheel">
187 <h1>Building an egg or wheel</h1>
188 <p>This is the procedure to make an lxml egg or <a class="reference external" href="https://wheel.readthedocs.io/en/latest/">wheel</a> for your platform.
189 It assumes that you have <tt class="docutils literal">setuptools</tt> or <tt class="docutils literal">distribute</tt> installed, as well
190 as the <tt class="docutils literal">wheel</tt> package.</p>
191 <p>First, download the lxml-x.y.tar.gz release. This contains the pregenerated
192 C files so that you can be sure you build exactly from the release sources.
193 Unpack them and <tt class="docutils literal">cd</tt> into the resulting directory. Then, to build a wheel,
194 simply run the command</p>
195 <pre class="literal-block">
196 python setup.py bdist_wheel
198 <p>or, to build a statically linked wheel with all of libxml2, libxslt and
199 friends compiled in, run</p>
201 python setup.py bdist_wheel --static-deps</blockquote>
202 <p>The resulting .whl file will be written into the <tt class="docutils literal">dist</tt> directory.</p>
203 <p>To build an egg file, run</p>
204 <pre class="literal-block">
205 python setup.py build_egg
207 <p>If you are on a Unix-like platform, you can first build the extension modules
209 <pre class="literal-block">
210 python setup.py build
212 <p>and then <tt class="docutils literal">cd</tt> into the directory <tt class="docutils literal">build/lib.your.platform</tt> to call
213 <tt class="docutils literal">strip</tt> on any <tt class="docutils literal">.so</tt> file you find there. This reduces the size of
214 the binary distribution considerably. Then, from the package root directory,
216 <pre class="literal-block">
217 python setup.py bdist_egg
219 <p>This will quickly package the pre-built packages into an egg file and
220 drop it into the <tt class="docutils literal">dist</tt> directory.</p>
222 <div class="section" id="building-lxml-on-macos-x">
223 <h1>Building lxml on MacOS-X</h1>
224 <p>Apple regularly ships new system releases with horribly outdated
225 system libraries. This is specifically the case for libxml2 and
226 libxslt, where the system provided versions used to be too old
227 to even build lxml for a long time.</p>
228 <p>While the Unix environment in MacOS-X makes it relatively easy to
229 install Unix/Linux style package management tools and new software, it
230 actually seems to be hard to get libraries set up for exclusive usage
231 that MacOS-X ships in an older version. Alternative distributions
232 (like macports) install their libraries in addition to the system
233 libraries, but the compiler and the runtime loader on MacOS still sees
234 the system libraries before the new libraries. This can lead to
235 undebuggable crashes where the newer library seems to be loaded but
236 the older system library is used.</p>
237 <p>Apple discourages static building against libraries, which would help
238 working around this problem. Apple does not ship static library
239 binaries with its system and several package management systems follow
240 this decision. Therefore, building static binaries requires building
241 the dependencies first. The <tt class="docutils literal">setup.py</tt> script does this
242 automatically when you call it like this:</p>
243 <pre class="literal-block">
244 python setup.py build --static-deps
246 <p>This will download and build the latest versions of libxml2 and
247 libxslt from the official FTP download site. If you want to use
248 specific versions, or want to prevent any online access, you can
249 download both <tt class="docutils literal">tar.gz</tt> release files yourself, place them into a
250 subdirectory <tt class="docutils literal">libs</tt> in the lxml distribution, and call <tt class="docutils literal">setup.py</tt>
251 with the desired target versions like this:</p>
252 <pre class="literal-block">
253 python setup.py build --static-deps \
254 --libxml2-version=2.9.1 \
255 --libxslt-version=1.1.28 \
257 sudo python setup.py install
259 <p>Instead of <tt class="docutils literal">build</tt>, you can use any target, like <tt class="docutils literal">bdist_egg</tt>
260 if you want to use setuptools to build an installable egg, or
261 <tt class="docutils literal">bdist_wheel</tt> for a wheel package.</p>
262 <p>Note that this also works with <a class="reference external" href="http://pypi.python.org/pypi/pip">pip</a>. Since you can't pass
263 command line options in this case, you have to use an environment
264 variable instead:</p>
265 <pre class="literal-block">
266 STATIC_DEPS=true pip install lxml
268 <p>To install the package into the system Python package directory,
269 run the installation with "sudo":</p>
270 <pre class="literal-block">
271 STATIC_DEPS=true sudo pip install lxml
273 <p>The <tt class="docutils literal">STATICBUILD</tt> environment variable is handled equivalently to
274 the <tt class="docutils literal">STATIC_DEPS</tt> variable, but is used by some other extension
276 <p>If you decide to do a non-static build, you may also have to install
277 the command line tools in addition to the XCode build environment.
278 They are available as a restricted download from here:</p>
279 <p><a class="reference external" href="https://developer.apple.com/downloads/index.action">https://developer.apple.com/downloads/index.action</a>?=command%20line%20tools#</p>
280 <p>Without them, the compiler may not find the necessary header files of
281 the XML libraries, according to the second comment in this ticket:</p>
282 <p><a class="reference external" href="https://bugs.launchpad.net/lxml/+bug/1244094">https://bugs.launchpad.net/lxml/+bug/1244094</a></p>
284 <div class="section" id="static-linking-on-windows">
285 <h1>Static linking on Windows</h1>
286 <p>Most operating systems have proper package management that makes installing
287 current versions of libxml2 and libxslt easy. The most famous exception is
288 Microsoft Windows, which entirely lacks these capabilities. To work around
289 the limits of this platform, lxml's installation can download pre-built
290 packages of the dependencies and build statically against them. Assuming
291 you have a proper C compiler setup to build Python extensions, this should
293 <pre class="literal-block">
294 python setup.py bdist_wininst --static-deps
296 <p>It should create a windows installer in the <tt class="docutils literal">pkg</tt> directory.</p>
298 <div class="section" id="building-debian-packages-from-svn-sources">
299 <h1>Building Debian packages from SVN sources</h1>
300 <p><a class="reference external" href="http://thread.gmane.org/gmane.comp.python.lxml.devel/1239/focus=1249">Andreas Pakulat</a> proposed the following approach.</p>
302 <li><tt class="docutils literal"><span class="pre">apt-get</span> source lxml</tt></li>
303 <li>remove the unpacked directory</li>
304 <li>tar.gz the lxml SVN version and replace the orig.tar.gz that lies in the
306 <li>check md5sum of created tar.gz file and place new sum and size in dsc file</li>
307 <li>do <tt class="docutils literal"><span class="pre">dpkg-source</span> <span class="pre">-x</span> <span class="pre">lxml-[VERSION].dsc</span></tt> and cd into the newly created directory</li>
308 <li>run <tt class="docutils literal">dch <span class="pre">-i</span></tt> and add a comment like "use trunk version", this will
309 increase the debian version number so apt/dpkg won't get confused</li>
310 <li>run <tt class="docutils literal"><span class="pre">dpkg-buildpackage</span> <span class="pre">-rfakeroot</span> <span class="pre">-us</span> <span class="pre">-uc</span></tt> to build the package</li>
312 <p>In case <tt class="docutils literal"><span class="pre">dpkg-buildpackage</span></tt> tells you that some dependencies are missing, you
313 can either install them manually or run <tt class="docutils literal"><span class="pre">apt-get</span> <span class="pre">build-dep</span> lxml</tt>.</p>
314 <p>That will give you .deb packages in the parent directory which can be
315 installed using <tt class="docutils literal">dpkg <span class="pre">-i</span></tt>.</p>
319 <hr class="footer" />
320 Generated on: 2020-01-29.