1 -- this file provides project_add_extern_libs, which takes care of the
2 -- dirty details of adding the libraries' include and lib paths.
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/"
14 -- No Unix-specific libs yet (use source directory instead!)
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" }
24 local function add_source_lib_paths(extern_lib
)
25 libdirs
{ libraries_source_dir
.. extern_lib
.. "/lib" }
28 local function add_default_include_paths(extern_lib
)
29 -- As of premake5-beta2, `sysincludedirs` has been deprecated in favour of
30 -- `externalincludedirs`, and continuing to use it causes warnings to be emitted.
32 -- We use `externalincludedirs` when available to prevent the warnings, falling back
33 -- to `sysincludedirs` when not to prevent breakage of the `--with-system-premake5`
35 if externalincludedirs
then
36 externalincludedirs
{ libraries_dir
.. extern_lib
.. "/include" }
38 sysincludedirs
{ libraries_dir
.. extern_lib
.. "/include" }
42 local function add_source_include_paths(extern_lib
)
43 if externalincludedirs
then
44 externalincludedirs
{ libraries_source_dir
.. extern_lib
.. "/include" }
46 sysincludedirs
{ libraries_source_dir
.. extern_lib
.. "/include" }
50 local function add_third_party_include_paths(extern_lib
)
51 if externalincludedirs
then
52 externalincludedirs
{ third_party_source_dir
.. extern_lib
.. "/include" }
54 sysincludedirs
{ third_party_source_dir
.. extern_lib
.. "/include" }
58 pkgconfig
= require
"pkgconfig"
60 -- Configure pkgconfig for MacOSX systems
61 if os
.istarget("macosx") then
62 pkgconfig
.additional_pc_path
= libraries_dir
.. "pkgconfig/"
63 pkgconfig
.static_link_libs
= true
66 local function add_delayload(name
, suffix
, def
)
68 if def
["no_delayload"] then
72 -- currently only supported by VC; nothing to do on other platforms.
73 if not os
.istarget("windows") then
77 -- no extra debug version; use same library in all configs
79 linkoptions
{ "/DELAYLOAD:"..name
..".dll" }
80 -- extra debug version available; use in debug config
82 local dbg_cmd
= "/DELAYLOAD:" .. name
.. suffix
.. ".dll"
83 local cmd
= "/DELAYLOAD:" .. name
.. ".dll"
86 linkoptions
{ dbg_cmd
}
94 local function add_default_links(def
)
96 -- careful: make sure to only use *_names when on the correct platform.
98 if os
.istarget("windows") then
100 names
= def
.win_names
102 elseif _OPTIONS
["android"] and def
.android_names
then
103 names
= def
.android_names
104 elseif os
.istarget("linux") and def
.linux_names
then
105 names
= def
.linux_names
106 elseif os
.istarget("macosx") and (def
.osx_names
or def
.osx_frameworks
) then
107 if def
.osx_names
then
108 names
= def
.osx_names
110 -- OS X "Frameworks" are added to the links as "name.framework"
111 if def
.osx_frameworks
then
112 for i
,name
in pairs(def
.osx_frameworks
) do
113 links
{ name
.. ".framework" }
116 elseif os
.istarget("bsd") and def
.bsd_names
then
117 names
= def
.bsd_names
118 elseif def
.unix_names
then
119 names
= def
.unix_names
123 -- library is overriding default suffix (typically "" to indicate there is none)
124 if def
["dbg_suffix"] then
125 suffix
= def
["dbg_suffix"]
127 -- non-Windows doesn't have the distinction of debug vs. release libraries
128 -- (to be more specific, they do, but the two are binary compatible;
129 -- usually only one type - debug or release - is installed at a time).
130 if not os
.istarget("windows") then
134 for i
,name
in pairs(names
) do
136 links
{ name
.. suffix
}
141 add_delayload(name
, suffix
, def
)
146 -- Library definitions
147 -- In a perfect world, libraries would have a common installation template,
148 -- i.e. location of include directory, naming convention for .lib, etc.
149 -- this table provides a means of working around each library's differences.
151 -- The basic approach is defining two functions per library:
153 -- 1. compile_settings
154 -- This function should set all settings requred during the compile-phase like
155 -- includedirs, defines etc...
158 -- This function should set all settings required during the link-phase like
159 -- libdirs, linkflag etc...
161 -- The main reason for separating those settings is different linking behaviour
162 -- on osx and xcode. For more details, read the comment in project_add_extern_libs.
164 -- There are some helper functions for the most common tasks. You should use them
165 -- if they can be used in your situation to make the definitions more consistent and
166 -- use their default beviours as a guideline.
169 -- add_default_lib_paths(extern_lib)
170 -- Description: Add '<libraries root>/<libraryname>/lib'to the libpaths
172 -- * extern_lib: <libraryname> to be used in the libpath.
174 -- add_default_include_paths(extern_lib)
175 -- Description: Add '<libraries root>/<libraryname>/include' to the includepaths
177 -- * extern_lib: <libraryname> to be used in the libpath.
180 -- Description: Adds links to libraries and configures delayloading.
181 -- If the *_names parameter for a plattform is missing, no linking will be done
182 -- on that plattform.
183 -- The default assumptions are:
184 -- * debug import library and DLL are distinguished with a "d" suffix
185 -- * the library should be marked for delay-loading.
187 -- * win_names: table of import library / DLL names (no extension) when
188 -- running on Windows.
189 -- * unix_names: as above; shared object names when running on non-Windows.
190 -- * osx_names, osx_frameworks: for OS X specifically; if any of those is
191 -- specified, unix_names is ignored. Using both is possible if needed.
192 -- * osx_names: as above.
193 -- * osx_frameworks: as above, for system libraries that need to be linked
194 -- as "name.framework".
195 -- * bsd_names: as above; for BSD specifically (overrides unix_names if both are
197 -- * linux_names: ditto for Linux (overrides unix_names if both given)
198 -- * dbg_suffix: changes the debug suffix from the above default.
199 -- can be "" to indicate the library doesn't have a debug build;
200 -- in that case, the same library (without suffix) is used in
201 -- all build configurations.
202 -- * no_delayload: indicate the library is not to be delay-loaded.
203 -- this is necessary for some libraries that do not support it,
204 -- e.g. Xerces (which is so stupid as to export variables).
208 compile_settings
= function()
209 if os
.istarget("windows") then
210 -- Force the autolink to use the vc141 libs.
211 defines
{ 'BOOST_LIB_TOOLSET="vc141"' }
212 add_default_include_paths("boost")
213 elseif os
.istarget("macosx") then
214 -- Suppress all the Boost warnings on OS X by including it as a system directory
215 buildoptions
{ "-isystem../" .. libraries_dir
.. "boost/include" }
217 -- TODO: This actually applies to most libraries we use on BSDs, make this a global setting.
218 if os
.istarget("bsd") then
219 if externalincludedirs
then
220 externalincludedirs
{ "/usr/local/include" }
222 sysincludedirs
{ "/usr/local/include" }
226 link_settings
= function()
227 if os
.istarget("windows") or os
.istarget("macosx") then
228 if os
.istarget("windows") then
229 defines
{ 'BOOST_LIB_TOOLSET="vc141"' }
231 add_default_lib_paths("boost")
234 -- The following are not strictly link dependencies on all systems, but
235 -- are included for compatibility with different versions of Boost
236 android_names
= { "boost_filesystem-gcc-mt", "boost_system-gcc-mt" },
237 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" },
238 osx_names
= { "boost_filesystem", "boost_system" },
243 link_settings
= function()
245 win_names
= { "comsuppw" },
252 compile_settings
= function()
253 if externalincludedirs
then
254 externalincludedirs
{ libraries_source_dir
.. "cxxtest-4.4" }
256 sysincludedirs
{ libraries_source_dir
.. "cxxtest-4.4" }
261 compile_settings
= function()
262 if os
.istarget("windows") then
263 add_default_include_paths("enet")
265 pkgconfig
.add_includes("libenet")
268 link_settings
= function()
269 if os
.istarget("windows") then
270 add_default_lib_paths("enet")
272 win_names
= { "enet" },
275 pkgconfig
.add_links("libenet")
280 compile_settings
= function()
281 add_source_include_paths("fcollada")
283 link_settings
= function()
284 add_source_lib_paths("fcollada")
285 if os
.istarget("windows") then
287 links
{ "FColladaD" }
293 links
{ "FColladaSD" }
295 links
{ "FColladaSR" }
301 compile_settings
= function()
302 if os
.istarget("windows") then
303 add_default_include_paths("fmt")
304 elseif os
.istarget("macosx") then
305 pkgconfig
.add_includes("fmt")
308 -- With Linux & BSD, we assume that fmt is installed in a standard location.
310 -- It would be nice to not assume, and to instead use pkg-config: however that
311 -- requires fmt 5.3.0 or greater.
313 -- Unfortunately (at the time of writing) only 92 out of 114 (~80.7%) of distros
314 -- that provide a fmt package meet this, according to
315 -- https://repology.org/badge/vertical-allrepos/fmt.svg?minversion=5.3
317 -- Whilst that might seem like a healthy majority, this does not include the 2018
318 -- Long Term Support and 2019.10 releases of Ubuntu - not only popular and widely
319 -- used as-is, but which are also used as a base for other popular distros (e.g.
322 -- When fmt 5.3 (or better) becomes more widely used, then we can safely use the
323 -- same line as we currently use for osx
325 link_settings
= function()
326 if os
.istarget("windows") then
327 add_default_lib_paths("fmt")
329 win_names
= { "fmt" },
333 elseif os
.istarget("macosx") then
334 -- See comment above as to why this is not also used on Linux or BSD.
335 pkgconfig
.add_links("fmt")
338 unix_names
= { "fmt" },
344 compile_settings
= function()
345 if os
.istarget("windows") then
346 add_default_include_paths("freetype")
348 pkgconfig
.add_includes("freetype2")
351 link_settings
= function()
352 if os
.istarget("windows") then
353 add_default_lib_paths("freetype")
355 pkgconfig
.add_links("freetype2")
358 win_names
= { "freetype" },
364 add_source_include_paths("glad")
367 compile_settings
= function()
368 if os
.istarget("windows") then
369 add_default_include_paths("gloox")
371 pkgconfig
.add_includes("gloox")
374 link_settings
= function()
375 if os
.istarget("windows") then
376 add_default_lib_paths("gloox")
378 win_names
= { "gloox-1.0" },
382 pkgconfig
.add_links("gloox")
384 if os
.istarget("macosx") then
385 -- gloox depends on gnutls, but doesn't identify this via pkg-config
386 pkgconfig
.add_links("gnutls")
392 compile_settings
= function()
393 if os
.istarget("windows") then
394 add_default_include_paths("iconv")
395 defines
{ "HAVE_ICONV_CONST" }
396 defines
{ "ICONV_CONST=const" }
397 defines
{ "LIBICONV_STATIC" }
398 elseif os
.istarget("macosx") then
399 add_default_include_paths("iconv")
400 defines
{ "LIBICONV_STATIC" }
401 elseif os
.getversion().description
== "FreeBSD" then
402 -- On FreeBSD you need this flag to tell it to use the BSD libc iconv
403 defines
{ "LIBICONV_PLUG" }
406 link_settings
= function()
407 if os
.istarget("windows") or os
.istarget("macosx") then
408 add_default_lib_paths("iconv")
411 win_names
= { "libiconv" },
412 osx_names
= { "iconv" },
416 -- glibc (used on Linux and GNU/kFreeBSD) has iconv
420 compile_settings
= function()
421 if os
.istarget("windows") then
422 add_default_include_paths("icu")
424 pkgconfig
.add_includes("icu-i18n")
427 link_settings
= function()
428 if os
.istarget("windows") then
429 add_default_lib_paths("icu")
431 win_names
= { "icuuc", "icuin" },
436 pkgconfig
.add_links("icu-i18n")
441 compile_settings
= function()
442 if os
.istarget("windows") then
443 add_default_include_paths("libcurl")
445 pkgconfig
.add_includes("libcurl")
448 link_settings
= function()
449 if os
.istarget("windows") then
450 add_default_lib_paths("libcurl")
452 pkgconfig
.add_links("libcurl")
455 win_names
= { "libcurl" },
456 osx_frameworks
= { "Security" }, -- Not supplied by curl's pkg-config
461 compile_settings
= function()
462 if os
.istarget("windows") then
463 add_default_include_paths("libpng")
465 pkgconfig
.add_includes("libpng")
468 link_settings
= function()
469 if os
.istarget("windows") then
470 add_default_lib_paths("libpng")
472 win_names
= { "libpng16" },
475 pkgconfig
.add_links("libpng")
480 compile_settings
= function()
481 if os
.istarget("windows") then
482 add_default_include_paths("libsodium")
484 pkgconfig
.add_includes("libsodium")
487 link_settings
= function()
488 if os
.istarget("windows") then
489 add_default_lib_paths("libsodium")
491 win_names
= { "libsodium" },
494 pkgconfig
.add_links("libsodium")
499 compile_settings
= function()
500 if os
.istarget("windows") then
501 add_default_include_paths("libxml2")
503 pkgconfig
.add_includes("libxml-2.0")
505 if os
.istarget("macosx") then
506 -- libxml2 needs _REENTRANT or __MT__ for thread support;
507 -- OS X doesn't get either set by default, so do it manually
508 defines
{ "_REENTRANT" }
512 link_settings
= function()
513 if os
.istarget("windows") then
514 add_default_lib_paths("libxml2")
521 pkgconfig
.add_links("libxml-2.0")
526 compile_settings
= function()
527 if os
.istarget("windows") then
528 add_default_include_paths("miniupnpc")
529 elseif os
.istarget("macosx") then
530 pkgconfig
.add_includes("miniupnpc")
533 -- On Linux and BSD systems we assume miniupnpc is installed in a standard location.
535 -- Support for pkg-config was added in v2.1 of miniupnpc (May 2018). However, the
536 -- implementation was flawed - it provided the wrong path to the project's headers.
537 -- This was corrected in v2.2.1 (December 2020).
539 -- At the time of writing, of the 123 Linux and BSD package repositories tracked by
540 -- Repology that supply a version of miniupnpc:
541 -- * 88 (~71.54%) have >= v2.1, needed to locate libraries
542 -- * 50 (~40.65%) have >= v2.2.1, needed to (correctly) locate headers
544 -- Once more recent versions become more widespread, we can safely start to use
545 -- pkg-config to find miniupnpc on Linux and BSD systems.
546 -- https://repology.org/badge/vertical-allrepos/miniupnpc.svg?minversion=2.2.1
548 link_settings
= function()
549 if os
.istarget("windows") then
550 add_default_lib_paths("miniupnpc")
552 win_names
= { "miniupnpc" },
554 elseif os
.istarget("macosx") then
555 pkgconfig
.add_links("miniupnpc")
557 -- Once miniupnpc v2.1 or better becomes near-universal (see above comment),
558 -- we can use pkg-config for Linux and BSD.
560 unix_names
= { "miniupnpc" },
566 compile_settings
= function()
567 if not _OPTIONS
["with-system-nvtt"] then
568 add_source_include_paths("nvtt")
570 defines
{ "NVTT_SHARED=1" }
572 link_settings
= function()
573 if not _OPTIONS
["with-system-nvtt"] then
574 add_source_lib_paths("nvtt")
577 win_names
= { "nvtt" },
578 unix_names
= { "nvcore", "nvmath", "nvimage", "nvtt" },
579 osx_names
= { "bc6h", "bc7", "nvcore", "nvimage", "nvmath", "nvthread", "nvtt", "squish" },
580 dbg_suffix
= "", -- for performance we always use the release-mode version
585 compile_settings
= function()
586 if os
.istarget("windows") then
587 add_default_include_paths("openal")
588 elseif not os
.istarget("macosx") then
589 pkgconfig
.add_includes("openal")
592 link_settings
= function()
593 if os
.istarget("windows") then
594 add_default_lib_paths("openal")
596 win_names
= { "openal32" },
598 no_delayload
= 1, -- delayload seems to cause errors on startup
600 elseif os
.istarget("macosx") then
602 osx_frameworks
= { "OpenAL" },
605 pkgconfig
.add_links("openal")
610 compile_settings
= function()
611 if os
.istarget("windows") then
612 includedirs
{ libraries_dir
.. "sdl2/include/SDL" }
613 elseif not _OPTIONS
["android"] then
614 pkgconfig
.add_includes("sdl2")
617 link_settings
= function()
618 if os
.istarget("windows") then
619 add_default_lib_paths("sdl2")
620 elseif not _OPTIONS
["android"] then
621 pkgconfig
.add_links("sdl2")
626 compile_settings
= function()
627 if _OPTIONS
["with-system-mozjs"] then
628 if not _OPTIONS
["android"] then
629 pkgconfig
.add_includes("mozjs-91")
632 if os
.istarget("windows") then
633 include_dir
= "include-win32"
635 include_dir
= "include-unix"
638 if externalincludedirs
then
639 externalincludedirs
{ libraries_source_dir
.."spidermonkey/"..include_dir
.."-debug" }
641 sysincludedirs
{ libraries_source_dir
.."spidermonkey/"..include_dir
.."-debug" }
645 if externalincludedirs
then
646 externalincludedirs
{ libraries_source_dir
.."spidermonkey/"..include_dir
.."-release" }
648 sysincludedirs
{ libraries_source_dir
.."spidermonkey/"..include_dir
.."-release" }
653 link_settings
= function()
654 if _OPTIONS
["with-system-mozjs"] then
655 if _OPTIONS
["android"] then
658 pkgconfig
.add_links("mozjs-91")
661 filter
{ "Debug", "action:vs*" }
662 links
{ "mozjs91-ps-debug" }
663 links
{ "mozjs91-ps-rust-debug" }
664 filter
{ "Debug", "action:not vs*" }
665 links
{ "mozjs91-ps-debug" }
666 links
{ "mozjs91-ps-rust" }
668 links
{ "mozjs91-ps-release" }
669 links
{ "mozjs91-ps-rust" }
671 add_source_lib_paths("spidermonkey")
676 compile_settings
= function()
677 add_third_party_include_paths("tinygettext")
681 compile_settings
= function()
682 -- Optional dependency
684 -- valgrind doesn't support windows:
685 -- https://valgrind.org/info/platforms.html
686 if _OPTIONS
["with-valgrind"] and not os
.istarget("windows") then
687 pkgconfig
.add_includes("valgrind")
688 defines
{ "CONFIG2_VALGRIND=1" }
693 compile_settings
= function()
694 if os
.istarget("windows") then
695 add_default_include_paths("vorbis")
697 pkgconfig
.add_includes("ogg")
698 pkgconfig
.add_includes("vorbisfile")
701 link_settings
= function()
702 if os
.istarget("windows") then
703 add_default_lib_paths("vorbis")
705 win_names
= { "libvorbisfile" },
707 elseif os
.getversion().description
== "OpenBSD" then
708 -- TODO: We need to force linking with these as currently
709 -- they need to be loaded explicitly on execution
711 unix_names
= { "ogg", "vorbis" },
714 pkgconfig
.add_links("vorbisfile")
719 compile_settings
= function()
720 if os
.istarget("windows") then
721 includedirs
{ libraries_dir
.."wxwidgets/include/msvc" }
722 add_default_include_paths("wxwidgets")
724 -- wxwidgets does not come with a definition file for pkg-config,
725 -- so we have to use wxwidgets' own config tool
726 wx_config_path
= os
.getenv("WX_CONFIG") or "wx-config"
727 pkgconfig
.add_includes(nil, wx_config_path
, "--unicode=yes --cxxflags")
730 link_settings
= function()
731 if os
.istarget("windows") then
732 libdirs
{ libraries_dir
.."wxwidgets/lib/vc_lib" }
734 wx_config_path
= os
.getenv("WX_CONFIG") or "wx-config"
735 pkgconfig
.add_links(nil, wx_config_path
, "--unicode=yes --libs std,gl")
740 compile_settings
= function()
741 if not os
.istarget("windows") and not os
.istarget("macosx") then
742 pkgconfig
.add_includes("x11")
745 link_settings
= function()
746 if not os
.istarget("windows") and not os
.istarget("macosx") then
747 pkgconfig
.add_links("x11")
752 compile_settings
= function()
753 if os
.istarget("windows") then
754 add_default_include_paths("zlib")
756 pkgconfig
.add_includes("zlib")
759 link_settings
= function()
760 if os
.istarget("windows") then
761 add_default_lib_paths("zlib")
763 win_names
= { "zlib1" },
767 pkgconfig
.add_links("zlib")
774 -- add a set of external libraries to the project; takes care of
775 -- include / lib path and linking against the import library.
776 -- extern_libs: table of library names [string]
777 -- target_type: String defining the projects kind [string]
778 function project_add_extern_libs(extern_libs
, target_type
)
780 for i
,extern_lib
in pairs(extern_libs
) do
781 local def
= extern_lib_defs
[extern_lib
]
782 assert(def
, "external library " .. extern_lib
.. " not defined")
784 if def
.compile_settings
then
785 def
.compile_settings()
788 -- Linking to external libraries will only be done in the main executable and not in the
789 -- static libraries. Premake would silently skip linking into static libraries for some
790 -- actions anyway (e.g. vs2010).
791 -- On osx using xcode, if this linking would be defined in the static libraries, it would fail to
792 -- link if only dylibs are available. If both *.a and *.dylib are available, it would link statically.
793 -- I couldn't find any problems with that approach.
794 if target_type
~= "StaticLib" and def
.link_settings
then