Moved pkg-config to a module so we no longer need special case code in core for it.

pull/340/head
Jussi Pakkanen 9 years ago
parent c86ee8158a
commit d64211f570
  1. 26
      backends.py
  2. 23
      build.py
  3. 66
      interpreter.py
  4. 82
      modules/pkgconfig.py
  5. 20
      ninjabackend.py
  6. 12
      test cases/common/51 pkgconfig-gen/meson.build

@ -311,32 +311,6 @@ class Backend():
arr.append(ts)
pickle.dump(arr, datafile)
def generate_pkgconfig_files(self):
for p in self.build.pkgconfig_gens:
outdir = self.environment.scratch_dir
fname = os.path.join(outdir, p.filebase + '.pc')
ofile = open(fname, 'w')
coredata = self.environment.get_coredata()
ofile.write('prefix=%s\n' % coredata.get_builtin_option('prefix'))
ofile.write('libdir=${prefix}/%s\n' % coredata.get_builtin_option('libdir'))
ofile.write('includedir=${prefix}/%s\n\n' % coredata.get_builtin_option('includedir'))
ofile.write('Name: %s\n' % p.name)
if len(p.description) > 0:
ofile.write('Description: %s\n' % p.description)
if len(p.version) > 0:
ofile.write('Version: %s\n' % p.version)
ofile.write('Libs: -L${libdir} ')
for l in p.libraries:
ofile.write('-l%s ' % l.name)
ofile.write('\n')
ofile.write('CFlags: ')
for h in p.subdirs:
if h == '.':
h = ''
ofile.write(os.path.join('-I${includedir}', h))
ofile.write(' ')
ofile.write('\n')
def generate_depmf_install(self, d):
if self.build.dep_manifest_name is None:

@ -73,7 +73,6 @@ class Build:
self.static_cross_linker = None
self.pot = []
self.subprojects = {}
self.pkgconfig_gens = []
self.install_scripts = []
self.install_dirs = []
self.dep_manifest_name = None
@ -930,20 +929,14 @@ class ConfigurationData():
def keys(self):
return self.values.keys()
class PkgConfigGenerator():
def __init__(self, libraries, subdirs, name, description, version, filebase):
self.libraries = []
for l in libraries:
if hasattr(l, 'held_object'):
self.libraries.append(l.held_object)
else:
self.libraries.append(l)
self.headerdirs = {}
self.subdirs = subdirs
self.name = name
self.description = description
self.version = version
self.filebase = filebase
# A bit poorly named, but this represents plain data files to copy
# during install.
class Data():
def __init__(self, in_sourcetree, source_subdir, sources, install_dir):
self.in_sourcetree = in_sourcetree
self.source_subdir = source_subdir
self.sources = sources
self.install_dir = install_dir
class InstallScript:
def __init__(self, cmd_arr):

@ -399,29 +399,25 @@ class Headers(InterpreterObject):
def get_custom_install_dir(self):
return self.custom_install_dir
class Data(InterpreterObject):
class DataHolder(InterpreterObject):
def __init__(self, in_sourcetree, source_subdir, sources, kwargs):
InterpreterObject.__init__(self)
self.in_sourcetree = in_sourcetree
self.source_subdir = source_subdir
self.sources = sources
kwsource = kwargs.get('sources', [])
if not isinstance(kwsource, list):
kwsource = [kwsource]
self.sources += kwsource
check_stringlist(self.sources)
self.install_dir = kwargs.get('install_dir', None)
if not isinstance(self.install_dir, str):
super().__init__()
kwsource = mesonlib.stringlistify(kwargs.get('sources', []))
sources += kwsource
check_stringlist(sources)
install_dir = kwargs.get('install_dir', None)
if not isinstance(install_dir, str):
raise InterpreterException('Custom_install_dir must be a string.')
self.held_object = build.Data(in_sourcetree, source_subdir, sources, install_dir)
def get_source_subdir(self):
return self.source_subdir
return self.held_object.source_subdir
def get_sources(self):
return self.sources
return self.held_object.sources
def get_install_dir(self):
return self.install_dir
return self.held_object.install_dir
class InstallDir(InterpreterObject):
def __init__(self, source_subdir, installable_subdir, install_dir):
@ -775,7 +771,6 @@ class ModuleHolder(InterpreterObject):
state.targets = self.interpreter.build.targets
state.headers = self.interpreter.build.get_headers()
state.man = self.interpreter.build.get_man()
state.pkgconfig_gens = self.interpreter.build.pkgconfig_gens
state.global_args = self.interpreter.build.global_args
value = fn(state, args, kwargs)
return self.interpreter.module_method_callback(value)
@ -963,7 +958,6 @@ class Interpreter():
'option' : self.func_option,
'get_option' : self.func_get_option,
'subproject' : self.func_subproject,
'pkgconfig_gen' : self.func_pkgconfig_gen,
'vcs_tag' : self.func_vcs_tag,
'set_variable' : self.func_set_variable,
'is_variable' : self.func_is_variable,
@ -1005,6 +999,8 @@ class Interpreter():
self.build.targets[v.name] = v
elif isinstance(v, build.InstallScript):
self.build.install_scripts.append(v)
elif isinstance(v, build.Data):
self.build.data.append(v)
else:
print(v)
raise InterpreterException('Module returned a value of unknown type.')
@ -1246,36 +1242,6 @@ class Interpreter():
def func_option(self, nodes, args, kwargs):
raise InterpreterException('Tried to call option() in build description file. All options must be in the option file.')
def func_pkgconfig_gen(self, nodes, args, kwargs):
if len(args) > 0:
raise InterpreterException('Pkgconfig_gen takes no positional arguments.')
libs = kwargs.get('libraries', [])
if not isinstance(libs, list):
libs = [libs]
for l in libs:
if not (isinstance(l, SharedLibraryHolder) or isinstance(l, StaticLibraryHolder)):
raise InterpreterException('Library argument not a library object.')
subdirs = kwargs.get('subdirs', ['.'])
if not isinstance(subdirs, list):
subdirs = [subdirs]
for h in subdirs:
if not isinstance(h, str):
raise InterpreterException('Header argument not string.')
version = kwargs.get('version', '')
if not isinstance(version, str):
raise InterpreterException('Version must be a string.')
name = kwargs.get('name', None)
if not isinstance(name, str):
raise InterpreterException('Name not specified.')
filebase = kwargs.get('filebase', name)
if not isinstance(filebase, str):
raise InterpreterException('Filebase must be a string.')
description = kwargs.get('description', None)
if not isinstance(description, str):
raise InterpreterException('Description is not a string.')
p = build.PkgConfigGenerator(libs, subdirs, name, description, version, filebase)
self.build.pkgconfig_gens.append(p)
@stringArgs
def func_subproject(self, nodes, args, kwargs):
if len(args) != 1:
@ -1801,8 +1767,8 @@ class Interpreter():
@stringArgs
def func_install_data(self, node, args, kwargs):
data = Data(True, self.subdir, args, kwargs)
self.build.data.append(data)
data = DataHolder(True, self.subdir, args, kwargs)
self.build.data.append(data.held_object)
return data
@stringArgs
@ -1852,7 +1818,7 @@ class Interpreter():
else:
raise InterpreterException('Configure_file must have either "configuration" or "command".')
if isinstance(kwargs.get('install_dir', None), str):
self.build.data.append(Data(False, self.subdir, [output], kwargs))
self.build.data.append(DataHolder(False, self.subdir, [output], kwargs).held_object)
return mesonlib.File.from_built_file(self.subdir, output)
@stringArgs

@ -0,0 +1,82 @@
# Copyright 2015 The Meson development team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import coredata, build
import mesonlib
import os
class PkgConfigModule:
def print_hello(self, state, args, kwargs):
print('Hello from a Meson module')
def generate_pkgconfig_file(self, state, libraries, subdirs, name, description, version, filebase):
outdir = state.environment.scratch_dir
fname = os.path.join(outdir, filebase + '.pc')
ofile = open(fname, 'w')
coredata = state.environment.get_coredata()
ofile.write('prefix=%s\n' % coredata.get_builtin_option('prefix'))
ofile.write('libdir=${prefix}/%s\n' % coredata.get_builtin_option('libdir'))
ofile.write('includedir=${prefix}/%s\n\n' % coredata.get_builtin_option('includedir'))
ofile.write('Name: %s\n' % name)
if len(description) > 0:
ofile.write('Description: %s\n' % description)
if len(version) > 0:
ofile.write('Version: %s\n' % version)
ofile.write('Libs: -L${libdir} ')
for l in libraries:
ofile.write('-l%s ' % l.name)
ofile.write('\n')
ofile.write('CFlags: ')
for h in subdirs:
if h == '.':
h = ''
ofile.write(os.path.join('-I${includedir}', h))
ofile.write(' ')
ofile.write('\n')
def generate(self, state, args, kwargs):
if len(args) > 0:
raise coredata.MesonException('Pkgconfig_gen takes no positional arguments.')
libs = kwargs.get('libraries', [])
if not isinstance(libs, list):
libs = [libs]
processed_libs = []
for l in libs:
if hasattr(l, 'held_object'):
l = l.held_object
if not (isinstance(l, build.SharedLibrary) or isinstance(l, build.StaticLibrary)):
raise coredata.MesonException('Library argument not a library object.')
processed_libs.append(l)
libs = processed_libs
subdirs = mesonlib.stringlistify(kwargs.get('subdirs', ['.']))
version = kwargs.get('version', '')
if not isinstance(version, str):
raise coredata.MesonException('Version must be a string.')
name = kwargs.get('name', None)
if not isinstance(name, str):
raise coredata.MesonException('Name not specified.')
filebase = kwargs.get('filebase', name)
if not isinstance(filebase, str):
raise coredata.MesonException('Filebase must be a string.')
description = kwargs.get('description', None)
if not isinstance(description, str):
raise coredata.MesonException('Description is not a string.')
pcfile = filebase + '.pc'
pkgroot = os.path.join(state.environment.coredata.get_builtin_option('libdir'), 'pkgconfig')
self.generate_pkgconfig_file(state, libs, subdirs, name, description, version, filebase)
return build.Data(False, state.environment.get_scratch_dir(), [pcfile], pkgroot)
def initialize():
return PkgConfigModule()

@ -162,7 +162,6 @@ int dummy;
outfilename = os.path.join(self.environment.get_build_dir(), self.ninja_filename)
tempfilename = outfilename + '~'
outfile = open(tempfilename, 'w')
self.generate_pkgconfig_files()
outfile.write('# This is the build file for project "%s"\n' % self.build.get_project())
outfile.write('# It is autogenerated by the Meson build system.\n')
outfile.write('# Do not edit by hand.\n\n')
@ -470,7 +469,6 @@ int dummy;
self.generate_man_install(d)
self.generate_data_install(d)
self.generate_po_install(d, elem)
self.generate_pkgconfig_install(d)
self.generate_custom_install_script(d)
self.generate_subdir_install(d)
elem.write(outfile)
@ -507,17 +505,6 @@ int dummy;
should_strip, t.install_rpath]
d.targets.append(i)
def generate_pkgconfig_install(self, d):
pkgroot = os.path.join(self.environment.coredata.get_builtin_option('libdir'), 'pkgconfig')
for p in self.build.pkgconfig_gens:
pcfile = p.filebase + '.pc'
srcabs = os.path.join(self.environment.get_scratch_dir(),
pcfile)
dstrel = os.path.join(pkgroot, pcfile)
i = [srcabs, dstrel]
d.man.append(i)
def generate_custom_install_script(self, d):
d.install_scripts = self.build.install_scripts
@ -551,13 +538,14 @@ int dummy;
def generate_data_install(self, d):
data = self.build.get_data()
for de in data:
subdir = de.get_install_dir()
for f in de.get_sources():
assert(isinstance(de, build.Data))
subdir = de.install_dir
for f in de.sources:
if de.in_sourcetree:
srcprefix = self.environment.get_source_dir()
else:
srcprefix = self.environment.get_build_dir()
srcabs = os.path.join(srcprefix, de.get_source_subdir(), f)
srcabs = os.path.join(srcprefix, de.source_subdir, f)
dstabs = os.path.join(subdir, f)
i = [srcabs, dstabs]
d.data.append(i)

@ -1,8 +1,16 @@
project('pkgconfig-gen', 'c')
pkgg = import('pkgconfig')
lib = shared_library('simple', 'simple.c', install : true)
libver = '1.0'
h = install_headers('simple.h')
pkgconfig_gen(libraries : lib, subdirs : '.', version : libver,
name : 'libsimple', filebase : 'simple', description : 'A simple demo library.')
pkgg.generate(
libraries : lib,
subdirs : '.',
version : libver,
name : 'libsimple',
filebase : 'simple',
description : 'A simple demo library.'
)

Loading…
Cancel
Save