Fix bundled spidermonkey code in Premake.
[0ad.git] / build / premake / extern_libs5.lua
blob08835c22be9d29c7a0ec7de265296e8d05dfd3ef
1 -- this file provides project_add_extern_libs, which takes care of the
2 -- dirty details of adding the libraries' include and lib paths.
3 --
4 -- TYPICAL TASK: add new library. Instructions:
5 -- 1) add a new extern_lib_defs entry
6 -- 2) add library name to extern_libs tables in premake.lua for all 'projects' that want to use it
8 -- directory in which OS-specific library subdirectories reside.
9 if os.istarget("macosx") then
10 libraries_dir = rootdir.."/libraries/osx/"
11 elseif os.istarget("windows") then
12 libraries_dir = rootdir.."/libraries/win32/"
13 else
14 -- No Unix-specific libs yet (use source directory instead!)
15 end
16 -- directory for shared, bundled libraries
17 libraries_source_dir = rootdir.."/libraries/source/"
18 third_party_source_dir = rootdir.."/source/third_party/"
20 local function add_default_lib_paths(extern_lib)
21 libdirs { libraries_dir .. extern_lib .. "/lib" }
22 end
24 local function add_source_lib_paths(extern_lib)
25 libdirs { libraries_source_dir .. extern_lib .. "/lib" }
26 end
28 local function add_default_include_paths(extern_lib)
29 sysincludedirs { libraries_dir .. extern_lib .. "/include" }
30 end
32 local function add_source_include_paths(extern_lib)
33 sysincludedirs { libraries_source_dir .. extern_lib .. "/include" }
34 end
36 local function add_third_party_include_paths(extern_lib)
37 sysincludedirs { third_party_source_dir .. extern_lib .. "/include" }
38 end
40 pkgconfig = require "pkgconfig"
42 -- Configure pkgconfig for MacOSX systems
43 if os.istarget("macosx") then
44 pkgconfig.additional_pc_path = libraries_dir .. "pkgconfig/"
45 pkgconfig.static_link_libs = true
46 end
48 local function add_delayload(name, suffix, def)
50 if def["no_delayload"] then
51 return
52 end
54 -- currently only supported by VC; nothing to do on other platforms.
55 if not os.istarget("windows") then
56 return
57 end
59 -- no extra debug version; use same library in all configs
60 if suffix == "" then
61 linkoptions { "/DELAYLOAD:"..name..".dll" }
62 -- extra debug version available; use in debug config
63 else
64 local dbg_cmd = "/DELAYLOAD:" .. name .. suffix .. ".dll"
65 local cmd = "/DELAYLOAD:" .. name .. ".dll"
67 filter "Debug"
68 linkoptions { dbg_cmd }
69 filter "Release"
70 linkoptions { cmd }
71 filter { }
72 end
74 end
76 local function add_default_links(def)
78 -- careful: make sure to only use *_names when on the correct platform.
79 local names = {}
80 if os.istarget("windows") then
81 if def.win_names then
82 names = def.win_names
83 end
84 elseif _OPTIONS["android"] and def.android_names then
85 names = def.android_names
86 elseif os.istarget("linux") and def.linux_names then
87 names = def.linux_names
88 elseif os.istarget("macosx") and (def.osx_names or def.osx_frameworks) then
89 if def.osx_names then
90 names = def.osx_names
91 end
92 -- OS X "Frameworks" are added to the links as "name.framework"
93 if def.osx_frameworks then
94 for i,name in pairs(def.osx_frameworks) do
95 links { name .. ".framework" }
96 end
97 end
98 elseif os.istarget("bsd") and def.bsd_names then
99 names = def.bsd_names
100 elseif def.unix_names then
101 names = def.unix_names
104 local suffix = "d"
105 -- library is overriding default suffix (typically "" to indicate there is none)
106 if def["dbg_suffix"] then
107 suffix = def["dbg_suffix"]
109 -- non-Windows doesn't have the distinction of debug vs. release libraries
110 -- (to be more specific, they do, but the two are binary compatible;
111 -- usually only one type - debug or release - is installed at a time).
112 if not os.istarget("windows") then
113 suffix = ""
116 for i,name in pairs(names) do
117 filter "Debug"
118 links { name .. suffix }
119 filter "Release"
120 links { name }
121 filter { }
123 add_delayload(name, suffix, def)
128 -- Library definitions
129 -- In a perfect world, libraries would have a common installation template,
130 -- i.e. location of include directory, naming convention for .lib, etc.
131 -- this table provides a means of working around each library's differences.
133 -- The basic approach is defining two functions per library:
135 -- 1. compile_settings
136 -- This function should set all settings requred during the compile-phase like
137 -- includedirs, defines etc...
139 -- 2. link_settings
140 -- This function should set all settings required during the link-phase like
141 -- libdirs, linkflag etc...
143 -- The main reason for separating those settings is different linking behaviour
144 -- on osx and xcode. For more details, read the comment in project_add_extern_libs.
146 -- There are some helper functions for the most common tasks. You should use them
147 -- if they can be used in your situation to make the definitions more consistent and
148 -- use their default beviours as a guideline.
151 -- add_default_lib_paths(extern_lib)
152 -- Description: Add '<libraries root>/<libraryname>/lib'to the libpaths
153 -- Parameters:
154 -- * extern_lib: <libraryname> to be used in the libpath.
156 -- add_default_include_paths(extern_lib)
157 -- Description: Add '<libraries root>/<libraryname>/include' to the includepaths
158 -- Parameters:
159 -- * extern_lib: <libraryname> to be used in the libpath.
161 -- add_default_links
162 -- Description: Adds links to libraries and configures delayloading.
163 -- If the *_names parameter for a plattform is missing, no linking will be done
164 -- on that plattform.
165 -- The default assumptions are:
166 -- * debug import library and DLL are distinguished with a "d" suffix
167 -- * the library should be marked for delay-loading.
168 -- Parameters:
169 -- * win_names: table of import library / DLL names (no extension) when
170 -- running on Windows.
171 -- * unix_names: as above; shared object names when running on non-Windows.
172 -- * osx_names, osx_frameworks: for OS X specifically; if any of those is
173 -- specified, unix_names is ignored. Using both is possible if needed.
174 -- * osx_names: as above.
175 -- * osx_frameworks: as above, for system libraries that need to be linked
176 -- as "name.framework".
177 -- * bsd_names: as above; for BSD specifically (overrides unix_names if both are
178 -- specified)
179 -- * linux_names: ditto for Linux (overrides unix_names if both given)
180 -- * dbg_suffix: changes the debug suffix from the above default.
181 -- can be "" to indicate the library doesn't have a debug build;
182 -- in that case, the same library (without suffix) is used in
183 -- all build configurations.
184 -- * no_delayload: indicate the library is not to be delay-loaded.
185 -- this is necessary for some libraries that do not support it,
186 -- e.g. Xerces (which is so stupid as to export variables).
188 extern_lib_defs = {
189 boost = {
190 compile_settings = function()
191 if os.istarget("windows") then
192 -- Force the autolink to use the vc141 libs.
193 defines { 'BOOST_LIB_TOOLSET="vc141"' }
194 add_default_include_paths("boost")
195 elseif os.istarget("macosx") then
196 -- Suppress all the Boost warnings on OS X by including it as a system directory
197 buildoptions { "-isystem../" .. libraries_dir .. "boost/include" }
199 -- TODO: This actually applies to most libraries we use on BSDs, make this a global setting.
200 if os.istarget("bsd") then
201 sysincludedirs { "/usr/local/include" }
203 end,
204 link_settings = function()
205 if os.istarget("windows") or os.istarget("macosx") then
206 if os.istarget("windows") then
207 defines { 'BOOST_LIB_TOOLSET="vc141"' }
209 add_default_lib_paths("boost")
211 add_default_links({
212 -- The following are not strictly link dependencies on all systems, but
213 -- are included for compatibility with different versions of Boost
214 android_names = { "boost_filesystem-gcc-mt", "boost_system-gcc-mt" },
215 unix_names = { os.findlib("boost_filesystem-mt") and "boost_filesystem-mt" or "boost_filesystem", os.findlib("boost_system-mt") and "boost_system-mt" or "boost_system" },
216 osx_names = { "boost_filesystem", "boost_system" },
218 end,
220 comsuppw = {
221 link_settings = function()
222 add_default_links({
223 win_names = { "comsuppw" },
224 dbg_suffix = "d",
225 no_delayload = 1,
227 end,
229 cxxtest = {
230 compile_settings = function()
231 sysincludedirs { libraries_source_dir .. "cxxtest-4.4" }
232 end,
234 enet = {
235 compile_settings = function()
236 if os.istarget("windows") then
237 add_default_include_paths("enet")
238 else
239 pkgconfig.add_includes("libenet")
241 end,
242 link_settings = function()
243 if os.istarget("windows") then
244 add_default_lib_paths("enet")
245 add_default_links({
246 win_names = { "enet" },
248 else
249 pkgconfig.add_links("libenet")
251 end,
253 fcollada = {
254 compile_settings = function()
255 add_source_include_paths("fcollada")
256 end,
257 link_settings = function()
258 add_source_lib_paths("fcollada")
259 if os.istarget("windows") then
260 filter "Debug"
261 links { "FColladaD" }
262 filter "Release"
263 links { "FCollada" }
264 filter { }
265 else
266 filter "Debug"
267 links { "FColladaSD" }
268 filter "Release"
269 links { "FColladaSR" }
270 filter { }
272 end,
274 fmt = {
275 compile_settings = function()
276 if os.istarget("windows") then
277 add_default_include_paths("fmt")
278 elseif os.istarget("macosx") then
279 pkgconfig.add_includes("fmt")
282 -- With Linux & BSD, we assume that fmt is installed in a standard location.
284 -- It would be nice to not assume, and to instead use pkg-config: however that
285 -- requires fmt 5.3.0 or greater.
287 -- Unfortunately (at the time of writing) only 92 out of 114 (~80.7%) of distros
288 -- that provide a fmt package meet this, according to
289 -- https://repology.org/badge/vertical-allrepos/fmt.svg?minversion=5.3
291 -- Whilst that might seem like a healthy majority, this does not include the 2018
292 -- Long Term Support and 2019.10 releases of Ubuntu - not only popular and widely
293 -- used as-is, but which are also used as a base for other popular distros (e.g.
294 -- Mint).
296 -- When fmt 5.3 (or better) becomes more widely used, then we can safely use the
297 -- same line as we currently use for osx
298 end,
299 link_settings = function()
300 if os.istarget("windows") then
301 add_default_lib_paths("fmt")
302 add_default_links({
303 win_names = { "fmt" },
304 dbg_suffix = "d",
305 no_delayload = 1,
307 elseif os.istarget("macosx") then
308 -- See comment above as to why this is not also used on Linux or BSD.
309 pkgconfig.add_links("fmt")
310 else
311 add_default_links({
312 unix_names = { "fmt" },
317 freetype = {
318 compile_settings = function()
319 if os.istarget("windows") then
320 add_default_include_paths("freetype")
321 else
322 pkgconfig.add_includes("freetype2")
324 end,
325 link_settings = function()
326 if os.istarget("windows") then
327 add_default_lib_paths("freetype")
328 else
329 pkgconfig.add_links("freetype2")
331 add_default_links({
332 win_names = { "freetype" },
333 no_delayload = 1,
335 end,
337 glad = {
338 add_source_include_paths("glad")
340 gloox = {
341 compile_settings = function()
342 if os.istarget("windows") then
343 add_default_include_paths("gloox")
344 else
345 pkgconfig.add_includes("gloox")
347 end,
348 link_settings = function()
349 if os.istarget("windows") then
350 add_default_lib_paths("gloox")
351 add_default_links({
352 win_names = { "gloox-1.0" },
353 no_delayload = 1,
355 else
356 pkgconfig.add_links("gloox")
358 if os.istarget("macosx") then
359 -- gloox depends on gnutls, but doesn't identify this via pkg-config
360 pkgconfig.add_links("gnutls")
363 end,
365 iconv = {
366 compile_settings = function()
367 if os.istarget("windows") then
368 add_default_include_paths("iconv")
369 defines { "HAVE_ICONV_CONST" }
370 defines { "ICONV_CONST=const" }
371 defines { "LIBICONV_STATIC" }
372 elseif os.istarget("macosx") then
373 add_default_include_paths("iconv")
374 defines { "LIBICONV_STATIC" }
375 elseif os.getversion().description == "FreeBSD" then
376 -- On FreeBSD you need this flag to tell it to use the BSD libc iconv
377 defines { "LIBICONV_PLUG" }
379 end,
380 link_settings = function()
381 if os.istarget("windows") or os.istarget("macosx") then
382 add_default_lib_paths("iconv")
384 add_default_links({
385 win_names = { "libiconv" },
386 osx_names = { "iconv" },
387 dbg_suffix = "",
388 no_delayload = 1,
390 -- glibc (used on Linux and GNU/kFreeBSD) has iconv
391 end,
393 icu = {
394 compile_settings = function()
395 if os.istarget("windows") then
396 add_default_include_paths("icu")
397 else
398 pkgconfig.add_includes("icu-i18n")
400 end,
401 link_settings = function()
402 if os.istarget("windows") then
403 add_default_lib_paths("icu")
404 add_default_links({
405 win_names = { "icuuc", "icuin" },
406 dbg_suffix = "",
407 no_delayload = 1,
409 else
410 pkgconfig.add_links("icu-i18n")
412 end,
414 libcurl = {
415 compile_settings = function()
416 if os.istarget("windows") then
417 add_default_include_paths("libcurl")
418 else
419 pkgconfig.add_includes("libcurl")
421 end,
422 link_settings = function()
423 if os.istarget("windows") then
424 add_default_lib_paths("libcurl")
425 else
426 pkgconfig.add_links("libcurl")
428 add_default_links({
429 win_names = { "libcurl" },
430 osx_frameworks = { "Security" }, -- Not supplied by curl's pkg-config
432 end,
434 libpng = {
435 compile_settings = function()
436 if os.istarget("windows") then
437 add_default_include_paths("libpng")
438 else
439 pkgconfig.add_includes("libpng")
441 end,
442 link_settings = function()
443 if os.istarget("windows") then
444 add_default_lib_paths("libpng")
445 add_default_links({
446 win_names = { "libpng16" },
448 else
449 pkgconfig.add_links("libpng")
451 end,
453 libsodium = {
454 compile_settings = function()
455 if os.istarget("windows") then
456 add_default_include_paths("libsodium")
457 else
458 pkgconfig.add_includes("libsodium")
460 end,
461 link_settings = function()
462 if os.istarget("windows") then
463 add_default_lib_paths("libsodium")
464 add_default_links({
465 win_names = { "libsodium" },
467 else
468 pkgconfig.add_links("libsodium")
470 end,
472 libxml2 = {
473 compile_settings = function()
474 if os.istarget("windows") then
475 add_default_include_paths("libxml2")
476 else
477 pkgconfig.add_includes("libxml-2.0")
479 if os.istarget("macosx") then
480 -- libxml2 needs _REENTRANT or __MT__ for thread support;
481 -- OS X doesn't get either set by default, so do it manually
482 defines { "_REENTRANT" }
485 end,
486 link_settings = function()
487 if os.istarget("windows") then
488 add_default_lib_paths("libxml2")
489 filter "Debug"
490 links { "libxml2" }
491 filter "Release"
492 links { "libxml2" }
493 filter { }
494 else
495 pkgconfig.add_links("libxml-2.0")
497 end,
499 miniupnpc = {
500 compile_settings = function()
501 if os.istarget("windows") then
502 add_default_include_paths("miniupnpc")
503 elseif os.istarget("macosx") then
504 pkgconfig.add_includes("miniupnpc")
507 -- On Linux and BSD systems we assume miniupnpc is installed in a standard location.
509 -- Support for pkg-config was added in v2.1 of miniupnpc (May 2018). However, the
510 -- implementation was flawed - it provided the wrong path to the project's headers.
511 -- This was corrected in v2.2.1 (December 2020).
513 -- At the time of writing, of the 123 Linux and BSD package repositories tracked by
514 -- Repology that supply a version of miniupnpc:
515 -- * 88 (~71.54%) have >= v2.1, needed to locate libraries
516 -- * 50 (~40.65%) have >= v2.2.1, needed to (correctly) locate headers
518 -- Once more recent versions become more widespread, we can safely start to use
519 -- pkg-config to find miniupnpc on Linux and BSD systems.
520 -- https://repology.org/badge/vertical-allrepos/miniupnpc.svg?minversion=2.2.1
521 end,
522 link_settings = function()
523 if os.istarget("windows") then
524 add_default_lib_paths("miniupnpc")
525 add_default_links({
526 win_names = { "miniupnpc" },
528 elseif os.istarget("macosx") then
529 pkgconfig.add_links("miniupnpc")
530 else
531 -- Once miniupnpc v2.1 or better becomes near-universal (see above comment),
532 -- we can use pkg-config for Linux and BSD.
533 add_default_links({
534 unix_names = { "miniupnpc" },
537 end,
539 nvtt = {
540 compile_settings = function()
541 if not _OPTIONS["with-system-nvtt"] then
542 add_source_include_paths("nvtt")
544 defines { "NVTT_SHARED=1" }
545 end,
546 link_settings = function()
547 if not _OPTIONS["with-system-nvtt"] then
548 add_source_lib_paths("nvtt")
550 add_default_links({
551 win_names = { "nvtt" },
552 unix_names = { "nvcore", "nvmath", "nvimage", "nvtt" },
553 osx_names = { "bc6h", "bc7", "nvcore", "nvimage", "nvmath", "nvthread", "nvtt", "squish" },
554 dbg_suffix = "", -- for performance we always use the release-mode version
556 end,
558 openal = {
559 compile_settings = function()
560 if os.istarget("windows") then
561 add_default_include_paths("openal")
562 elseif not os.istarget("macosx") then
563 pkgconfig.add_includes("openal")
565 end,
566 link_settings = function()
567 if os.istarget("windows") then
568 add_default_lib_paths("openal")
569 add_default_links({
570 win_names = { "openal32" },
571 dbg_suffix = "",
572 no_delayload = 1, -- delayload seems to cause errors on startup
574 elseif os.istarget("macosx") then
575 add_default_links({
576 osx_frameworks = { "OpenAL" },
578 else
579 pkgconfig.add_links("openal")
581 end,
583 sdl = {
584 compile_settings = function()
585 if os.istarget("windows") then
586 includedirs { libraries_dir .. "sdl2/include/SDL" }
587 elseif not _OPTIONS["android"] then
588 pkgconfig.add_includes("sdl2")
590 end,
591 link_settings = function()
592 if os.istarget("windows") then
593 add_default_lib_paths("sdl2")
594 elseif not _OPTIONS["android"] then
595 pkgconfig.add_links("sdl2")
597 end,
599 spidermonkey = {
600 compile_settings = function()
601 if _OPTIONS["with-system-mozjs"] then
602 if not _OPTIONS["android"] then
603 pkgconfig.add_includes("mozjs-91")
605 else
606 if os.istarget("windows") then
607 include_dir = "include-win32"
608 else
609 include_dir = "include-unix"
611 filter "Debug"
612 sysincludedirs { libraries_source_dir.."spidermonkey/"..include_dir.."-debug" }
613 defines { "DEBUG" }
614 filter "Release"
615 sysincludedirs { libraries_source_dir.."spidermonkey/"..include_dir.."-release" }
616 filter { }
618 end,
619 link_settings = function()
620 if _OPTIONS["with-system-mozjs"] then
621 if _OPTIONS["android"] then
622 links { "mozjs-91" }
623 else
624 pkgconfig.add_links("mozjs-91")
626 else
627 filter { "Debug", "action:vs*" }
628 links { "mozjs91-ps-debug" }
629 links { "mozjs91-ps-rust-debug" }
630 filter { "Debug", "action:not vs*" }
631 links { "mozjs91-ps-debug" }
632 links { "mozjs91-ps-rust" }
633 filter { "Release" }
634 links { "mozjs91-ps-release" }
635 links { "mozjs91-ps-rust" }
636 filter { }
637 add_source_lib_paths("spidermonkey")
639 end,
641 tinygettext = {
642 compile_settings = function()
643 add_third_party_include_paths("tinygettext")
644 end,
646 valgrind = {
647 compile_settings = function()
648 -- Optional dependency
650 -- valgrind doesn't support windows:
651 -- https://valgrind.org/info/platforms.html
652 if _OPTIONS["with-valgrind"] and not os.istarget("windows") then
653 pkgconfig.add_includes("valgrind")
654 defines { "CONFIG2_VALGRIND=1" }
656 end,
658 vorbis = {
659 compile_settings = function()
660 if os.istarget("windows") then
661 add_default_include_paths("vorbis")
662 else
663 pkgconfig.add_includes("ogg")
664 pkgconfig.add_includes("vorbisfile")
666 end,
667 link_settings = function()
668 if os.istarget("windows") then
669 add_default_lib_paths("vorbis")
670 add_default_links({
671 win_names = { "libvorbisfile" },
673 elseif os.getversion().description == "OpenBSD" then
674 -- TODO: We need to force linking with these as currently
675 -- they need to be loaded explicitly on execution
676 add_default_links({
677 unix_names = { "ogg", "vorbis" },
679 else
680 pkgconfig.add_links("vorbisfile")
682 end,
684 wxwidgets = {
685 compile_settings = function()
686 if os.istarget("windows") then
687 includedirs { libraries_dir.."wxwidgets/include/msvc" }
688 add_default_include_paths("wxwidgets")
689 else
690 -- wxwidgets does not come with a definition file for pkg-config,
691 -- so we have to use wxwidgets' own config tool
692 wx_config_path = os.getenv("WX_CONFIG") or "wx-config"
693 pkgconfig.add_includes(nil, wx_config_path, "--unicode=yes --cxxflags")
695 end,
696 link_settings = function()
697 if os.istarget("windows") then
698 libdirs { libraries_dir.."wxwidgets/lib/vc_lib" }
699 else
700 wx_config_path = os.getenv("WX_CONFIG") or "wx-config"
701 pkgconfig.add_links(nil, wx_config_path, "--unicode=yes --libs std,gl")
703 end,
705 x11 = {
706 compile_settings = function()
707 if not os.istarget("windows") and not os.istarget("macosx") then
708 pkgconfig.add_includes("x11")
710 end,
711 link_settings = function()
712 if not os.istarget("windows") and not os.istarget("macosx") then
713 pkgconfig.add_links("x11")
715 end,
717 zlib = {
718 compile_settings = function()
719 if os.istarget("windows") then
720 add_default_include_paths("zlib")
721 else
722 pkgconfig.add_includes("zlib")
724 end,
725 link_settings = function()
726 if os.istarget("windows") then
727 add_default_lib_paths("zlib")
728 add_default_links({
729 win_names = { "zlib1" },
730 no_delayload = 1,
732 else
733 pkgconfig.add_links("zlib")
735 end,
740 -- add a set of external libraries to the project; takes care of
741 -- include / lib path and linking against the import library.
742 -- extern_libs: table of library names [string]
743 -- target_type: String defining the projects kind [string]
744 function project_add_extern_libs(extern_libs, target_type)
746 for i,extern_lib in pairs(extern_libs) do
747 local def = extern_lib_defs[extern_lib]
748 assert(def, "external library " .. extern_lib .. " not defined")
750 if def.compile_settings then
751 def.compile_settings()
754 -- Linking to external libraries will only be done in the main executable and not in the
755 -- static libraries. Premake would silently skip linking into static libraries for some
756 -- actions anyway (e.g. vs2010).
757 -- On osx using xcode, if this linking would be defined in the static libraries, it would fail to
758 -- link if only dylibs are available. If both *.a and *.dylib are available, it would link statically.
759 -- I couldn't find any problems with that approach.
760 if target_type ~= "StaticLib" and def.link_settings then
761 def.link_settings()