|
|
@ -12,6 +12,11 @@ |
|
|
|
# See the License for the specific language governing permissions and |
|
|
|
# See the License for the specific language governing permissions and |
|
|
|
# limitations under the License. |
|
|
|
# limitations under the License. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import shlex |
|
|
|
|
|
|
|
import os, sys, pickle, re |
|
|
|
|
|
|
|
import subprocess, shutil |
|
|
|
|
|
|
|
from collections import OrderedDict |
|
|
|
|
|
|
|
|
|
|
|
from . import backends |
|
|
|
from . import backends |
|
|
|
from .. import modules |
|
|
|
from .. import modules |
|
|
|
from .. import environment, mesonlib |
|
|
|
from .. import environment, mesonlib |
|
|
@ -24,16 +29,13 @@ from ..mesonlib import File, MesonException, OrderedSet |
|
|
|
from ..mesonlib import get_meson_script, get_compiler_for_source |
|
|
|
from ..mesonlib import get_meson_script, get_compiler_for_source |
|
|
|
from .backends import CleanTrees, InstallData |
|
|
|
from .backends import CleanTrees, InstallData |
|
|
|
from ..build import InvalidArguments |
|
|
|
from ..build import InvalidArguments |
|
|
|
import os, sys, pickle, re |
|
|
|
|
|
|
|
import subprocess, shutil |
|
|
|
|
|
|
|
from collections import OrderedDict |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if mesonlib.is_windows(): |
|
|
|
if mesonlib.is_windows(): |
|
|
|
quote_char = '"' |
|
|
|
quote_func = lambda s: '"{}"'.format(s) |
|
|
|
execute_wrapper = 'cmd /c' |
|
|
|
execute_wrapper = 'cmd /c' |
|
|
|
rmfile_prefix = 'del /f /s /q {} &&' |
|
|
|
rmfile_prefix = 'del /f /s /q {} &&' |
|
|
|
else: |
|
|
|
else: |
|
|
|
quote_char = "'" |
|
|
|
quote_func = shlex.quote |
|
|
|
execute_wrapper = '' |
|
|
|
execute_wrapper = '' |
|
|
|
rmfile_prefix = 'rm -f {} &&' |
|
|
|
rmfile_prefix = 'rm -f {} &&' |
|
|
|
|
|
|
|
|
|
|
@ -58,22 +60,22 @@ class NinjaBuildElement: |
|
|
|
self.infilenames = [infilenames] |
|
|
|
self.infilenames = [infilenames] |
|
|
|
else: |
|
|
|
else: |
|
|
|
self.infilenames = infilenames |
|
|
|
self.infilenames = infilenames |
|
|
|
self.deps = [] |
|
|
|
self.deps = set() |
|
|
|
self.orderdeps = [] |
|
|
|
self.orderdeps = set() |
|
|
|
self.elems = [] |
|
|
|
self.elems = [] |
|
|
|
self.all_outputs = all_outputs |
|
|
|
self.all_outputs = all_outputs |
|
|
|
|
|
|
|
|
|
|
|
def add_dep(self, dep): |
|
|
|
def add_dep(self, dep): |
|
|
|
if isinstance(dep, list): |
|
|
|
if isinstance(dep, list): |
|
|
|
self.deps += dep |
|
|
|
self.deps.update(dep) |
|
|
|
else: |
|
|
|
else: |
|
|
|
self.deps.append(dep) |
|
|
|
self.deps.add(dep) |
|
|
|
|
|
|
|
|
|
|
|
def add_orderdep(self, dep): |
|
|
|
def add_orderdep(self, dep): |
|
|
|
if isinstance(dep, list): |
|
|
|
if isinstance(dep, list): |
|
|
|
self.orderdeps += dep |
|
|
|
self.orderdeps.update(dep) |
|
|
|
else: |
|
|
|
else: |
|
|
|
self.orderdeps.append(dep) |
|
|
|
self.orderdeps.add(dep) |
|
|
|
|
|
|
|
|
|
|
|
def add_item(self, name, elems): |
|
|
|
def add_item(self, name, elems): |
|
|
|
if isinstance(elems, str): |
|
|
|
if isinstance(elems, str): |
|
|
@ -105,18 +107,17 @@ class NinjaBuildElement: |
|
|
|
(name, elems) = e |
|
|
|
(name, elems) = e |
|
|
|
should_quote = name not in raw_names |
|
|
|
should_quote = name not in raw_names |
|
|
|
line = ' %s = ' % name |
|
|
|
line = ' %s = ' % name |
|
|
|
q_templ = quote_char + "%s" + quote_char |
|
|
|
|
|
|
|
noq_templ = "%s" |
|
|
|
noq_templ = "%s" |
|
|
|
newelems = [] |
|
|
|
newelems = [] |
|
|
|
for i in elems: |
|
|
|
for i in elems: |
|
|
|
if not should_quote or i == '&&': # Hackety hack hack |
|
|
|
if not should_quote or i == '&&': # Hackety hack hack |
|
|
|
templ = noq_templ |
|
|
|
quoter = ninja_quote |
|
|
|
else: |
|
|
|
else: |
|
|
|
templ = q_templ |
|
|
|
quoter = lambda x: ninja_quote(quote_func(x)) |
|
|
|
i = i.replace('\\', '\\\\') |
|
|
|
i = i.replace('\\', '\\\\') |
|
|
|
if quote_char == '"': |
|
|
|
if quote_func('') == '""': |
|
|
|
i = i.replace('"', '\\"') |
|
|
|
i = i.replace('"', '\\"') |
|
|
|
newelems.append(templ % ninja_quote(i)) |
|
|
|
newelems.append(quoter(i)) |
|
|
|
line += ' '.join(newelems) |
|
|
|
line += ' '.join(newelems) |
|
|
|
line += '\n' |
|
|
|
line += '\n' |
|
|
|
outfile.write(line) |
|
|
|
outfile.write(line) |
|
|
@ -854,12 +855,12 @@ int dummy; |
|
|
|
outfile.write(' depfile = $DEPFILE\n') |
|
|
|
outfile.write(' depfile = $DEPFILE\n') |
|
|
|
outfile.write(' restat = 1\n\n') |
|
|
|
outfile.write(' restat = 1\n\n') |
|
|
|
outfile.write('rule REGENERATE_BUILD\n') |
|
|
|
outfile.write('rule REGENERATE_BUILD\n') |
|
|
|
c = (quote_char + ninja_quote(sys.executable) + quote_char, |
|
|
|
c = (ninja_quote(quote_func(sys.executable)), |
|
|
|
quote_char + ninja_quote(self.environment.get_build_command()) + quote_char, |
|
|
|
ninja_quote(quote_func(self.environment.get_build_command())), |
|
|
|
'--internal', |
|
|
|
'--internal', |
|
|
|
'regenerate', |
|
|
|
'regenerate', |
|
|
|
quote_char + ninja_quote(self.environment.get_source_dir()) + quote_char, |
|
|
|
ninja_quote(quote_func(self.environment.get_source_dir())), |
|
|
|
quote_char + ninja_quote(self.environment.get_build_dir()) + quote_char) |
|
|
|
ninja_quote(quote_func(self.environment.get_build_dir()))) |
|
|
|
outfile.write(" command = %s %s %s %s %s %s --backend ninja\n" % c) |
|
|
|
outfile.write(" command = %s %s %s %s %s %s --backend ninja\n" % c) |
|
|
|
outfile.write(' description = Regenerating build files.\n') |
|
|
|
outfile.write(' description = Regenerating build files.\n') |
|
|
|
outfile.write(' generator = 1\n\n') |
|
|
|
outfile.write(' generator = 1\n\n') |
|
|
@ -1515,7 +1516,7 @@ rule FORTRAN_DEP_HACK |
|
|
|
pass |
|
|
|
pass |
|
|
|
return [] |
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
def generate_compile_rule_for(self, langname, compiler, qstr, is_cross, outfile): |
|
|
|
def generate_compile_rule_for(self, langname, compiler, is_cross, outfile): |
|
|
|
if langname == 'java': |
|
|
|
if langname == 'java': |
|
|
|
if not is_cross: |
|
|
|
if not is_cross: |
|
|
|
self.generate_java_compile_rule(compiler, outfile) |
|
|
|
self.generate_java_compile_rule(compiler, outfile) |
|
|
@ -1547,7 +1548,7 @@ rule FORTRAN_DEP_HACK |
|
|
|
quoted_depargs = [] |
|
|
|
quoted_depargs = [] |
|
|
|
for d in depargs: |
|
|
|
for d in depargs: |
|
|
|
if d != '$out' and d != '$in': |
|
|
|
if d != '$out' and d != '$in': |
|
|
|
d = qstr % d |
|
|
|
d = quote_func(d) |
|
|
|
quoted_depargs.append(d) |
|
|
|
quoted_depargs.append(d) |
|
|
|
cross_args = self.get_cross_info_lang_args(langname, is_cross) |
|
|
|
cross_args = self.get_cross_info_lang_args(langname, is_cross) |
|
|
|
if mesonlib.is_windows(): |
|
|
|
if mesonlib.is_windows(): |
|
|
@ -1576,7 +1577,7 @@ rule FORTRAN_DEP_HACK |
|
|
|
outfile.write(description) |
|
|
|
outfile.write(description) |
|
|
|
outfile.write('\n') |
|
|
|
outfile.write('\n') |
|
|
|
|
|
|
|
|
|
|
|
def generate_pch_rule_for(self, langname, compiler, qstr, is_cross, outfile): |
|
|
|
def generate_pch_rule_for(self, langname, compiler, is_cross, outfile): |
|
|
|
if langname != 'c' and langname != 'cpp': |
|
|
|
if langname != 'c' and langname != 'cpp': |
|
|
|
return |
|
|
|
return |
|
|
|
if is_cross: |
|
|
|
if is_cross: |
|
|
@ -1595,7 +1596,7 @@ rule FORTRAN_DEP_HACK |
|
|
|
quoted_depargs = [] |
|
|
|
quoted_depargs = [] |
|
|
|
for d in depargs: |
|
|
|
for d in depargs: |
|
|
|
if d != '$out' and d != '$in': |
|
|
|
if d != '$out' and d != '$in': |
|
|
|
d = qstr % d |
|
|
|
d = quote_func(d) |
|
|
|
quoted_depargs.append(d) |
|
|
|
quoted_depargs.append(d) |
|
|
|
if compiler.get_id() == 'msvc': |
|
|
|
if compiler.get_id() == 'msvc': |
|
|
|
output = '' |
|
|
|
output = '' |
|
|
@ -1621,12 +1622,11 @@ rule FORTRAN_DEP_HACK |
|
|
|
outfile.write('\n') |
|
|
|
outfile.write('\n') |
|
|
|
|
|
|
|
|
|
|
|
def generate_compile_rules(self, outfile): |
|
|
|
def generate_compile_rules(self, outfile): |
|
|
|
qstr = quote_char + "%s" + quote_char |
|
|
|
|
|
|
|
for langname, compiler in self.build.compilers.items(): |
|
|
|
for langname, compiler in self.build.compilers.items(): |
|
|
|
if compiler.get_id() == 'clang': |
|
|
|
if compiler.get_id() == 'clang': |
|
|
|
self.generate_llvm_ir_compile_rule(compiler, False, outfile) |
|
|
|
self.generate_llvm_ir_compile_rule(compiler, False, outfile) |
|
|
|
self.generate_compile_rule_for(langname, compiler, qstr, False, outfile) |
|
|
|
self.generate_compile_rule_for(langname, compiler, False, outfile) |
|
|
|
self.generate_pch_rule_for(langname, compiler, qstr, False, outfile) |
|
|
|
self.generate_pch_rule_for(langname, compiler, False, outfile) |
|
|
|
if self.environment.is_cross_build(): |
|
|
|
if self.environment.is_cross_build(): |
|
|
|
# In case we are going a target-only build, make the native compilers |
|
|
|
# In case we are going a target-only build, make the native compilers |
|
|
|
# masquerade as cross compilers. |
|
|
|
# masquerade as cross compilers. |
|
|
@ -1637,8 +1637,8 @@ rule FORTRAN_DEP_HACK |
|
|
|
for langname, compiler in cclist.items(): |
|
|
|
for langname, compiler in cclist.items(): |
|
|
|
if compiler.get_id() == 'clang': |
|
|
|
if compiler.get_id() == 'clang': |
|
|
|
self.generate_llvm_ir_compile_rule(compiler, True, outfile) |
|
|
|
self.generate_llvm_ir_compile_rule(compiler, True, outfile) |
|
|
|
self.generate_compile_rule_for(langname, compiler, qstr, True, outfile) |
|
|
|
self.generate_compile_rule_for(langname, compiler, True, outfile) |
|
|
|
self.generate_pch_rule_for(langname, compiler, qstr, True, outfile) |
|
|
|
self.generate_pch_rule_for(langname, compiler, True, outfile) |
|
|
|
outfile.write('\n') |
|
|
|
outfile.write('\n') |
|
|
|
|
|
|
|
|
|
|
|
def generate_generator_list_rules(self, target, outfile): |
|
|
|
def generate_generator_list_rules(self, target, outfile): |
|
|
|