2012-12-30 01:10:52 +08:00
#!/usr/bin/python3 -tt
# Copyright 2012 Jussi Pakkanen
# 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.
2013-03-09 00:43:30 +08:00
import os , sys , stat , re , pickle
2013-01-14 07:13:55 +08:00
import interpreter , nodes
2013-02-21 06:36:28 +08:00
import environment
2013-02-23 19:18:56 +08:00
from meson_install import InstallData
2013-03-10 08:28:36 +08:00
from interpreter import InvalidArguments
2012-12-30 01:10:52 +08:00
2013-03-09 00:29:37 +08:00
if environment . is_windows ( ) :
quote_char = ' " '
2013-03-09 01:10:52 +08:00
execute_wrapper = ' cmd /c '
2013-03-09 00:29:37 +08:00
else :
quote_char = " ' "
2013-03-09 01:10:52 +08:00
execute_wrapper = ' '
2013-03-09 00:29:37 +08:00
2013-01-02 05:43:25 +08:00
def shell_quote ( cmdlist ) :
return [ " ' " + x + " ' " for x in cmdlist ]
2013-02-07 02:37:46 +08:00
def ninja_quote ( text ) :
return text . replace ( ' ' , ' $ ' )
2013-03-10 08:28:36 +08:00
def do_replacement ( regex , line , variables ) :
match = re . search ( regex , line )
while match :
varname = match . group ( 1 )
if varname in variables :
var = variables [ varname ]
if isinstance ( var , str ) :
pass
elif isinstance ( var , nodes . StringStatement ) :
var = var . get_value ( )
else :
raise RuntimeError ( ' Tried to replace a variable with something other than a string. ' )
else :
var = ' '
line = line . replace ( ' @ ' + varname + ' @ ' , var )
match = re . search ( regex , line )
return line
def do_mesondefine ( line , variables ) :
arr = line . split ( )
if len ( arr ) != 2 :
2013-03-16 04:04:19 +08:00
raise interpreter . InvalidArguments ( ' #mesondefine does not contain exactly two tokens. ' )
2013-03-10 08:28:36 +08:00
varname = arr [ 1 ]
v = variables . get ( varname , False )
if isinstance ( v , bool ) :
value = v
elif isinstance ( v , nodes . BoolStatement ) :
value = v . get_value ( )
else :
2013-03-16 04:04:19 +08:00
raise interpreter . InvalidArguments ( ' #mesondefine argument " %s " is not boolean. ' % varname )
2013-03-10 08:28:36 +08:00
if value :
return ' #define %s \n ' % varname
return ' /* undef %s */ \n ' % varname
2013-01-14 07:13:55 +08:00
def do_conf_file ( src , dst , variables ) :
data = open ( src ) . readlines ( )
regex = re . compile ( ' @(.*?)@ ' )
result = [ ]
for line in data :
2013-03-10 08:28:36 +08:00
if line . startswith ( ' #mesondefine ' ) :
line = do_mesondefine ( line , variables )
else :
line = do_replacement ( regex , line , variables )
2013-01-14 07:13:55 +08:00
result . append ( line )
2013-03-10 07:53:24 +08:00
dst_tmp = dst + ' ~ '
open ( dst_tmp , ' w ' ) . writelines ( result )
# If contents are identical, don't touch the file to prevent
# unnecessary rebuilds.
try :
if open ( dst , ' r ' ) . read ( ) == open ( dst_tmp , ' r ' ) . read ( ) :
return
except FileNotFoundError :
pass
os . replace ( dst_tmp , dst )
2013-01-14 07:13:55 +08:00
2013-02-07 03:34:00 +08:00
2013-02-24 01:42:18 +08:00
class Backend ( ) :
2013-01-14 07:13:55 +08:00
def __init__ ( self , build , interp ) :
2013-01-12 04:59:49 +08:00
self . build = build
self . environment = build . environment
2013-01-14 07:13:55 +08:00
self . interpreter = interp
2013-02-07 01:45:23 +08:00
self . processed_targets = { }
2013-02-07 05:51:12 +08:00
self . build_to_src = os . path . relpath ( self . environment . get_source_dir ( ) ,
self . environment . get_build_dir ( ) )
2013-02-07 01:45:23 +08:00
2013-02-07 03:34:00 +08:00
def get_compiler_for_source ( self , src ) :
for i in self . build . compilers :
if i . can_compile ( src ) :
return i
raise RuntimeError ( ' No specified compiler can handle file ' + src )
2013-02-07 02:37:46 +08:00
def get_target_filename ( self , target ) :
targetdir = self . get_target_dir ( target )
filename = os . path . join ( targetdir , target . get_filename ( ) )
return filename
def get_target_dir ( self , target ) :
2013-02-07 05:51:12 +08:00
dirname = target . get_subdir ( )
os . makedirs ( os . path . join ( self . environment . get_build_dir ( ) , dirname ) , exist_ok = True )
2013-02-07 02:37:46 +08:00
return dirname
def get_target_private_dir ( self , target ) :
dirname = os . path . join ( self . get_target_dir ( target ) , target . get_basename ( ) + ' .dir ' )
2013-02-07 05:51:12 +08:00
os . makedirs ( os . path . join ( self . environment . get_build_dir ( ) , dirname ) , exist_ok = True )
2013-02-07 02:37:46 +08:00
return dirname
2013-02-07 03:15:49 +08:00
def generate_target ( self , target , outfile ) :
name = target . get_basename ( )
if name in self . processed_targets :
return
self . process_target_dependencies ( target , outfile )
print ( ' Generating target ' , name )
2013-02-24 05:00:00 +08:00
self . generate_custom_generator_rules ( target , outfile )
2013-02-07 03:15:49 +08:00
outname = self . get_target_filename ( target )
obj_list = [ ]
if target . has_pch ( ) :
self . generate_pch ( target , outfile )
2013-03-02 05:02:06 +08:00
header_deps = [ ]
2013-02-24 04:27:47 +08:00
for genlist in target . get_generated_sources ( ) :
for src in genlist . get_outfilelist ( ) :
2013-03-02 02:49:46 +08:00
if not self . environment . is_header ( src ) :
obj_list . append ( self . generate_single_compile ( target , outfile , src , True ) )
2013-03-02 05:02:06 +08:00
else :
header_deps . append ( src )
for src in target . get_sources ( ) :
if not self . environment . is_header ( src ) :
obj_list . append ( self . generate_single_compile ( target , outfile , src , False , header_deps ) )
2013-03-02 03:53:32 +08:00
elem = self . generate_link ( target , outfile , outname , obj_list )
self . generate_shlib_aliases ( target , self . get_target_dir ( target ) , outfile , elem )
2013-02-07 03:15:49 +08:00
self . processed_targets [ name ] = True
def process_target_dependencies ( self , target , outfile ) :
for t in target . get_dependencies ( ) :
tname = t . get_basename ( )
if not tname in self . processed_targets :
self . generate_target ( t , outfile )
2013-02-07 03:34:00 +08:00
def get_pch_include_args ( self , compiler , target ) :
args = [ ]
pchpath = self . get_target_private_dir ( target )
includearg = compiler . get_include_arg ( pchpath )
for p in target . get_pch ( ) :
if compiler . can_compile ( p ) :
args . append ( ' -include ' )
args . append ( os . path . split ( p ) [ - 1 ] )
if len ( args ) > 0 :
args = [ includearg ] + args
return args
2013-02-07 03:48:31 +08:00
def generate_basic_compiler_flags ( self , target , compiler ) :
2013-02-07 03:34:00 +08:00
commands = [ ]
commands + = self . build . get_global_flags ( compiler )
commands + = target . get_extra_args ( compiler . get_language ( ) )
2013-03-02 05:13:17 +08:00
if self . environment . coredata . buildtype != ' plain ' :
2013-02-11 03:04:30 +08:00
commands + = compiler . get_debug_flags ( )
2013-03-02 05:13:17 +08:00
commands + = compiler . get_std_warn_flags ( )
if self . environment . coredata . buildtype == ' optimized ' :
2013-02-11 03:04:30 +08:00
commands + = compiler . get_std_opt_flags ( )
2013-03-02 05:13:17 +08:00
if self . environment . coredata . coverage :
2013-02-21 06:36:28 +08:00
commands + = compiler . get_coverage_flags ( )
2013-02-07 03:34:00 +08:00
if isinstance ( target , interpreter . SharedLibrary ) :
commands + = compiler . get_pic_flags ( )
for dep in target . get_external_deps ( ) :
2013-03-10 05:08:22 +08:00
commands + = dep . get_compile_flags ( )
2013-02-07 03:34:00 +08:00
return commands
2013-02-07 04:40:18 +08:00
def build_target_link_arguments ( self , deps ) :
args = [ ]
for d in deps :
if not isinstance ( d , interpreter . StaticLibrary ) and \
not isinstance ( d , interpreter . SharedLibrary ) :
raise RuntimeError ( ' Tried to link with a non-library target " %s " . ' % d . get_basename ( ) )
2013-02-07 05:51:12 +08:00
fname = self . get_target_filename ( d )
2013-02-07 06:01:11 +08:00
fname = ' ./ ' + fname # Hack to make ldd find the library.
2013-02-07 05:51:12 +08:00
args . append ( fname )
2013-02-07 04:40:18 +08:00
return args
2013-02-09 07:02:42 +08:00
def generate_configure_files ( self ) :
for cf in self . build . get_configure_files ( ) :
infile = os . path . join ( self . environment . get_source_dir ( ) ,
cf . get_subdir ( ) ,
cf . get_source_name ( ) )
outdir = os . path . join ( self . environment . get_build_dir ( ) ,
cf . get_subdir ( ) )
os . makedirs ( outdir , exist_ok = True )
outfile = os . path . join ( outdir , cf . get_target_name ( ) )
do_conf_file ( infile , outfile , self . interpreter . get_variables ( ) )
2013-03-02 03:20:25 +08:00
class NinjaBuildElement ( ) :
2013-03-02 04:14:26 +08:00
def __init__ ( self , outfilenames , rule , infilenames ) :
2013-03-02 03:53:32 +08:00
if isinstance ( outfilenames , str ) :
self . outfilenames = [ outfilenames ]
else :
self . outfilenames = outfilenames
2013-03-02 04:14:26 +08:00
self . rule = rule
if isinstance ( infilenames , str ) :
self . infilenames = [ infilenames ]
else :
self . infilenames = infilenames
2013-03-02 03:20:25 +08:00
self . deps = [ ]
self . orderdeps = [ ]
self . elems = [ ]
def add_dep ( self , dep ) :
if isinstance ( dep , list ) :
self . deps + = dep
else :
self . deps . append ( dep )
def add_orderdep ( self , dep ) :
if isinstance ( dep , list ) :
self . orderdeps + = dep
else :
self . orderdeps . append ( dep )
def add_item ( self , name , elems ) :
if isinstance ( elems , str ) :
elems = [ elems ]
self . elems . append ( ( name , elems ) )
def write ( self , outfile ) :
2013-03-02 04:14:26 +08:00
line = ' build %s : %s %s ' % ( ' ' . join ( [ ninja_quote ( i ) for i in self . outfilenames ] ) , \
self . rule ,
' ' . join ( [ ninja_quote ( i ) for i in self . infilenames ] ) )
2013-03-02 03:20:25 +08:00
if len ( self . deps ) > 0 :
line + = ' | ' + ' ' . join ( [ ninja_quote ( x ) for x in self . deps ] )
if len ( self . orderdeps ) > 0 :
line + = ' || ' + ' ' . join ( [ ninja_quote ( x ) for x in self . orderdeps ] )
line + = ' \n '
outfile . write ( line )
for e in self . elems :
( name , elems ) = e
should_quote = True
2013-03-02 06:24:50 +08:00
if name == ' DEPFILE ' or name == ' DESC ' :
2013-03-02 03:20:25 +08:00
should_quote = False
line = ' %s = ' % name
2013-03-09 00:29:37 +08:00
q_templ = quote_char + " %s " + quote_char
2013-03-02 03:53:32 +08:00
noq_templ = " %s "
newelems = [ ]
for i in elems :
if not should_quote or i == ' && ' : # Hackety hack hack
templ = noq_templ
else :
templ = q_templ
newelems . append ( templ % ninja_quote ( i ) )
line + = ' ' . join ( newelems )
2013-03-02 03:20:25 +08:00
line + = ' \n '
outfile . write ( line )
outfile . write ( ' \n ' )
2013-03-02 03:24:45 +08:00
2013-02-24 01:42:18 +08:00
class NinjaBackend ( Backend ) :
2013-02-07 01:45:23 +08:00
def __init__ ( self , build , interp ) :
2013-02-24 01:42:18 +08:00
Backend . __init__ ( self , build , interp )
2013-02-07 02:00:59 +08:00
self . ninja_filename = ' build.ninja '
2013-02-07 01:45:23 +08:00
def generate ( self ) :
2013-02-07 02:00:59 +08:00
outfilename = os . path . join ( self . environment . get_build_dir ( ) , self . ninja_filename )
2013-03-10 07:43:15 +08:00
tempfilename = outfilename + ' ~ '
outfile = open ( tempfilename , ' w ' )
2013-02-09 07:02:42 +08:00
self . generate_configure_files ( )
2013-02-07 02:15:07 +08:00
outfile . write ( ' # This is the build file for project " %s " \n ' % self . build . get_project ( ) )
outfile . write ( ' # It is autogenerated. Do not edit by hand. \n \n ' )
2013-02-07 02:00:59 +08:00
self . generate_rules ( outfile )
2013-02-07 03:15:49 +08:00
outfile . write ( ' # Build rules for targets \n \n ' )
2013-02-07 03:34:00 +08:00
[ self . generate_target ( t , outfile ) for t in self . build . get_targets ( ) . values ( ) ]
2013-02-09 02:02:42 +08:00
outfile . write ( ' # Test rules \n \n ' )
self . generate_tests ( outfile )
2013-02-09 02:22:47 +08:00
outfile . write ( ' # Install rules \n \n ' )
self . generate_install ( outfile )
2013-03-02 05:13:17 +08:00
if self . environment . coredata . coverage :
2013-02-21 06:36:28 +08:00
outfile . write ( ' # Coverage rules \n \n ' )
self . generate_coverage_rules ( outfile )
2013-02-07 03:15:49 +08:00
outfile . write ( ' # Suffix \n \n ' )
2013-02-07 03:09:18 +08:00
self . generate_ending ( outfile )
2013-03-10 07:43:15 +08:00
# Only ovewrite the old build file after the new one has been
# fully created.
outfile . close ( )
os . replace ( tempfilename , outfilename )
2013-02-09 02:22:47 +08:00
2013-02-21 06:36:28 +08:00
def generate_coverage_rules ( self , outfile ) :
( gcovr_exe , lcov_exe , genhtml_exe ) = environment . find_coverage_tools ( )
2013-02-21 06:54:47 +08:00
added_rule = False
2013-02-21 06:36:28 +08:00
if gcovr_exe :
2013-02-21 06:54:47 +08:00
added_rule = True
2013-03-02 05:38:51 +08:00
elem = NinjaBuildElement ( ' coverage-xml ' , ' CUSTOM_COMMAND ' , ' ' )
elem . add_item ( ' COMMAND ' , [ gcovr_exe , ' -x ' , ' -r ' , self . environment . get_build_dir ( ) , \
' -o ' , ' coverage.xml ' ] )
2013-03-02 06:24:50 +08:00
elem . add_item ( ' DESC ' , ' Generating XML coverage report. ' )
2013-03-02 05:38:51 +08:00
elem . write ( outfile )
elem = NinjaBuildElement ( ' coverage-text ' , ' CUSTOM_COMMAND ' , ' ' )
elem . add_item ( ' COMMAND ' , [ gcovr_exe , ' -r ' , self . environment . get_build_dir ( ) , \
' -o ' , ' coverage.txt ' ] )
2013-03-02 06:24:50 +08:00
elem . add_item ( ' DESC ' , ' Generating text coverage report. ' )
2013-03-02 05:38:51 +08:00
elem . write ( outfile )
2013-02-21 06:36:28 +08:00
if lcov_exe and genhtml_exe :
2013-02-21 06:54:47 +08:00
added_rule = True
2013-03-02 05:38:51 +08:00
phony_elem = NinjaBuildElement ( ' coverage-html ' , ' phony ' , ' coveragereport/index.html ' )
phony_elem . write ( outfile )
elem = NinjaBuildElement ( ' coveragereport/index.html ' , ' CUSTOM_COMMAND ' , ' ' )
command = [ lcov_exe , ' --directory ' , self . environment . get_build_dir ( ) , \
' --capture ' , ' --output-file ' , ' coverage.info ' , ' --no-checksum ' , \
' && ' , genhtml_exe , ' --prefix ' , self . environment . get_build_dir ( ) , \
' --output-directory ' , ' coveragereport ' , ' --title ' , ' Code coverage ' , \
' --legend ' , ' --show-details ' , ' coverage.info ' ]
elem . add_item ( ' COMMAND ' , command )
2013-03-02 06:24:50 +08:00
elem . add_item ( ' DESC ' , ' Generating HTML coverage report. ' )
2013-03-02 05:38:51 +08:00
elem . write ( outfile )
2013-02-21 06:54:47 +08:00
if not added_rule :
print ( ' Warning: coverage requested but neither gcovr nor lcov/genhtml found. ' )
2013-02-21 06:36:28 +08:00
2013-02-09 02:22:47 +08:00
def generate_install ( self , outfile ) :
2013-02-23 19:11:47 +08:00
script_root = self . environment . get_script_dir ( )
2013-02-23 19:18:56 +08:00
install_script = os . path . join ( script_root , ' meson_install.py ' )
2013-02-09 04:05:46 +08:00
install_data_file = os . path . join ( self . environment . get_scratch_dir ( ) , ' install.dat ' )
2013-02-23 19:11:47 +08:00
depfixer = os . path . join ( script_root , ' depfixer.py ' )
2013-02-16 00:52:54 +08:00
d = InstallData ( self . environment . get_prefix ( ) , depfixer , ' ./ ' ) # Fixme
2013-03-02 03:24:45 +08:00
elem = NinjaBuildElement ( ' install ' , ' CUSTOM_COMMAND ' , ' ' )
elem . add_dep ( ' all ' )
2013-03-02 06:24:50 +08:00
elem . add_item ( ' DESC ' , ' Installing files. ' )
2013-03-09 00:43:30 +08:00
elem . add_item ( ' COMMAND ' , [ sys . executable , install_script , install_data_file ] )
2013-03-02 03:24:45 +08:00
elem . write ( outfile )
2013-02-09 04:05:46 +08:00
self . generate_target_install ( d )
self . generate_header_install ( d )
2013-02-09 04:17:17 +08:00
self . generate_man_install ( d )
2013-02-09 04:28:06 +08:00
self . generate_data_install ( d )
2013-02-09 04:05:46 +08:00
ofile = open ( install_data_file , ' wb ' )
pickle . dump ( d , ofile )
def generate_target_install ( self , d ) :
2013-02-16 00:52:54 +08:00
libdir = self . environment . get_libdir ( )
bindir = self . environment . get_bindir ( )
2013-02-09 03:07:53 +08:00
2013-03-02 05:13:17 +08:00
should_strip = self . environment . coredata . strip
2013-02-09 04:05:46 +08:00
for t in self . build . get_targets ( ) . values ( ) :
2013-02-09 03:07:53 +08:00
if t . should_install ( ) :
if isinstance ( t , interpreter . Executable ) :
outdir = bindir
else :
outdir = libdir
2013-02-16 00:52:54 +08:00
i = [ self . get_target_filename ( t ) , outdir , t . get_aliaslist ( ) , should_strip ]
2013-02-09 03:07:53 +08:00
d . targets . append ( i )
2013-02-09 04:05:46 +08:00
def generate_header_install ( self , d ) :
2013-02-16 00:52:54 +08:00
incroot = self . environment . get_includedir ( )
2013-02-09 04:05:46 +08:00
headers = self . build . get_headers ( )
for h in headers :
outdir = os . path . join ( incroot , h . get_subdir ( ) )
for f in h . get_sources ( ) :
abspath = os . path . join ( self . environment . get_source_dir ( ) , f ) # FIXME
i = [ abspath , outdir ]
d . headers . append ( i )
2013-02-09 02:22:47 +08:00
2013-02-09 04:17:17 +08:00
def generate_man_install ( self , d ) :
2013-02-16 00:52:54 +08:00
manroot = self . environment . get_mandir ( )
2013-02-09 04:17:17 +08:00
man = self . build . get_man ( )
for m in man :
for f in m . get_sources ( ) :
num = f . split ( ' . ' ) [ - 1 ]
subdir = ' man ' + num
srcabs = os . path . join ( self . environment . get_source_dir ( ) , f )
dstabs = os . path . join ( manroot ,
os . path . join ( subdir , f + ' .gz ' ) )
i = [ srcabs , dstabs ]
d . man . append ( i )
2013-02-09 04:28:06 +08:00
def generate_data_install ( self , d ) :
2013-02-16 00:52:54 +08:00
dataroot = self . environment . get_datadir ( )
2013-02-09 04:28:06 +08:00
data = self . build . get_data ( )
for de in data :
subdir = os . path . join ( dataroot , de . get_subdir ( ) )
for f in de . get_sources ( ) :
srcabs = os . path . join ( self . environment . get_source_dir ( ) , f )
2013-02-16 00:52:54 +08:00
dstabs = os . path . join ( subdir , f )
2013-02-09 04:28:06 +08:00
i = [ srcabs , dstabs ]
d . data . append ( i )
2013-02-09 02:02:42 +08:00
def generate_tests ( self , outfile ) :
2013-03-23 04:48:28 +08:00
valgrind = environment . find_valgrind ( )
2013-02-23 19:11:47 +08:00
script_root = self . environment . get_script_dir ( )
2013-02-23 19:18:56 +08:00
test_script = os . path . join ( script_root , ' meson_test.py ' )
test_data = os . path . join ( self . environment . get_scratch_dir ( ) , ' meson_test_setup.dat ' )
2013-03-23 04:48:28 +08:00
cmd = [ sys . executable , test_script , test_data ]
2013-03-10 05:57:14 +08:00
elem = NinjaBuildElement ( ' test ' , ' CUSTOM_COMMAND ' , ' all ' )
2013-03-23 04:48:28 +08:00
elem . add_item ( ' COMMAND ' , cmd )
2013-03-02 06:24:50 +08:00
elem . add_item ( ' DESC ' , ' Running test suite. ' )
2013-03-02 03:24:45 +08:00
elem . write ( outfile )
2013-03-23 04:48:28 +08:00
if valgrind :
velem = NinjaBuildElement ( ' test-valgrind ' , ' CUSTOM_COMMAND ' , ' all ' )
velem . add_item ( ' COMMAND ' , cmd + [ ' --wrapper= ' + valgrind ] )
2013-03-23 06:12:38 +08:00
velem . add_item ( ' DESC ' , ' Running test suite under Valgrind. ' )
2013-03-23 04:48:28 +08:00
velem . write ( outfile )
2013-02-09 02:02:42 +08:00
datafile = open ( test_data , ' w ' )
for t in self . build . get_tests ( ) :
datafile . write ( self . get_target_filename ( t . get_exe ( ) ) + ' \n ' )
datafile . close ( )
2013-02-07 02:00:59 +08:00
def generate_rules ( self , outfile ) :
2013-02-07 02:37:46 +08:00
outfile . write ( ' # Rules for compiling. \n \n ' )
2013-02-07 02:15:07 +08:00
self . generate_compile_rules ( outfile )
outfile . write ( ' # Rules for linking. \n \n ' )
2013-02-07 02:37:46 +08:00
self . generate_static_link_rules ( outfile )
self . generate_dynamic_link_rules ( outfile )
2013-02-09 02:02:42 +08:00
outfile . write ( ' # Other rules \n \n ' )
outfile . write ( ' rule CUSTOM_COMMAND \n ' )
outfile . write ( ' command = $COMMAND \n ' )
2013-03-02 06:24:50 +08:00
outfile . write ( ' description = $DESC \n ' )
2013-02-09 02:02:42 +08:00
outfile . write ( ' restat = 1 \n \n ' )
2013-02-17 03:14:04 +08:00
outfile . write ( ' rule REGENERATE_BUILD \n ' )
2013-03-10 07:11:00 +08:00
c = ( sys . executable ,
ninja_quote ( self . environment . get_build_command ( ) ) ,
2013-02-17 03:14:04 +08:00
ninja_quote ( self . environment . get_source_dir ( ) ) ,
ninja_quote ( self . environment . get_build_dir ( ) ) )
2013-03-10 07:37:20 +08:00
outfile . write ( " command = ' %s ' ' %s ' ' %s ' ' %s ' --backend ninja \n " % c )
2013-02-17 03:49:00 +08:00
outfile . write ( ' description = Regenerating build files \n ' )
outfile . write ( ' generator = 1 \n \n ' )
2013-02-07 02:37:46 +08:00
def generate_static_link_rules ( self , outfile ) :
2013-02-07 02:15:07 +08:00
static_linker = self . build . static_linker
rule = ' rule STATIC_LINKER \n '
2013-02-09 02:22:47 +08:00
command = ' command = %s $LINK_FLAGS $out $in \n ' % \
' ' . join ( static_linker . get_exelist ( ) )
2013-02-07 02:15:07 +08:00
description = ' description = Static linking library $out \n \n '
outfile . write ( rule )
outfile . write ( command )
outfile . write ( description )
2013-02-07 02:37:46 +08:00
def generate_dynamic_link_rules ( self , outfile ) :
for compiler in self . build . compilers :
langname = compiler . get_language ( )
rule = ' rule %s _LINKER \n ' % langname
2013-03-09 01:10:52 +08:00
command = ' command = %s %s $FLAGS %s $out $in $LINK_FLAGS $aliasing \n ' % \
( execute_wrapper ,
' ' . join ( compiler . get_exelist ( ) ) , \
2013-02-07 04:40:18 +08:00
' ' . join ( compiler . get_output_flags ( ) ) )
2013-02-07 02:37:46 +08:00
description = ' description = Linking target $out '
outfile . write ( rule )
outfile . write ( command )
outfile . write ( description )
outfile . write ( ' \n ' )
2013-02-07 03:09:18 +08:00
outfile . write ( ' \n ' )
2013-02-07 02:15:07 +08:00
def generate_compile_rules ( self , outfile ) :
2013-03-09 00:29:37 +08:00
qstr = quote_char + " %s " + quote_char
2013-02-07 02:00:59 +08:00
for compiler in self . build . compilers :
langname = compiler . get_language ( )
rule = ' rule %s _COMPILER \n ' % langname
2013-02-11 01:53:31 +08:00
depflags = compiler . get_dependency_gen_flags ( ' $out ' , ' $DEPFILE ' )
command = " command = %s $FLAGS %s %s $out %s $in \n " % \
2013-02-07 02:00:59 +08:00
( ' ' . join ( compiler . get_exelist ( ) ) , \
2013-03-09 00:29:37 +08:00
' ' . join ( [ qstr % d for d in depflags ] ) , \
2013-02-07 02:00:59 +08:00
' ' . join ( compiler . get_output_flags ( ) ) , \
' ' . join ( compiler . get_compile_only_flags ( ) ) )
2013-02-11 01:53:31 +08:00
description = ' description = Compiling %s object $out \n ' % langname
dep = ' depfile = $DEPFILE \n '
2013-02-07 02:00:59 +08:00
outfile . write ( rule )
outfile . write ( command )
2013-02-11 01:53:31 +08:00
outfile . write ( dep )
2013-02-07 02:00:59 +08:00
outfile . write ( description )
outfile . write ( ' \n ' )
outfile . write ( ' \n ' )
2013-02-07 01:45:23 +08:00
2013-02-24 05:00:00 +08:00
def generate_custom_generator_rules ( self , target , outfile ) :
for genlist in target . get_generated_sources ( ) :
generator = genlist . get_generator ( )
exe = generator . get_exe ( )
infilelist = genlist . get_infilelist ( )
outfilelist = genlist . get_outfilelist ( )
if len ( infilelist ) != len ( outfilelist ) :
raise RuntimeError ( ' Internal data structures broken. ' )
2013-03-10 03:12:03 +08:00
if isinstance ( exe , interpreter . BuildTarget ) :
exe_file = os . path . join ( self . environment . get_build_dir ( ) , self . get_target_filename ( exe ) )
else :
exe_file = exe . get_command ( )
2013-02-24 05:00:00 +08:00
base_args = generator . get_arglist ( )
for i in range ( len ( infilelist ) ) :
infilename = os . path . join ( self . build_to_src , infilelist [ i ] )
2013-03-02 05:02:06 +08:00
outfilename = os . path . join ( self . get_target_private_dir ( target ) , outfilelist [ i ] )
2013-02-24 07:31:01 +08:00
args = [ x . replace ( " @INPUT@ " , infilename ) . replace ( ' @OUTPUT@ ' , outfilename ) \
2013-02-24 05:00:00 +08:00
for x in base_args ]
cmdlist = [ exe_file ] + args
2013-03-02 03:53:32 +08:00
elem = NinjaBuildElement ( outfilename , ' CUSTOM_COMMAND ' , infilename )
2013-03-02 06:24:50 +08:00
elem . add_item ( ' DESC ' , ' Generating $out ' )
2013-03-10 03:12:03 +08:00
if isinstance ( exe , interpreter . BuildTarget ) :
elem . add_dep ( self . get_target_filename ( exe ) )
2013-03-02 03:53:32 +08:00
elem . add_item ( ' COMMAND ' , cmdlist )
elem . write ( outfile )
2013-02-24 05:00:00 +08:00
2013-03-02 05:02:06 +08:00
def generate_single_compile ( self , target , outfile , src , is_generated = False , header_deps = [ ] ) :
2013-02-07 03:34:00 +08:00
compiler = self . get_compiler_for_source ( src )
2013-02-07 03:48:31 +08:00
commands = self . generate_basic_compiler_flags ( target , compiler )
2013-03-02 05:02:06 +08:00
commands . append ( compiler . get_include_arg ( self . get_target_private_dir ( target ) ) )
2013-02-24 04:27:47 +08:00
if is_generated :
2013-03-24 21:50:40 +08:00
rel_src = os . path . join ( self . get_target_private_dir ( target ) , src )
2013-02-24 04:27:47 +08:00
else :
2013-03-24 21:50:40 +08:00
rel_src = os . path . join ( self . build_to_src , target . get_source_subdir ( ) , src )
if os . path . isabs ( src ) :
src_filename = os . path . basename ( src )
else :
src_filename = src
rel_obj = os . path . join ( self . get_target_private_dir ( target ) , src_filename )
rel_obj + = ' . ' + self . environment . get_object_suffix ( )
dep_file = rel_obj + ' . ' + compiler . get_depfile_suffix ( )
2013-02-09 05:31:07 +08:00
pchlist = target . get_pch ( )
if len ( pchlist ) == 0 :
2013-03-02 03:20:25 +08:00
pch_dep = [ ]
2013-02-09 05:31:07 +08:00
else :
arr = [ ]
for pch in pchlist :
i = os . path . join ( self . get_target_private_dir ( target ) ,
os . path . split ( pch ) [ - 1 ] + ' . ' + compiler . get_pch_suffix ( ) )
arr . append ( i )
2013-03-02 03:20:25 +08:00
pch_dep = arr
2013-02-07 03:34:00 +08:00
for i in target . get_include_dirs ( ) :
basedir = i . get_curdir ( )
for d in i . get_incdirs ( ) :
expdir = os . path . join ( basedir , d )
fulldir = os . path . join ( self . environment . get_source_dir ( ) , expdir )
barg = compiler . get_include_arg ( expdir )
sarg = compiler . get_include_arg ( fulldir )
commands . append ( barg )
commands . append ( sarg )
commands + = self . get_pch_include_args ( compiler , target )
compiler_name = ' %s _COMPILER ' % compiler . get_language ( )
2013-03-02 03:20:25 +08:00
2013-03-24 21:50:40 +08:00
element = NinjaBuildElement ( rel_obj , compiler_name , rel_src )
2013-03-02 05:02:06 +08:00
if len ( header_deps ) > 0 :
element . add_dep ( [ os . path . join ( self . get_target_private_dir ( target ) , d ) for d in header_deps ] )
2013-03-02 03:20:25 +08:00
element . add_orderdep ( pch_dep )
element . add_item ( ' DEPFILE ' , dep_file )
element . add_item ( ' FLAGS ' , commands )
element . write ( outfile )
2013-03-24 21:50:40 +08:00
return rel_obj
2013-02-07 04:40:18 +08:00
2013-02-09 05:31:07 +08:00
def generate_pch ( self , target , outfile ) :
for pch in target . get_pch ( ) :
if ' / ' not in pch :
raise interpreter . InvalidArguments ( ' Precompiled header of " %s " must not be in the same direcotory as source, please put it in a subdirectory. ' % target . get_basename ( ) )
compiler = self . get_compiler_for_source ( pch )
commands = [ ]
commands + = self . generate_basic_compiler_flags ( target , compiler )
src = os . path . join ( self . build_to_src , target . get_source_subdir ( ) , pch )
dst = os . path . join ( self . get_target_private_dir ( target ) ,
os . path . split ( pch ) [ - 1 ] + ' . ' + compiler . get_pch_suffix ( ) )
2013-02-11 03:26:27 +08:00
dep = dst + ' . ' + compiler . get_depfile_suffix ( )
2013-03-02 03:53:32 +08:00
elem = NinjaBuildElement ( dst , compiler . get_language ( ) + ' _COMPILER ' , src )
elem . add_item ( ' FLAGS ' , commands )
elem . add_item ( ' DEPFILE ' , dep )
elem . write ( outfile )
2013-02-09 05:31:07 +08:00
2013-02-07 03:34:00 +08:00
def generate_link ( self , target , outfile , outname , obj_list ) :
2013-02-07 04:40:18 +08:00
if isinstance ( target , interpreter . StaticLibrary ) :
linker = self . build . static_linker
linker_base = ' STATIC '
else :
linker = self . build . compilers [ 0 ]
linker_base = linker . get_language ( ) # Fixme.
linker_rule = linker_base + ' _LINKER '
commands = [ ]
if isinstance ( target , interpreter . Executable ) :
commands + = linker . get_std_exe_link_flags ( )
elif isinstance ( target , interpreter . SharedLibrary ) :
commands + = linker . get_std_shared_lib_link_flags ( )
commands + = linker . get_pic_flags ( )
elif isinstance ( target , interpreter . StaticLibrary ) :
commands + = linker . get_std_link_flags ( )
else :
raise RuntimeError ( ' Unknown build target type. ' )
for dep in target . get_external_deps ( ) :
2013-03-10 05:08:22 +08:00
commands + = dep . get_link_flags ( )
2013-02-09 04:51:19 +08:00
dependencies = target . get_dependencies ( )
commands + = self . build_target_link_arguments ( dependencies )
2013-03-02 05:13:17 +08:00
if self . environment . coredata . coverage :
2013-02-21 06:36:28 +08:00
commands + = linker . get_coverage_link_flags ( )
2013-03-02 03:53:32 +08:00
dep_targets = [ self . get_target_filename ( t ) for t in dependencies ]
elem = NinjaBuildElement ( outname , linker_rule , obj_list )
elem . add_dep ( dep_targets )
elem . add_item ( ' LINK_FLAGS ' , commands )
return elem
def generate_shlib_aliases ( self , target , outdir , outfile , elem ) :
2013-02-09 05:49:25 +08:00
basename = target . get_filename ( )
aliases = target . get_aliaslist ( )
2013-03-02 03:53:32 +08:00
aliascmd = [ ]
2013-02-09 05:49:25 +08:00
for alias in aliases :
aliasfile = os . path . join ( outdir , alias )
2013-03-02 03:53:32 +08:00
cmd = [ " && " , ' ln ' , ' -s ' , ' -f ' , basename , aliasfile ]
2013-02-09 05:49:25 +08:00
aliascmd + = cmd
2013-03-02 03:53:32 +08:00
elem . add_item ( ' aliasing ' , aliascmd )
elem . write ( outfile )
2013-02-07 03:09:18 +08:00
def generate_ending ( self , outfile ) :
2013-02-09 03:29:02 +08:00
targetlist = [ self . get_target_filename ( t ) for t in self . build . get_targets ( ) . values ( ) ]
2013-03-02 04:03:31 +08:00
elem = NinjaBuildElement ( ' all ' , ' phony ' , targetlist )
elem . write ( outfile )
2013-02-07 03:09:18 +08:00
default = ' default all \n \n '
outfile . write ( default )
2013-02-17 03:49:00 +08:00
2013-03-10 05:43:49 +08:00
elem = NinjaBuildElement ( ' clean ' , ' CUSTOM_COMMAND ' , ' ' )
elem . add_item ( ' COMMAND ' , [ ' ninja ' , ' -t ' , ' clean ' ] )
elem . add_item ( ' description ' , ' Cleaning ' )
elem . write ( outfile )
2013-03-02 04:03:31 +08:00
deps = [ os . path . join ( self . build_to_src , df ) \
2013-02-17 03:14:04 +08:00
for df in self . interpreter . get_build_def_files ( ) ]
2013-03-02 04:03:31 +08:00
elem = NinjaBuildElement ( ' build.ninja ' , ' REGENERATE_BUILD ' , deps )
elem . write ( outfile )
2013-02-17 03:49:00 +08:00
2013-03-02 04:14:26 +08:00
elem = NinjaBuildElement ( deps , ' phony ' , ' ' )
elem . write ( outfile )
2013-02-07 03:09:18 +08:00
2013-02-24 01:42:18 +08:00
class ShellBackend ( Backend ) :
2013-02-07 01:45:23 +08:00
def __init__ ( self , build , interp ) :
2013-02-24 01:42:18 +08:00
Backend . __init__ ( self , build , interp )
2012-12-30 01:10:52 +08:00
self . build_filename = ' compile.sh '
2013-01-07 01:13:30 +08:00
self . test_filename = ' run_tests.sh '
2013-01-12 08:25:06 +08:00
self . install_filename = ' install.sh '
2013-01-06 08:59:54 +08:00
2012-12-30 01:10:52 +08:00
def generate ( self ) :
2013-01-07 01:13:30 +08:00
self . generate_compile_script ( )
self . generate_test_script ( )
2013-01-12 08:25:06 +08:00
self . generate_install_script ( )
2013-01-07 01:13:30 +08:00
2013-01-12 08:25:06 +08:00
def create_shfile ( self , outfilename , message ) :
2012-12-30 01:10:52 +08:00
outfile = open ( outfilename , ' w ' )
2012-12-30 04:13:14 +08:00
outfile . write ( ' #!/bin/sh \n \n ' )
2013-01-12 08:25:06 +08:00
outfile . write ( message )
2013-01-02 05:49:37 +08:00
cdcmd = [ ' cd ' , self . environment . get_build_dir ( ) ]
outfile . write ( ' ' . join ( shell_quote ( cdcmd ) ) + ' \n ' )
2012-12-30 01:10:52 +08:00
os . chmod ( outfilename , stat . S_IREAD | stat . S_IWRITE | stat . S_IEXEC | \
stat . S_IRGRP | stat . S_IXGRP | stat . S_IROTH | stat . S_IXOTH )
2013-01-12 08:25:06 +08:00
return outfile
def generate_compile_script ( self ) :
outfilename = os . path . join ( self . environment . get_build_dir ( ) , self . build_filename )
message = """ echo This is an autogenerated shell script build file for project \\ " %s \\ "
echo This is experimental and most likely will not work !
""" % s elf.build.get_project()
outfile = self . create_shfile ( outfilename , message )
self . generate_commands ( outfile )
outfile . close ( )
2012-12-30 01:10:52 +08:00
2013-01-07 01:13:30 +08:00
def generate_test_script ( self ) :
outfilename = os . path . join ( self . environment . get_build_dir ( ) , self . test_filename )
2013-01-12 08:25:06 +08:00
message = """ echo This is an autogenerated test script for project \\ " %s \\ "
echo This is experimental and most likely will not work !
echo Run compile . sh before this or bad things will happen .
""" % s elf.build.get_project()
outfile = self . create_shfile ( outfilename , message )
2013-01-07 01:13:30 +08:00
self . generate_tests ( outfile )
outfile . close ( )
2013-01-12 08:25:06 +08:00
def generate_install_script ( self ) :
outfilename = os . path . join ( self . environment . get_build_dir ( ) , self . install_filename )
message = """ echo This is an autogenerated install script for project \\ " %s \\ "
echo This is experimental and most likely will not work !
echo Run compile . sh before this or bad things will happen .
""" % s elf.build.get_project()
outfile = self . create_shfile ( outfilename , message )
2013-01-14 07:13:55 +08:00
self . generate_configure_files ( )
2013-01-12 19:53:19 +08:00
self . generate_target_install ( outfile )
self . generate_header_install ( outfile )
2013-01-12 20:31:43 +08:00
self . generate_man_install ( outfile )
2013-01-14 01:25:54 +08:00
self . generate_data_install ( outfile )
2013-01-12 08:25:06 +08:00
outfile . close ( )
2013-01-12 19:53:19 +08:00
2013-02-07 04:40:18 +08:00
def make_subdir ( self , outfile , sdir ) :
cmdlist = [ ' mkdir ' , ' -p ' , sdir ]
2013-01-12 20:31:43 +08:00
outfile . write ( ' ' . join ( shell_quote ( cmdlist ) ) + ' || exit \n ' )
2013-01-12 19:53:19 +08:00
def copy_file ( self , outfile , filename , outdir ) :
cpcommand = [ ' cp ' , filename , outdir ]
2013-01-12 20:31:43 +08:00
cpcommand = ' ' . join ( shell_quote ( cpcommand ) ) + ' || exit \n '
2013-01-12 19:53:19 +08:00
outfile . write ( cpcommand )
2013-02-07 03:15:49 +08:00
2013-01-14 01:25:54 +08:00
def generate_data_install ( self , outfile ) :
prefix = self . environment . get_prefix ( )
dataroot = os . path . join ( prefix , self . environment . get_datadir ( ) )
data = self . build . get_data ( )
if len ( data ) != 0 :
outfile . write ( ' \n echo Installing data files. \n ' )
else :
outfile . write ( ' \n echo This project has no data files to install. \n ' )
for d in data :
2013-01-14 02:50:16 +08:00
subdir = os . path . join ( dataroot , d . get_subdir ( ) )
2013-01-14 01:25:54 +08:00
absdir = os . path . join ( self . environment . get_prefix ( ) , subdir )
for f in d . get_sources ( ) :
self . make_subdir ( outfile , absdir )
srcabs = os . path . join ( self . environment . get_source_dir ( ) , f )
dstabs = os . path . join ( absdir , f )
self . copy_file ( outfile , srcabs , dstabs )
2013-01-12 20:31:43 +08:00
def generate_man_install ( self , outfile ) :
prefix = self . environment . get_prefix ( )
manroot = os . path . join ( prefix , self . environment . get_mandir ( ) )
man = self . build . get_man ( )
if len ( man ) != 0 :
outfile . write ( ' \n echo Installing man pages. \n ' )
else :
outfile . write ( ' \n echo This project has no man pages to install. \n ' )
for m in man :
for f in m . get_sources ( ) :
num = f . split ( ' . ' ) [ - 1 ]
subdir = ' man ' + num
absdir = os . path . join ( manroot , subdir )
self . make_subdir ( outfile , absdir )
srcabs = os . path . join ( self . environment . get_source_dir ( ) , f )
dstabs = os . path . join ( manroot ,
os . path . join ( subdir , f + ' .gz ' ) )
cmd = " gzip < ' %s ' > ' %s ' || exit \n " % ( srcabs , dstabs )
outfile . write ( cmd )
2013-01-12 19:53:19 +08:00
def generate_header_install ( self , outfile ) :
prefix = self . environment . get_prefix ( )
incroot = os . path . join ( prefix , self . environment . get_includedir ( ) )
headers = self . build . get_headers ( )
if len ( headers ) != 0 :
outfile . write ( ' \n echo Installing headers. \n ' )
else :
2013-01-12 20:31:43 +08:00
outfile . write ( ' \n echo This project has no headers to install. \n ' )
2013-01-12 19:53:19 +08:00
for h in headers :
outdir = os . path . join ( incroot , h . get_subdir ( ) )
self . make_subdir ( outfile , outdir )
for f in h . get_sources ( ) :
2013-01-12 20:31:43 +08:00
abspath = os . path . join ( self . environment . get_source_dir ( ) , f ) # FIXME
2013-01-12 19:53:19 +08:00
self . copy_file ( outfile , abspath , outdir )
2013-01-12 08:25:06 +08:00
2013-01-12 19:53:19 +08:00
def generate_target_install ( self , outfile ) :
2013-01-12 08:25:06 +08:00
prefix = self . environment . get_prefix ( )
libdir = os . path . join ( prefix , self . environment . get_libdir ( ) )
bindir = os . path . join ( prefix , self . environment . get_bindir ( ) )
2013-01-12 19:53:19 +08:00
self . make_subdir ( outfile , libdir )
self . make_subdir ( outfile , bindir )
2013-01-14 01:25:54 +08:00
if len ( self . build . get_targets ( ) ) != 0 :
outfile . write ( ' \n echo Installing targets. \n ' )
else :
outfile . write ( ' \n echo This project has no targets to install. \n ' )
2013-01-12 08:25:06 +08:00
for tmp in self . build . get_targets ( ) . items ( ) :
( name , t ) = tmp
if t . should_install ( ) :
if isinstance ( t , interpreter . Executable ) :
outdir = bindir
else :
outdir = libdir
outfile . write ( ' echo Installing " %s " . \n ' % name )
2013-01-12 19:53:19 +08:00
self . copy_file ( outfile , self . get_target_filename ( t ) , outdir )
2013-01-28 05:51:06 +08:00
self . generate_shlib_aliases ( t , outdir , outfile )
2013-02-03 23:51:05 +08:00
self . fix_deps ( outfile , t , outdir )
def fix_deps ( self , outfile , target , outdir ) :
if isinstance ( target , interpreter . StaticLibrary ) :
return
depfixer = self . environment . get_depfixer ( )
fname = os . path . join ( outdir , target . get_filename ( ) )
2013-02-07 06:01:11 +08:00
cmds = [ depfixer , fname , ' ./ ' ]
2013-02-03 23:51:05 +08:00
outfile . write ( ' ' . join ( shell_quote ( cmds ) ) + ' || exit \n ' )
2013-01-07 01:13:30 +08:00
def generate_tests ( self , outfile ) :
2013-01-12 04:59:49 +08:00
for t in self . build . get_tests ( ) :
2013-01-07 01:13:30 +08:00
cmds = [ ]
cmds . append ( self . get_target_filename ( t . get_exe ( ) ) )
outfile . write ( ' echo Running test \\ " %s \\ " . \n ' % t . get_name ( ) )
outfile . write ( ' ' . join ( shell_quote ( cmds ) ) + ' || exit \n ' )
2013-01-14 02:50:16 +08:00
def generate_single_compile ( self , target , outfile , src ) :
compiler = self . get_compiler_for_source ( src )
2013-02-07 03:48:31 +08:00
commands = [ ]
commands + = compiler . get_exelist ( )
commands + = self . generate_basic_compiler_flags ( target , compiler )
commands + = compiler . get_compile_only_flags ( )
2013-01-14 02:50:16 +08:00
abs_src = os . path . join ( self . environment . get_source_dir ( ) , target . get_source_subdir ( ) , src )
2013-01-28 07:07:13 +08:00
abs_obj = os . path . join ( self . get_target_private_dir ( target ) , src )
2013-01-14 02:50:16 +08:00
abs_obj + = ' . ' + self . environment . get_object_suffix ( )
2013-01-26 06:28:13 +08:00
for i in target . get_include_dirs ( ) :
basedir = i . get_curdir ( )
for d in i . get_incdirs ( ) :
2013-01-28 08:13:06 +08:00
expdir = os . path . join ( basedir , d )
fulldir = os . path . join ( self . environment . get_source_dir ( ) , expdir )
barg = compiler . get_include_arg ( expdir )
sarg = compiler . get_include_arg ( fulldir )
commands . append ( barg )
commands . append ( sarg )
2013-01-14 02:50:16 +08:00
commands + = self . get_pch_include_args ( compiler , target )
2012-12-30 01:51:32 +08:00
commands . append ( abs_src )
commands + = compiler . get_output_flags ( )
commands . append ( abs_obj )
2013-01-02 05:43:25 +08:00
quoted = shell_quote ( commands )
2012-12-30 04:13:14 +08:00
outfile . write ( ' \n echo Compiling \\ " %s \\ " \n ' % src )
2012-12-30 07:08:50 +08:00
outfile . write ( ' ' . join ( quoted ) + ' || exit \n ' )
2012-12-30 01:51:32 +08:00
return abs_obj
2013-01-07 00:40:32 +08:00
2012-12-30 06:55:35 +08:00
def generate_link ( self , target , outfile , outname , obj_list ) :
2013-01-06 00:13:38 +08:00
if isinstance ( target , interpreter . StaticLibrary ) :
2013-01-12 04:59:49 +08:00
linker = self . build . static_linker
2013-01-06 00:13:38 +08:00
else :
2013-01-12 04:59:49 +08:00
linker = self . build . compilers [ 0 ] # Fixme.
2012-12-30 04:04:24 +08:00
commands = [ ]
commands + = linker . get_exelist ( )
2013-02-10 20:08:53 +08:00
if isinstance ( target , interpreter . StaticLibrary ) :
commands + = linker . get_std_link_flags ( )
2013-02-10 19:56:29 +08:00
commands + = linker . get_output_flags ( )
commands . append ( outname )
commands + = obj_list
2013-01-06 03:08:08 +08:00
if isinstance ( target , interpreter . Executable ) :
commands + = linker . get_std_exe_link_flags ( )
elif isinstance ( target , interpreter . SharedLibrary ) :
commands + = linker . get_std_shared_lib_link_flags ( )
2013-01-06 03:12:14 +08:00
commands + = linker . get_pic_flags ( )
2013-01-06 03:08:08 +08:00
elif isinstance ( target , interpreter . StaticLibrary ) :
2013-02-10 20:08:53 +08:00
pass
2013-01-06 03:08:08 +08:00
else :
raise RuntimeError ( ' Unknown build target type. ' )
2012-12-30 06:55:35 +08:00
for dep in target . get_external_deps ( ) :
commands + = dep . get_link_flags ( )
2013-01-06 08:59:54 +08:00
commands + = self . build_target_link_arguments ( target . get_dependencies ( ) )
2013-01-02 05:43:25 +08:00
quoted = shell_quote ( commands )
2013-01-02 06:56:46 +08:00
outfile . write ( ' \n echo Linking \\ " %s \\ " . \n ' % target . get_basename ( ) )
2012-12-30 07:08:50 +08:00
outfile . write ( ' ' . join ( quoted ) + ' || exit \n ' )
2012-12-30 01:51:32 +08:00
def generate_commands ( self , outfile ) :
2013-01-12 04:59:49 +08:00
for i in self . build . get_targets ( ) . items ( ) :
2013-01-02 06:00:24 +08:00
target = i [ 1 ]
2013-01-06 08:59:54 +08:00
self . generate_target ( target , outfile )
2013-01-14 02:50:16 +08:00
def generate_pch ( self , target , outfile ) :
print ( ' Generating pch for " %s " ' % target . get_basename ( ) )
for pch in target . get_pch ( ) :
if ' / ' not in pch :
raise interpreter . InvalidArguments ( ' Precompiled header of " %s " must not be in the same direcotory as source, please put it in a subdirectory. ' % target . get_basename ( ) )
compiler = self . get_compiler_for_source ( pch )
2013-02-07 03:48:31 +08:00
commands = [ ]
commands + = compiler . get_exelist ( )
commands + = self . generate_basic_compiler_flags ( target , compiler )
2013-01-14 02:50:16 +08:00
srcabs = os . path . join ( self . environment . get_source_dir ( ) , target . get_source_subdir ( ) , pch )
dstabs = os . path . join ( self . environment . get_build_dir ( ) ,
2013-01-28 07:07:13 +08:00
self . get_target_private_dir ( target ) ,
2013-01-14 02:50:16 +08:00
os . path . split ( pch ) [ - 1 ] + ' . ' + compiler . get_pch_suffix ( ) )
commands . append ( srcabs )
commands + = compiler . get_output_flags ( )
commands . append ( dstabs )
quoted = shell_quote ( commands )
outfile . write ( ' \n echo Generating pch \\ " %s \\ " . \n ' % pch )
outfile . write ( ' ' . join ( quoted ) + ' || exit \n ' )
2013-02-07 03:34:00 +08:00
2013-01-28 05:51:06 +08:00
def generate_shlib_aliases ( self , target , outdir , outfile ) :
basename = target . get_filename ( )
aliases = target . get_aliaslist ( )
for alias in aliases :
aliasfile = os . path . join ( outdir , alias )
cmd = [ ' ln ' , ' -s ' , ' -f ' , basename , aliasfile ]
outfile . write ( ' ' . join ( shell_quote ( cmd ) ) + ' || exit \n ' )