Epoxy is a small library that GTK +, and other projects, use in order to access the OpenGL API in somewhat sane fashion, hiding all the awful bits of craziness that actually need to happen because apparently somebody dosed the water supply at SGI with large quantities of LSD in the mid-‘90s, orsomething.
As an added advantage, Epoxy is also portable on different platforms, which is a plus for GTK +.
Since I’ve started using Meson for my personal (and some work-related ) projects as well, I’ve been on the lookout for adding Meson build rules to other free and open source software projects, in order to improve both their build time and portability, and to improve Mesonitself.
As a small, portable project, Epoxy sounded like a good candidate for the port of its build system from autotools to Meson .
To the Bat BuildMachine!tl;dr
Since you may be interested just in the numbers , building Epoxy with Meson on my Kaby Lake four Core i7 and NMVe SSD takes about 45% less time than building it withautotools.
A fairly good fraction of the autotools time is spent going through the autogen and configure phases, because they both aren’t parallelised, and create a ton of shellinvocations.
Conversely, Meson’s configuration phase is incredibly fast; the whole Meson build of Epoxy fits in the same time the autogen.sh and configure scripts complete theirrun.Administrivia
Epoxy is a simple library, which means it does not need a hugely complicated build system set up; it does have some interesting deviations, though, which made the porting an interestingchallenge.
For instance, on linux and similar operating systems Epoxy uses pkg-config to find things like the EGL availability and the X11 headers and libraries; on windows, though, it relies on finding the opengl32 shared or static library object itself. This means that we get something straightforward in the former case,like:# Optional dependencies gl_dep = dependency('gl', required: false) egl_dep = dependency('egl', required: false)
and something slightly less straightforward in the lattercase:if host_system == 'windows' # Required dependencies on Windows opengl32_dep = cc.find_library('opengl32', required: true) gdi32_dep = cc.find_library('gdi32', required: true) endif
And, still, this is miles better than what you have to deal with when usingautotools.
Let’s take a messy thing in autotools, like checking whether or not the compiler supports a set of arguments; usually, this involves some m4 macro that’s either part of autoconf-archive or some additional repository, like the xorg macros . Meson handles this in a much better way, out of thebox:# Use different flags depending on the compiler if cc.get_id() == 'msvc' test_cflags = [ '-W3', ..., ] elif cc.get_id() == 'gcc' test_cflags = [ '-Wpointer-arith', ..., ] else test_cflags = [ ] endif common_cflags =  foreach cflag: test_cflags if cc.has_argument(cflag) common_cflags += [ cflag ] endif endforeach
In terms of speed, the configuration step could be made even faster by parallelising the compiler argument checks; right now, Meson has to do them all in a series, but nothing except some additional parsing effort would prevent Meson from running the whole set of checks in parallel, and gather the results at theend.Generatingcode
In order to use the GL entry points without linking against libGL or libGLES* Epoxy takes the XML description of the API from the Khronos repository and generates the code that ends up being compiled by using a python script to parse the XML and generating header and sourcefiles.
Additionally, and unlike most libraries in the G* stack, Epoxy stores its public headers inside a separate directory from itssources:libepoxy ├── cross ├── doc ├── include │ └── epoxy ├── registry ├── src └── test
The autotools build has the src/gen_dispatch.py script create both the source and the header file for each XML at the same time using a rule processed when recursing inside the src directory, and proceeds to put the generated header under $(top_builddir)/include/epoxy , and the generated source under $(top_builddir)/src . Each code generation rule in the Makefile manually creates the include/epoxy directory under the build root to make up for parallel dispatch of eachrule.
Meson makes is harder to do this kind of spooky-action-at-a-distance build, so we need to generate the headers in one pass, and the source in another. This is a bit of a let down, to be honest, and yet a build that invokes the generator script twice for each API description file is still faster under Ninja than a build with the single invocation underMake.
There are sill issues in this step that are being addressed by the Meson developers; for instance, right now we have to use a custom target for each generated header and source separately instead of declaring a generator and calling it multiple times. Hopefully, this will be fixed fairlysoon.Documentation
Epoxy has a very small footprint, in terms of API , but it still benefits from having some documentation on its use. I decided to generate the API reference using Doxygen , as it’s not a G* library and does not need the additional features of gtk-doc. Sadly, Doxygen’s default style is absolutely terrible; it would be great if somebody could fix it to make it look half as good as the look gtk-doc gets out of thebox.Cross-compilation and nativebuilds
Now we get into “interesting”territory.
Epoxy is portable; it works on Linux and * BSD systems; on macOS; and on Windows. Epoxy also works on both Intel Architecture and on ARM .
Making it run on Unix-like systems is not at all complicated. When it comes to Windows, though, things get weirdfast.
Meson uses cross files to determine the environment and toolchain of the host machine , i.e. the machine where the result of the build will eventually run. These are simple text files with key/value pairs that you can either keep in a separate repository, in case you want to share among projects; or you can keep them in your own project’s repository, especially if you want to easily set up continuous integration of cross-compilationbuilds.
Each toolchain has its own; for instance, this is the description of a cross compilation done on Fedora withMingW:[binaries
本文系统（linux）相关术语:linux系统 鸟哥的linux私房菜 linux命令大全 linux操作系统