aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/vs2010backend.py41
-rw-r--r--mesonbuild/build.py42
-rw-r--r--mesonbuild/dependencies.py48
-rw-r--r--mesonbuild/environment.py2
-rw-r--r--mesonbuild/mesonmain.py2
-rw-r--r--mesonbuild/scripts/regen_checker.py18
6 files changed, 120 insertions, 33 deletions
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index fc241e3..58a7bd3 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -21,13 +21,13 @@ from .. import mlog
import xml.etree.ElementTree as ET
import xml.dom.minidom
from ..coredata import MesonException
+from ..environment import Environment
class RegenInfo():
- def __init__(self, source_dir, build_dir, depfiles, solutionfile):
+ def __init__(self, source_dir, build_dir, depfiles):
self.source_dir = source_dir
self.build_dir = build_dir
self.depfiles = depfiles
- self.solutionfile = solutionfile
class Vs2010Backend(backends.Backend):
def __init__(self, build):
@@ -92,18 +92,22 @@ class Vs2010Backend(backends.Backend):
self.gen_testproj('RUN_TESTS', os.path.join(self.environment.get_build_dir(), 'RUN_TESTS.vcxproj'))
self.gen_regenproj('REGEN', os.path.join(self.environment.get_build_dir(), 'REGEN.vcxproj'))
self.generate_solution(sln_filename, projlist)
- self.generate_regen_info(sln_filename)
- open(os.path.join(self.environment.get_scratch_dir(), 'regen.stamp'), 'wb')
- rulefile = os.path.join(self.environment.get_scratch_dir(), 'regen.rule')
- if not os.path.exists(rulefile):
- open(rulefile, 'w').write("# For some reason this needs to be here.")
+ self.generate_regen_info()
+ Vs2010Backend.touch_regen_timestamp(self.environment.get_build_dir())
+
+ @staticmethod
+ def get_regen_stampfile(build_dir):
+ return os.path.join(os.path.join(build_dir, Environment.private_dir), 'regen.stamp')
+
+ @staticmethod
+ def touch_regen_timestamp(build_dir):
+ open(Vs2010Backend.get_regen_stampfile(build_dir), 'w').close()
- def generate_regen_info(self, sln_filename):
+ def generate_regen_info(self):
deps = self.get_regen_filelist()
regeninfo = RegenInfo(self.environment.get_source_dir(),
self.environment.get_build_dir(),
- deps,
- sln_filename)
+ deps)
pickle.dump(regeninfo, open(os.path.join(self.environment.get_scratch_dir(), 'regeninfo.dump'), 'wb'))
def get_obj_target_deps(self, obj_list):
@@ -227,10 +231,8 @@ class Vs2010Backend(backends.Backend):
if target.subdir == '':
return ''
- directories = os.path.split(target.subdir)
- directories = list(filter(bool,directories)) #Filter out empty strings
-
- return '/'.join(['..']*len(directories))
+ directories = os.path.normpath(target.subdir).split(os.sep)
+ return os.sep.join(['..']*len(directories))
def special_quote(self, arr):
return ['"%s"' % i for i in arr]
@@ -575,15 +577,18 @@ exit /b %%1
:cmDone
if %%errorlevel%% neq 0 goto :VCEnd'''
igroup = ET.SubElement(root, 'ItemGroup')
- custombuild = ET.SubElement(igroup, 'CustomBuild', Include='meson-private/regen.rule')
+ rulefile = os.path.join(self.environment.get_scratch_dir(), 'regen.rule')
+ if not os.path.exists(rulefile):
+ with open(rulefile, 'w') as f:
+ f.write("# Meson regen file.")
+ custombuild = ET.SubElement(igroup, 'CustomBuild', Include=rulefile)
message = ET.SubElement(custombuild, 'Message')
message.text = 'Checking whether solution needs to be regenerated.'
ET.SubElement(custombuild, 'Command').text = cmd_templ % \
('" "'.join(regen_command), private_dir)
- ET.SubElement(custombuild, 'Outputs').text = os.path.join(self.environment.get_scratch_dir(), 'regen.stamp')
+ ET.SubElement(custombuild, 'Outputs').text = Vs2010Backend.get_regen_stampfile(self.environment.get_build_dir())
deps = self.get_regen_filelist()
- depstr = ';'.join([os.path.join(self.environment.get_source_dir(), d) for d in deps])
- ET.SubElement(custombuild, 'AdditionalInputs').text = depstr
+ ET.SubElement(custombuild, 'AdditionalInputs').text = ';'.join(deps)
ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets')
ET.SubElement(root, 'ImportGroup', Label='ExtensionTargets')
tree = ET.ElementTree(root)
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index f9e628d..e2dd7ca 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -44,7 +44,10 @@ known_basic_kwargs = {'install' : True,
known_shlib_kwargs = known_basic_kwargs.copy()
known_shlib_kwargs.update({'version' : True,
- 'soversion' : True})
+ 'soversion' : True,
+ 'name_prefix' : True,
+ 'name_suffix' : True,
+ })
backslash_explanation = \
'''Compiler arguments have a backslash "\\" character. This is unfortunately not
@@ -411,6 +414,23 @@ class BuildTarget():
if not os.path.isfile(trial):
raise InvalidArguments('Tried to add non-existing resource %s.' % r)
self.resources = resources
+ if 'name_prefix' in kwargs:
+ name_prefix = kwargs['name_prefix']
+ if isinstance(name_prefix, list):
+ if len(name_prefix) != 0:
+ raise InvalidArguments('Array must be empty to signify null.')
+ elif not isinstance(name_prefix, str):
+ raise InvalidArguments('Name prefix must be a string.')
+ self.prefix = name_prefix
+ if 'name_suffix' in kwargs:
+ name_suffix = kwargs['name_suffix']
+ if isinstance(name_suffix, list):
+ if len(name_suffix) != 0:
+ raise InvalidArguments('Array must be empty to signify null.')
+ else:
+ if not isinstance(name_suffix, str):
+ raise InvalidArguments('Name suffix must be a string.')
+ self.suffix = name_suffix
def get_subdir(self):
return self.subdir
@@ -654,7 +674,8 @@ class StaticLibrary(BuildTarget):
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
if len(self.sources) > 0 and self.sources[0].endswith('.cs'):
raise InvalidArguments('Static libraries not supported for C#.')
- self.prefix = environment.get_static_lib_prefix()
+ if not hasattr(self, 'prefix'):
+ self.prefix = environment.get_static_lib_prefix()
self.suffix = environment.get_static_lib_suffix()
if len(self.sources) > 0 and self.sources[0].endswith('.rs'):
self.suffix = 'rlib'
@@ -675,13 +696,18 @@ class SharedLibrary(BuildTarget):
self.soversion = None
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs);
if len(self.sources) > 0 and self.sources[0].endswith('.cs'):
- self.suffix = 'dll'
- self.prefix = 'lib'
+ prefix = 'lib'
+ suffix = 'dll'
else:
- self.prefix = environment.get_shared_lib_prefix()
- self.suffix = environment.get_shared_lib_suffix()
- if len(self.sources) > 0 and self.sources[0].endswith('.rs'):
- self.suffix = 'rlib'
+ prefix = environment.get_shared_lib_prefix()
+ suffix = environment.get_shared_lib_suffix()
+ if not hasattr(self, 'prefix'):
+ self.prefix = prefix
+ if not hasattr(self, 'suffix'):
+ if len(self.sources) > 0 and self.sources[0].endswith('.rs'):
+ self.suffix = 'rlib'
+ else:
+ self.suffix = suffix
self.importsuffix = environment.get_import_lib_suffix()
self.filename = self.prefix + self.name + '.' + self.suffix
diff --git a/mesonbuild/dependencies.py b/mesonbuild/dependencies.py
index b89bc11..ca5fa89 100644
--- a/mesonbuild/dependencies.py
+++ b/mesonbuild/dependencies.py
@@ -21,6 +21,7 @@
import re
import os, stat, glob, subprocess, shutil
+import sysconfig
from . coredata import MesonException
from . import mlog
from . import mesonlib
@@ -1073,6 +1074,52 @@ class ThreadDependency(Dependency):
def need_threads(self):
return True
+class Python3Dependency(Dependency):
+ def __init__(self, environment, kwargs):
+ super().__init__()
+ self.name = 'python3'
+ self.is_found = False
+ try:
+ pkgdep = PkgConfigDependency('python3', environment, kwargs)
+ if pkgdep.found():
+ self.cargs = pkgdep.cargs
+ self.libs = pkgdep.libs
+ self.is_found = True
+ return
+ except Exception:
+ pass
+ if not self.is_found:
+ if mesonlib.is_windows():
+ inc = sysconfig.get_path('include')
+ platinc = sysconfig.get_path('platinclude')
+ self.cargs = ['-I' + inc]
+ if inc != platinc:
+ self.cargs.append('-I' + platinc)
+ # Nothing exposes this directly that I coulf find
+ basedir = sysconfig.get_config_var('base')
+ vernum = sysconfig.get_config_var('py_version_nodot')
+ self.libs = ['-L{}/libs'.format(basedir),
+ '-lpython{}'.format(vernum)]
+ self.is_found = True
+ elif mesonlib.is_osx():
+ # In OSX the Python 3 framework does not have a version
+ # number in its name.
+ fw = ExtraFrameworkDependency('python', False)
+ if fw.found():
+ self.cargs = fw.get_compile_args()
+ self.libs = fw.get_link_args()
+ self.is_found = True
+ if self.is_found:
+ mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.green('YES'))
+ else:
+ mlog.log('Dependency', mlog.bold(self.name), 'found:', mlog.red('NO'))
+
+ def get_compile_args(self):
+ return self.cargs
+
+ def get_link_args(self):
+ return self.libs
+
def get_dep_identifier(name, kwargs):
elements = [name]
modlist = kwargs.get('modules', [])
@@ -1123,4 +1170,5 @@ packages = {'boost': BoostDependency,
'sdl2' : SDL2Dependency,
'gl' : GLDependency,
'threads' : ThreadDependency,
+ 'python3' : Python3Dependency,
}
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 369ca20..1586248 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -126,7 +126,7 @@ class Environment():
def is_cross_build(self):
return self.cross_info is not None
- def generating_finished(self):
+ def dump_coredata(self):
cdf = os.path.join(self.get_build_dir(), Environment.coredata_file)
coredata.save(self.coredata, cdf)
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 1a7b084..543a31f 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -166,8 +166,8 @@ itself as required.'''
mlog.log('Build machine cpu family:', mlog.bold(intr.builtin['build_machine'].cpu_family_method([], {})))
mlog.log('Build machine cpu:', mlog.bold(intr.builtin['build_machine'].cpu_method([], {})))
intr.run()
+ env.dump_coredata()
g.generate(intr)
- env.generating_finished()
dumpfile = os.path.join(env.get_scratch_dir(), 'build.dat')
pickle.dump(b, open(dumpfile, 'wb'))
diff --git a/mesonbuild/scripts/regen_checker.py b/mesonbuild/scripts/regen_checker.py
index a5e5fab..2e974d8 100644
--- a/mesonbuild/scripts/regen_checker.py
+++ b/mesonbuild/scripts/regen_checker.py
@@ -19,13 +19,18 @@ import pickle, subprocess
# This could also be used for XCode.
-def need_regen(regeninfo):
- sln_time = os.stat(os.path.join(regeninfo.build_dir, regeninfo.solutionfile)).st_mtime
+def need_regen(regeninfo, regen_timestamp):
for i in regeninfo.depfiles:
curfile = os.path.join(regeninfo.build_dir, i)
curtime = os.stat(curfile).st_mtime
- if curtime > sln_time:
+ if curtime > regen_timestamp:
return True
+ # The timestamp file gets automatically deleted by MSBuild during a 'Clean' build.
+ # We must make sure to recreate it, even if we do not regenerate the solution.
+ # Otherwise, Visual Studio will always consider the REGEN project out of date.
+ print("Everything is up-to-date, regeneration of build files is not needed.")
+ from mesonbuild.backend.vs2010backend import Vs2010Backend
+ Vs2010Backend.touch_regen_timestamp(regeninfo.build_dir)
return False
def regen(regeninfo):
@@ -41,8 +46,11 @@ def regen(regeninfo):
subprocess.check_call(cmd)
def run(args):
- regeninfo = pickle.load(open(os.path.join(args[0], 'regeninfo.dump'), 'rb'))
- if need_regen(regeninfo):
+ private_dir = args[0]
+ dumpfile = os.path.join(private_dir, 'regeninfo.dump')
+ regeninfo = pickle.load(open(dumpfile, 'rb'))
+ regen_timestamp = os.stat(dumpfile).st_mtime
+ if need_regen(regeninfo, regen_timestamp):
regen(regeninfo)
sys.exit(0)