2016-01-26 02:53:53 +00:00
# Development tool - utility commands plugin
#
# Copyright (C) 2015-2016 Intel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
""" Devtool utility plugins """
import os
import sys
import shutil
import tempfile
import logging
import argparse
import subprocess
2016-02-19 09:38:50 +00:00
import scriptutils
2016-01-26 02:53:53 +00:00
from devtool import exec_build_env_command , setup_tinfoil , check_workspace_recipe , DevtoolError
from devtool import parse_recipe
logger = logging . getLogger ( ' devtool ' )
def edit_recipe ( args , config , basepath , workspace ) :
""" Entry point for the devtool ' edit-recipe ' subcommand """
if args . any_recipe :
tinfoil = setup_tinfoil ( config_only = False , basepath = basepath )
try :
rd = parse_recipe ( config , tinfoil , args . recipename , True )
if not rd :
return 1
2016-12-14 21:13:05 +00:00
recipefile = rd . getVar ( ' FILE ' )
2016-01-26 02:53:53 +00:00
finally :
tinfoil . shutdown ( )
else :
check_workspace_recipe ( workspace , args . recipename )
recipefile = workspace [ args . recipename ] [ ' recipefile ' ]
if not recipefile :
raise DevtoolError ( " Recipe file for %s is not under the workspace " %
args . recipename )
2016-02-19 09:38:50 +00:00
return scriptutils . run_editor ( recipefile )
2016-01-26 02:53:53 +00:00
2016-01-26 02:53:54 +00:00
def configure_help ( args , config , basepath , workspace ) :
""" Entry point for the devtool ' configure-help ' subcommand """
import oe . utils
check_workspace_recipe ( workspace , args . recipename )
tinfoil = setup_tinfoil ( config_only = False , basepath = basepath )
try :
rd = parse_recipe ( config , tinfoil , args . recipename , appends = True , filter_workspace = False )
if not rd :
return 1
2016-12-14 21:13:05 +00:00
b = rd . getVar ( ' B ' )
s = rd . getVar ( ' S ' )
2016-01-26 02:53:54 +00:00
configurescript = os . path . join ( s , ' configure ' )
confdisabled = ' noexec ' in rd . getVarFlags ( ' do_configure ' ) or ' do_configure ' not in ( rd . getVar ( ' __BBTASKS ' , False ) or [ ] )
2016-12-14 21:13:05 +00:00
configureopts = oe . utils . squashspaces ( rd . getVar ( ' CONFIGUREOPTS ' ) or ' ' )
extra_oeconf = oe . utils . squashspaces ( rd . getVar ( ' EXTRA_OECONF ' ) or ' ' )
extra_oecmake = oe . utils . squashspaces ( rd . getVar ( ' EXTRA_OECMAKE ' ) or ' ' )
do_configure = rd . getVar ( ' do_configure ' ) or ' '
2016-01-26 02:53:54 +00:00
do_configure_noexpand = rd . getVar ( ' do_configure ' , False ) or ' '
packageconfig = rd . getVarFlags ( ' PACKAGECONFIG ' ) or [ ]
autotools = bb . data . inherits_class ( ' autotools ' , rd ) and ( ' oe_runconf ' in do_configure or ' autotools_do_configure ' in do_configure )
cmake = bb . data . inherits_class ( ' cmake ' , rd ) and ( ' cmake_do_configure ' in do_configure )
2016-12-14 21:13:05 +00:00
cmake_do_configure = rd . getVar ( ' cmake_do_configure ' )
pn = rd . getVar ( ' PN ' )
2016-01-26 02:53:54 +00:00
finally :
tinfoil . shutdown ( )
if ' doc ' in packageconfig :
del packageconfig [ ' doc ' ]
if autotools and not os . path . exists ( configurescript ) :
logger . info ( ' Running do_configure to generate configure script ' )
try :
stdout , _ = exec_build_env_command ( config . init_path , basepath ,
2016-03-21 05:14:03 +00:00
' bitbake -c configure %s ' % args . recipename ,
2016-01-26 02:53:54 +00:00
stderr = subprocess . STDOUT )
except bb . process . ExecutionError :
pass
if confdisabled or do_configure . strip ( ) in ( ' ' , ' : ' ) :
raise DevtoolError ( " do_configure task has been disabled for this recipe " )
elif args . no_pager and not os . path . exists ( configurescript ) :
raise DevtoolError ( " No configure script found and no other information to display " )
else :
configopttext = ' '
if autotools and configureopts :
configopttext = '''
Arguments currently passed to the configure script :
% s
Some of those are fixed . ''' % (configureopts + ' ' + extra_oeconf)
if extra_oeconf :
configopttext + = ''' The ones that are specified through EXTRA_OECONF (which you can change or add to easily):
% s ''' % e xtra_oeconf
elif cmake :
in_cmake = False
cmake_cmd = ' '
for line in cmake_do_configure . splitlines ( ) :
if in_cmake :
cmake_cmd = cmake_cmd + ' ' + line . strip ( ) . rstrip ( ' \\ ' )
if not line . endswith ( ' \\ ' ) :
break
if line . lstrip ( ) . startswith ( ' cmake ' ) :
cmake_cmd = line . strip ( ) . rstrip ( ' \\ ' )
if line . endswith ( ' \\ ' ) :
in_cmake = True
else :
break
if cmake_cmd :
configopttext = '''
The current cmake command line :
% s
Arguments specified through EXTRA_OECMAKE ( which you can change or add to easily )
% s ''' % (oe.utils.squashspaces(cmake_cmd), extra_oecmake)
else :
configopttext = '''
The current implementation of cmake_do_configure :
cmake_do_configure ( ) {
% s
}
Arguments specified through EXTRA_OECMAKE ( which you can change or add to easily )
% s ''' % (cmake_do_configure.rstrip(), extra_oecmake)
elif do_configure :
configopttext = '''
The current implementation of do_configure :
do_configure ( ) {
% s
} ''' % d o_configure.rstrip()
if ' $ {EXTRA_OECONF} ' in do_configure_noexpand :
configopttext + = '''
Arguments specified through EXTRA_OECONF ( which you can change or add to easily ) :
% s ''' % e xtra_oeconf
if packageconfig :
configopttext + = '''
Some of these options may be controlled through PACKAGECONFIG ; for more details please see the recipe . '''
if args . arg :
helpargs = ' ' . join ( args . arg )
elif cmake :
helpargs = ' -LH '
else :
helpargs = ' --help '
msg = ''' configure information for %s
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
% s ''' % (pn, configopttext)
if cmake :
msg + = '''
The cmake % s output for % s follows . After " -- Cache values " you should see a list of variables you can add to EXTRA_OECMAKE ( prefixed with - D and suffixed with = followed by the desired value , without any spaces ) .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' % (helpargs, pn)
elif os . path . exists ( configurescript ) :
msg + = '''
The . / configure % s output for % s follows .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ''' % (helpargs, pn)
olddir = os . getcwd ( )
tmppath = tempfile . mkdtemp ( )
with tempfile . NamedTemporaryFile ( ' w ' , delete = False ) as tf :
if not args . no_header :
tf . write ( msg + ' \n ' )
tf . close ( )
try :
try :
cmd = ' cat %s ' % tf . name
if cmake :
cmd + = ' ; cmake %s %s 2>&1 ' % ( helpargs , s )
os . chdir ( b )
elif os . path . exists ( configurescript ) :
cmd + = ' ; %s %s ' % ( configurescript , helpargs )
if sys . stdout . isatty ( ) and not args . no_pager :
pager = os . environ . get ( ' PAGER ' , ' less ' )
cmd = ' ( %s ) | %s ' % ( cmd , pager )
subprocess . check_call ( cmd , shell = True )
except subprocess . CalledProcessError as e :
return e . returncode
finally :
os . chdir ( olddir )
shutil . rmtree ( tmppath )
os . remove ( tf . name )
2016-01-26 02:53:53 +00:00
def register_commands ( subparsers , context ) :
""" Register devtool subcommands from this plugin """
parser_edit_recipe = subparsers . add_parser ( ' edit-recipe ' , help = ' Edit a recipe file in your workspace ' ,
devtool: categorise and order subcommands in help output
The listing of subcommands in the --help output for devtool was starting
to get difficult to follow, with commands appearing in no particular
order (due to some being in separate modules and the order of those
modules being parsed). Logically grouping the subcommands as well as
being able to exercise some control over the order of the subcommands
and groups would help, if we do so without losing the dynamic nature of
the list (i.e. that it comes from the plugins). Argparse provides no
built-in way to handle this and really, really makes it a pain to add,
but with some subclassing and hacking it's now possible, and can be
extended by any plugin as desired.
To put a subcommand into a group, all you need to do is specify a group=
parameter in the call to subparsers.add_parser(). you can also specify
an order= parameter to make the subcommand sort higher or lower in the
list (higher order numbers appear first, so use negative numbers to
force items to the end if that's what you want). To add a new group, use
subparsers.add_subparser_group(), supplying the name, description and
optionally an order number for the group itself (again, higher numbers
appear first).
(From OE-Core rev: e1b9d31e6ea3c254ecfe940fe795af44761e0e69)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-19 09:38:53 +00:00
description = ' Runs the default editor (as specified by the EDITOR variable) on the specified recipe. Note that the recipe file itself must be in the workspace (i.e. as a result of " devtool add " or " devtool upgrade " ); you can override this with the -a/--any-recipe option. ' ,
group = ' working ' )
2016-01-26 02:53:53 +00:00
parser_edit_recipe . add_argument ( ' recipename ' , help = ' Recipe to edit ' )
parser_edit_recipe . add_argument ( ' --any-recipe ' , ' -a ' , action = " store_true " , help = ' Edit any recipe, not just where the recipe file itself is in the workspace ' )
parser_edit_recipe . set_defaults ( func = edit_recipe )
2016-01-26 02:53:54 +00:00
# NOTE: Needed to override the usage string here since the default
# gets the order wrong - recipename must come before --arg
parser_configure_help = subparsers . add_parser ( ' configure-help ' , help = ' Get help on configure script options ' ,
usage = ' devtool configure-help [options] recipename [--arg ...] ' ,
devtool: categorise and order subcommands in help output
The listing of subcommands in the --help output for devtool was starting
to get difficult to follow, with commands appearing in no particular
order (due to some being in separate modules and the order of those
modules being parsed). Logically grouping the subcommands as well as
being able to exercise some control over the order of the subcommands
and groups would help, if we do so without losing the dynamic nature of
the list (i.e. that it comes from the plugins). Argparse provides no
built-in way to handle this and really, really makes it a pain to add,
but with some subclassing and hacking it's now possible, and can be
extended by any plugin as desired.
To put a subcommand into a group, all you need to do is specify a group=
parameter in the call to subparsers.add_parser(). you can also specify
an order= parameter to make the subcommand sort higher or lower in the
list (higher order numbers appear first, so use negative numbers to
force items to the end if that's what you want). To add a new group, use
subparsers.add_subparser_group(), supplying the name, description and
optionally an order number for the group itself (again, higher numbers
appear first).
(From OE-Core rev: e1b9d31e6ea3c254ecfe940fe795af44761e0e69)
Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
2016-02-19 09:38:53 +00:00
description = ' Displays the help for the configure script for the specified recipe (i.e. runs ./configure --help) prefaced by a header describing the current options being specified. Output is piped through less (or whatever PAGER is set to, if set) for easy browsing. ' ,
group = ' working ' )
2016-01-26 02:53:54 +00:00
parser_configure_help . add_argument ( ' recipename ' , help = ' Recipe to show configure help for ' )
parser_configure_help . add_argument ( ' -p ' , ' --no-pager ' , help = ' Disable paged output ' , action = " store_true " )
parser_configure_help . add_argument ( ' -n ' , ' --no-header ' , help = ' Disable explanatory header text ' , action = " store_true " )
parser_configure_help . add_argument ( ' --arg ' , help = ' Pass remaining arguments to the configure script instead of --help (useful if the script has additional help options) ' , nargs = argparse . REMAINDER )
parser_configure_help . set_defaults ( func = configure_help )