@ -16,12 +16,82 @@ import os
from pathlib import PurePath
from . . import build
from . . import dependencies
from . . import mesonlib
from . . import mlog
from . import ModuleReturnValue
from . import ExtensionModule
from . . interpreterbase import permittedKwargs
class DepsHolder :
def __init__ ( self ) :
self . pub_libs = [ ]
self . pub_reqs = [ ]
self . priv_libs = [ ]
self . priv_reqs = [ ]
self . cflags = [ ]
def add_pub_libs ( self , libs ) :
libs , reqs , cflags = self . _process_libs ( libs , True )
self . pub_libs + = libs
self . pub_reqs + = reqs
self . cflags + = cflags
def add_priv_libs ( self , libs ) :
libs , reqs , _ = self . _process_libs ( libs , False )
self . priv_libs + = libs
self . priv_reqs + = reqs
def add_pub_reqs ( self , reqs ) :
self . pub_reqs + = mesonlib . stringlistify ( reqs )
def add_priv_reqs ( self , reqs ) :
self . priv_reqs + = mesonlib . stringlistify ( reqs )
def add_cflags ( self , cflags ) :
self . cflags + = mesonlib . stringlistify ( cflags )
def _process_libs ( self , libs , public ) :
libs = mesonlib . listify ( libs )
processed_libs = [ ]
processed_reqs = [ ]
processed_cflags = [ ]
for obj in libs :
if hasattr ( obj , ' held_object ' ) :
obj = obj . held_object
if hasattr ( obj , ' pcdep ' ) :
pcdeps = mesonlib . listify ( obj . pcdep )
processed_reqs + = [ i . name for i in pcdeps ]
elif isinstance ( obj , dependencies . PkgConfigDependency ) :
processed_reqs . append ( obj . name )
elif isinstance ( obj , dependencies . ThreadDependency ) :
processed_libs + = obj . get_compiler ( ) . thread_link_flags ( obj . env )
processed_cflags + = obj . get_compiler ( ) . thread_flags ( obj . env )
elif isinstance ( obj , dependencies . Dependency ) :
processed_libs + = obj . get_link_args ( )
processed_cflags + = obj . get_compile_args ( )
elif isinstance ( obj , ( build . SharedLibrary , build . StaticLibrary ) ) :
processed_libs . append ( obj )
if public :
self . add_priv_libs ( obj . get_dependencies ( ) )
self . add_priv_libs ( obj . get_external_deps ( ) )
elif isinstance ( obj , str ) :
processed_libs . append ( obj )
else :
raise mesonlib . MesonException ( ' library argument not a string, library or dependency object. ' )
return processed_libs , processed_reqs , processed_cflags
def remove_dups ( self ) :
self . pub_libs = list ( set ( self . pub_libs ) )
self . pub_reqs = list ( set ( self . pub_reqs ) )
self . priv_libs = list ( set ( self . priv_libs ) )
self . priv_reqs = list ( set ( self . priv_reqs ) )
self . cflags = list ( set ( self . cflags ) )
# Remove from pivate libs/reqs if they are in public already
self . priv_libs = [ i for i in self . priv_libs if i not in self . pub_libs ]
self . priv_reqs = [ i for i in self . priv_reqs if i not in self . pub_reqs ]
class PkgConfigModule ( ExtensionModule ) :
@ -64,9 +134,9 @@ class PkgConfigModule(ExtensionModule):
subdir = subdir . replace ( prefix , ' ' )
return subdir
def generate_pkgconfig_file ( self , state , librarie s, subdirs , name , description ,
url , version , pcfile , pub_reqs , priv_reqs ,
conflicts , priv_libs , extra_cflags , variables ) :
def generate_pkgconfig_file ( self , state , dep s, subdirs , name , description ,
url , version , pcfile , conflicts , variables ) :
deps . remove_dups ( )
coredata = state . environment . get_coredata ( )
outdir = state . environment . scratch_dir
fname = os . path . join ( outdir , pcfile )
@ -78,6 +148,8 @@ class PkgConfigModule(ExtensionModule):
ofile . write ( ' prefix= {} \n ' . format ( self . _escape ( prefix ) ) )
ofile . write ( ' libdir= {} \n ' . format ( self . _escape ( ' $ {prefix} ' / libdir ) ) )
ofile . write ( ' includedir= {} \n ' . format ( self . _escape ( ' $ {prefix} ' / incdir ) ) )
if variables :
ofile . write ( ' \n ' )
for k , v in variables :
ofile . write ( ' {} = {} \n ' . format ( k , self . _escape ( v ) ) )
ofile . write ( ' \n ' )
@ -87,11 +159,11 @@ class PkgConfigModule(ExtensionModule):
if len ( url ) > 0 :
ofile . write ( ' URL: %s \n ' % url )
ofile . write ( ' Version: %s \n ' % version )
if len ( pub_reqs ) > 0 :
ofile . write ( ' Requires: {} \n ' . format ( ' ' . join ( pub_reqs ) ) )
if len ( priv_reqs ) > 0 :
if len ( deps . pub_reqs ) > 0 :
ofile . write ( ' Requires: {} \n ' . format ( ' ' . join ( deps . pub_reqs ) ) )
if len ( deps . priv_reqs ) > 0 :
ofile . write (
' Requires.private: {} \n ' . format ( ' ' . join ( priv_reqs ) ) )
' Requires.private: {} \n ' . format ( ' ' . join ( deps . priv_reqs ) ) )
if len ( conflicts ) > 0 :
ofile . write ( ' Conflicts: {} \n ' . format ( ' ' . join ( conflicts ) ) )
@ -117,10 +189,10 @@ class PkgConfigModule(ExtensionModule):
mlog . warning ( msg . format ( l . name , ' name_suffix ' , lname , pcfile ) )
yield ' -l %s ' % lname
if len ( librarie s) > 0 :
ofile . write ( ' Libs: {} \n ' . format ( ' ' . join ( generate_libs_flags ( librarie s) ) ) )
if len ( priv_libs ) > 0 :
ofile . write ( ' Libs.private: {} \n ' . format ( ' ' . join ( generate_libs_flags ( priv_libs ) ) ) )
if len ( deps . pub_lib s) > 0 :
ofile . write ( ' Libs: {} \n ' . format ( ' ' . join ( generate_libs_flags ( deps . pub_lib s) ) ) )
if len ( deps . priv_libs ) > 0 :
ofile . write ( ' Libs.private: {} \n ' . format ( ' ' . join ( generate_libs_flags ( deps . priv_libs ) ) ) )
ofile . write ( ' Cflags: ' )
for h in subdirs :
ofile . write ( ' ' )
@ -128,30 +200,25 @@ class PkgConfigModule(ExtensionModule):
ofile . write ( ' -I$ {includedir} ' )
else :
ofile . write ( self . _escape ( PurePath ( ' -I$ {includedir} ' ) / h ) )
for f in extra_ cflags:
for f in deps . cflags :
ofile . write ( ' ' )
ofile . write ( self . _escape ( f ) )
ofile . write ( ' \n ' )
def process_libs ( self , libs ) :
libs = mesonlib . listify ( libs )
processed_libs = [ ]
for l in libs :
if hasattr ( l , ' held_object ' ) :
l = l . held_object
if not isinstance ( l , ( build . SharedLibrary , build . StaticLibrary , str ) ) :
raise mesonlib . MesonException ( ' Library argument not a library object nor a string. ' )
processed_libs . append ( l )
return processed_libs
@permittedKwargs ( { ' libraries ' , ' version ' , ' name ' , ' description ' , ' filebase ' ,
' subdirs ' , ' requires ' , ' requires_private ' , ' libraries_private ' ,
' install_dir ' , ' extra_cflags ' , ' variables ' , ' url ' , ' d_module_versions ' } )
def generate ( self , state , args , kwargs ) :
if len ( args ) > 0 :
raise mesonlib . MesonException ( ' Pkgconfig_gen takes no positional arguments. ' )
libs = self . process_libs ( kwargs . get ( ' libraries ' , [ ] ) )
priv_libs = self . process_libs ( kwargs . get ( ' libraries_private ' , [ ] ) )
deps = DepsHolder ( )
deps . add_pub_libs ( kwargs . get ( ' libraries ' , [ ] ) )
deps . add_priv_libs ( kwargs . get ( ' libraries_private ' , [ ] ) )
deps . add_pub_reqs ( kwargs . get ( ' requires ' , [ ] ) )
deps . add_priv_reqs ( kwargs . get ( ' requires_private ' , [ ] ) )
deps . add_cflags ( kwargs . get ( ' extra_cflags ' , [ ] ) )
subdirs = mesonlib . stringlistify ( kwargs . get ( ' subdirs ' , [ ' . ' ] ) )
version = kwargs . get ( ' version ' , None )
if not isinstance ( version , str ) :
@ -168,16 +235,13 @@ class PkgConfigModule(ExtensionModule):
url = kwargs . get ( ' url ' , ' ' )
if not isinstance ( url , str ) :
raise mesonlib . MesonException ( ' URL is not a string. ' )
pub_reqs = mesonlib . stringlistify ( kwargs . get ( ' requires ' , [ ] ) )
priv_reqs = mesonlib . stringlistify ( kwargs . get ( ' requires_private ' , [ ] ) )
conflicts = mesonlib . stringlistify ( kwargs . get ( ' conflicts ' , [ ] ) )
extra_cflags = mesonlib . stringlistify ( kwargs . get ( ' extra_cflags ' , [ ] ) )
dversions = kwargs . get ( ' d_module_versions ' , None )
if dversions :
compiler = state . environment . coredata . compilers . get ( ' d ' )
if compiler :
extra_cflags . extend ( compiler . get_feature_args ( { ' versions ' : dversions } ) )
deps . add_cflags ( compiler . get_feature_args ( { ' versions ' : dversions } ) )
def parse_variable_list ( stringlist ) :
reserved = [ ' prefix ' , ' libdir ' , ' includedir ' ]
@ -211,9 +275,8 @@ class PkgConfigModule(ExtensionModule):
pkgroot = os . path . join ( state . environment . coredata . get_builtin_option ( ' libdir ' ) , ' pkgconfig ' )
if not isinstance ( pkgroot , str ) :
raise mesonlib . MesonException ( ' Install_dir must be a string. ' )
self . generate_pkgconfig_file ( state , libs , subdirs , name , description , url ,
version , pcfile , pub_reqs , priv_reqs ,
conflicts , priv_libs , extra_cflags , variables )
self . generate_pkgconfig_file ( state , deps , subdirs , name , description , url ,
version , pcfile , conflicts , variables )
res = build . Data ( mesonlib . File ( True , state . environment . get_scratch_dir ( ) , pcfile ) , pkgroot )
return ModuleReturnValue ( res , [ res ] )