Patchwork [2/7] support/scripts: add a script to add a new package

login
register
mail settings
Submitter Yann E. MORIN
Date Sept. 9, 2012, 11:40 p.m.
Message ID <1347234052-10527-3-git-send-email-yann.morin.1998@free.fr>
Download mbox | patch
Permalink /patch/182754/
State Rejected
Headers show

Comments

Yann E. MORIN - Sept. 9, 2012, 11:40 p.m.
This script asks a few questions to the user, and creates the skeleton
files (Config.in and package.mk).

Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
---
 docs/manual/adding-packages-script.txt |   41 +++++++++
 docs/manual/adding-packages.txt        |    2 +
 support/scripts/pkg-new                |  151 ++++++++++++++++++++++++++++++++
 3 files changed, 194 insertions(+), 0 deletions(-)
 create mode 100644 docs/manual/adding-packages-script.txt
 create mode 100755 support/scripts/pkg-new
Arnout Vandecappelle - Nov. 1, 2012, 2 a.m.
On 09/10/12 01:40, Yann E. MORIN wrote:
> This script asks a few questions to the user, and creates the skeleton
> files (Config.in and package.mk).
>
> Signed-off-by: "Yann E. MORIN"<yann.morin.1998@free.fr>
> ---
>   docs/manual/adding-packages-script.txt |   41 +++++++++
>   docs/manual/adding-packages.txt        |    2 +
>   support/scripts/pkg-new                |  151 ++++++++++++++++++++++++++++++++
>   3 files changed, 194 insertions(+), 0 deletions(-)
>   create mode 100644 docs/manual/adding-packages-script.txt
>   create mode 100755 support/scripts/pkg-new
>
> diff --git a/docs/manual/adding-packages-script.txt b/docs/manual/adding-packages-script.txt
> new file mode 100644
> index 0000000..b19e6ee
> --- /dev/null
> +++ b/docs/manual/adding-packages-script.txt
> @@ -0,0 +1,41 @@
> +Scripted new package
> +--------------------
> +
> +To help you add your new package, Buildroot offers a script that partially
> +automates the creation of a new package: +support/scripts/pkg-new+.
> +
> +When run, this script asks you a few questions about your package, and
> +creates skeleton files for you, so you only have to fill-in the the values
> +for the different variables.
> +
> +----
> +$ ./support/script/pkg-new
> +Name of the package: libfoo
> +
> +1) none
> +2) multimedia
> +3) java
> +4) x11r7
> +5) games
> +Category of your package: 1

  I would skip this question and always create it in packages/libfoo.  The
subdirectories are rare, we want to get rid of them, and anyway you can
easily move the generated directory to a different place after the fact.

> +
> +1) autotools
> +2) cmake
> +3) generic
> +Build-system your package is using: 1
> +
> +Your package skeleton files have been created; you can now edit these files
> +to complete the creation of the package:
> +  package/libfoo/Config.in
> +  package/libfoo/libfoo.mk
> +
> +Do not forget to also edit 'package/Config.in' to include
> +package/libfoo/Config.in in the correct location.
> +----
> +
> +Then, you just have to edit the two generated files with appropriate values.
> +Refer to the following sections for each type of build-system:
> +
> +* xref:generic-package-tutorial[]
> +* xref:autotools-package-tutorial[]
> +* xref:cmake-package-tutorial[]
> diff --git a/docs/manual/adding-packages.txt b/docs/manual/adding-packages.txt
> index cb75f2d..1aacaa8 100644
> --- a/docs/manual/adding-packages.txt
> +++ b/docs/manual/adding-packages.txt
> @@ -19,4 +19,6 @@ include::adding-packages-handwritten.txt[]
>
>   include::adding-packages-gettext.txt[]
>
> +include::adding-packages-script.txt[]
> +

  I would put this before the rest of adding-packages.

>   include::adding-packages-conclusion.txt[]
> diff --git a/support/scripts/pkg-new b/support/scripts/pkg-new
> new file mode 100755
> index 0000000..4e1ddac
> --- /dev/null
> +++ b/support/scripts/pkg-new
> @@ -0,0 +1,151 @@
> +#!/bin/bash

  Does it have to be bash?  Hm, yes, for the arrays...  It would be better
if we can avoid relying on bash for new functionality.

> +
> +my_name="${0##*/}"
> +
> +# -----------------------------------------------------------------------------
> +# Ask some questions...
> +#
> +
> +# List of known categories:
> +CAT_LIST=( none multimedia java x11r7 games )
> +# List of known build-systems:
> +BS_LIST=( autotools cmake generic )
> +
> +# --------------------------------------
> +# First, some trivial stuff: what's the package name?
> +if [ -n "${1}" ]; then
> +    pkg_name="${1}"
> +    printf "Starting addition of new package '%s'\n" "${pkg_name}"
> +else
> +    read -p "Name of the package: " pkg_name
> +fi
> +
> +# Check we do not already have this package
> +pkgs="$( find package -type d -name "${pkg_name}" 2>/dev/null )"
> +if [ -n "${pkgs}" ]; then
> +    printf "%s: error: package '%s' already exists in:\n"   \
> +           "${my_name}" "${pkg_name}"
> +    for p in ${pkgs}; do
> +        printf "    %s\n" "${p}"
> +    done
> +    exit 1
> +fi
> +PKG_NAME="$( tr '[:lower:]-' '[:upper:]_'<<<"${pkg_name}" )"
> +
> +# --------------------------------------
> +# Will it be categorised?
> +printf "\n"
> +PS3="Category of your package: "
> +select pkg_cat in "${CAT_LIST[@]}"; do
> +    case "${pkg_cat}" in
> +        none)   pkg_cat=""; break;;
> +        ?*)     break;;
> +    esac
> +    printf "Please enter a number in [1..%d]\n" "${#CAT_LIST[@]}"
> +done
> +
> +pkg_dir="package/${pkg_cat}/${pkg_name}"
> +pkg_dir="${pkg_dir//\/\///}"
> +
> +# --------------------------------------
> +# What kind of build system is it using?
> +printf "\n"
> +PS3="Build-system your package is using: "
> +select pkg_bs in "${BS_LIST[@]}"; do
> +    case "${pkg_bs}" in
> +        *?)     break;;
> +    esac
> +    printf "Please enter a number in [1..%d]\n" "${#BS_LIST[@]}"
> +done
> +
> +# -----------------------------------------------------------------------------
> +# Now we can create the package
> +#
> +
> +mkdir -p "${pkg_dir}"
> +
> +# --------------------------------------
> +# Can't use 'cat<<-_EOF_', as Config.in uses leading tabs.

  I don't think the indented Config.in block is very readable; I'd use a
plain <<_EOF_ with no extra indentation.  Then you can use cat after all.

> +sed -r -e 's/^    //;'>"${pkg_dir}/Config.in"<<_EOF_
> +    config BR2_PACKAGE_${PKG_NAME}_AVAILABLE
> +    	def_bool y
> +    	# Here, add one 'depends on' line for each of your
> +    	# package's dependencies, eg.:
> +    	#depends on BR2_PACKAGE_LIBBAR_AVAILABLE
> +    	#depends on BR2_LARGEFILE
> +
> +    # Update this comment to tell why the package is not available:
> +    comment "${pkg_name} requires XXX and YYY"
> +    	depends on !BR2_PACKAGE_${PKG_NAME}_AVAILABLE
> +
> +    config BR2_PACKAGE_${PKG_NAME}
> +    	bool "${pkg_name}"
> +    	depends on BR2_PACKAGE_${PKG_NAME}_AVAILABLE
> +    	# Here, add one 'select' line for each package your
> +    	# package depends on, eg.:
> +    	#select BR2_PACKAGE_LIBBAR
> +    	help
> +    	  # Here, add a short description of your package
> +    	  # For example, copy the first few description sentences
> +    	  # from the package's website
> +    	
> +    	  # Also, add a pointer to the package's website
> +
> +    # Here, you may add optional features/options of your package:

    # Remove it if it is empty

> +    if BR2_PACKAGE_${PKG_NAME}
> +    endif # BR2_PACKAGE_${PKG_NAME}
> +_EOF_
> +
> +# --------------------------------------
> +# Create the package.mk file
> +cat>"${pkg_dir}/${pkg_name}.mk"<<-_EOF_

  Same here, indentation doesn't look natural to me.

> +	#############################################################
> +	#
> +	# ${pkg_name}
> +	#
> +	#############################################################
> +	
> +	${PKG_NAME}_VERSION       =
> +	${PKG_NAME}_SOURCE        =
> +	${PKG_NAME}_SITE          =
> +	${PKG_NAME}_DEPENDENCIES  =
> +	${PKG_NAME}_LICENSE       =
> +	${PKG_NAME}_LICENSE_FILES =
> +	
> +_EOF_

  For autotools-package and cmake-package, _CONF_OPT is also a very useful one.

  Maybe also add _INSTALL_STAGING.

> +
> +if [ "${pkg_bs}" = "generic" ]; then
> +    cat>>"${pkg_dir}/${pkg_name}.mk"<<-_EOF_
> +		# See docs/manual/ for the complete list of actions that can
> +		# be defined; only the most common ones are listed below:
> +		
> +		define ${PKG_NAME}_CONFIGURE_CMDS
> +		endef
> +		
> +		define ${PKG_NAME}_BUILD_CMDS
> +		endef
> +		
> +		define ${PKG_NAME}_INSTALL_TARGET_CMDS

  Putting a sample
	install -D -m 0644 $(@D)/... $(TARGET_DIR)/...
isn't a bad idea.

> +		endef
> +		
> +		define ${PKG_NAME}_UNINSTALL_TARGET_CMDS
> +		endef
> +		
> +	_EOF_
> +fi
> +
> +printf '$(eval $(%s-package))\n' "${pkg_bs}">>"${pkg_dir}/${pkg_name}.mk"
> +
> +# -----------------------------------------------------------------------------
> +# The End
> +#
> +cat<<-_EOF_
> +	
> +	Your package skeleton files have been created; you can now edit these files
> +	to complete the creation of the package:
> +	  ${pkg_dir}/Config.in
> +	  ${pkg_dir}/${pkg_name}.mk
> +	
> +	Do not forget to also edit '${pkg_dir%/${pkg_name}}/Config.in' to include
> +	${pkg_dir}/Config.in in the correct location.
> +_EOF_


  Regards,
  Arnout
Thomas Petazzoni - Nov. 1, 2012, 9:09 a.m.
On Thu, 01 Nov 2012 03:00:22 +0100, Arnout Vandecappelle wrote:

> > +$ ./support/script/pkg-new
> > +Name of the package: libfoo
> > +
> > +1) none
> > +2) multimedia
> > +3) java
> > +4) x11r7
> > +5) games
> > +Category of your package: 1
> 
>   I would skip this question and always create it in
> packages/libfoo.  The subdirectories are rare, we want to get rid of
> them, and anyway you can easily move the generated directory to a
> different place after the fact.

Agreed. However, I also wonder if it is a good idea to make this script
ask questions, as compared to a more conventional script that takes
command line arguments. But it's true that a script asking questions is
more like a wizard, probably easier to use.

> > +		define ${PKG_NAME}_INSTALL_TARGET_CMDS
> 
>   Putting a sample
> 	install -D -m 0644 $(@D)/... $(TARGET_DIR)/...
> isn't a bad idea.

Not sure I agree here. People too often do manual installation in
generic packages, while they should use 'make install', possibly after
tunning/patching the Makefile.

Best regards,

Thomas
Yann E. MORIN - Nov. 1, 2012, 4:56 p.m.
Arnout, All,

On Thursday 01 November 2012 Arnout Vandecappelle wrote:
> On 09/10/12 01:40, Yann E. MORIN wrote:
> > --- /dev/null
> > +++ b/docs/manual/adding-packages-script.txt
> > @@ -0,0 +1,41 @@
> > +$ ./support/script/pkg-new
> > +Name of the package: libfoo
> > +
> > +1) none
> > +2) multimedia
> > +3) java
> > +4) x11r7
> > +5) games
> > +Category of your package: 1
> 
>   I would skip this question and always create it in packages/libfoo.  The
> subdirectories are rare, we want to get rid of them, and anyway you can
> easily move the generated directory to a different place after the fact.

OK

> > --- a/docs/manual/adding-packages.txt
> > +++ b/docs/manual/adding-packages.txt
> > @@ -19,4 +19,6 @@ include::adding-packages-handwritten.txt[]
> >
> >   include::adding-packages-gettext.txt[]
> >
> > +include::adding-packages-script.txt[]
> > +
> 
>   I would put this before the rest of adding-packages.

I've poundered this, too, but the script just an /implementation/ of the
documentation, so I think it should go last.

> > --- /dev/null
> > +++ b/support/scripts/pkg-new
> > @@ -0,0 +1,151 @@
> > +#!/bin/bash
> 
>   Does it have to be bash?  Hm, yes, for the arrays...  It would be better
> if we can avoid relying on bash for new functionality.

I'll check if I can make it a POSIX-compliant script.


> > +# --------------------------------------
> > +# Can't use 'cat<<-_EOF_', as Config.in uses leading tabs.
> 
>   I don't think the indented Config.in block is very readable; I'd use a
> plain <<_EOF_ with no extra indentation.  Then you can use cat after all.

Indenting here-documents allows one to easily see the end of it. I
personally have difficulties reading scripts where this is not the case.

> > +# --------------------------------------
> > +# Create the package.mk file
> > +cat>"${pkg_dir}/${pkg_name}.mk"<<-_EOF_
> 
>   Same here, indentation doesn't look natural to me.

Hmmm. Let's ask a neutral party, then! ;-)

> > +	#############################################################
> > +	#
> > +	# ${pkg_name}
> > +	#
> > +	#############################################################
> > +	
> > +	${PKG_NAME}_VERSION       =
> > +	${PKG_NAME}_SOURCE        =
> > +	${PKG_NAME}_SITE          =
> > +	${PKG_NAME}_DEPENDENCIES  =
> > +	${PKG_NAME}_LICENSE       =
> > +	${PKG_NAME}_LICENSE_FILES =
> > +	
> > +_EOF_
> 
>   For autotools-package and cmake-package, _CONF_OPT is also a very useful one.
>   Maybe also add _INSTALL_STAGING.

I think we should fill-in only strictly-required variables.

> > +if [ "${pkg_bs}" = "generic" ]; then
> > +    cat>>"${pkg_dir}/${pkg_name}.mk"<<-_EOF_
> > +		# See docs/manual/ for the complete list of actions that can
> > +		# be defined; only the most common ones are listed below:
> > +		
> > +		define ${PKG_NAME}_CONFIGURE_CMDS
> > +		endef
> > +		
> > +		define ${PKG_NAME}_BUILD_CMDS
> > +		endef
> > +		
> > +		define ${PKG_NAME}_INSTALL_TARGET_CMDS
> 
>   Putting a sample
> 	install -D -m 0644 $(@D)/... $(TARGET_DIR)/...
> isn't a bad idea.

I don't like it. This is just a skeleton file. No default value has been
provided for any variable.

Regards,
Yann E. MORIN.
Yann E. MORIN - Nov. 1, 2012, 5 p.m.
Thomas, All,

On Thursday 01 November 2012 Thomas Petazzoni wrote:
> However, I also wonder if it is a good idea to make this script
> ask questions, as compared to a more conventional script that takes
> command line arguments. But it's true that a script asking questions is
> more like a wizard, probably easier to use.

Indeed, the script is designed as a wizard for newbies, so they do not
find it too complex to add a new package, especially since the
_AVAILABLE stuff can be a bit misleading.

It's also meant for experts to quickly add a new package. For them, it
might be better to get the values from the arguments, rather than asking
questions, right. This script can be refined later for this use-case.

> > > +		define ${PKG_NAME}_INSTALL_TARGET_CMDS
> > 
> >   Putting a sample
> > 	install -D -m 0644 $(@D)/... $(TARGET_DIR)/...
> > isn't a bad idea.
> 
> Not sure I agree here. People too often do manual installation in
> generic packages, while they should use 'make install', possibly after
> tunning/patching the Makefile.

Agreed.

Regards,
Yann E. MORIN.
Yann E. MORIN - Nov. 1, 2012, 5:25 p.m.
Arnout, All,

On Thursday 01 November 2012 Arnout Vandecappelle wrote:
> On 09/10/12 01:40, Yann E. MORIN wrote:
> > This script asks a few questions to the user, and creates the skeleton
> > files (Config.in and package.mk).
[--SNIP--]
> > +# --------------------------------------
> > +# Can't use 'cat<<-_EOF_', as Config.in uses leading tabs.
> 
>   I don't think the indented Config.in block is very readable; I'd use a
> plain <<_EOF_ with no extra indentation.  Then you can use cat after all.

Hmm. Maybe that's because my default tabstop is 4, not 8.
I just tried with 8, and it is indeed less readable.

Yet, I prefer that here-documents be indented rather than not.
I'll see to make it readable for tabstop=8.

Regards,
Yann E. MORIN.

Patch

diff --git a/docs/manual/adding-packages-script.txt b/docs/manual/adding-packages-script.txt
new file mode 100644
index 0000000..b19e6ee
--- /dev/null
+++ b/docs/manual/adding-packages-script.txt
@@ -0,0 +1,41 @@ 
+Scripted new package
+--------------------
+
+To help you add your new package, Buildroot offers a script that partially
+automates the creation of a new package: +support/scripts/pkg-new+.
+
+When run, this script asks you a few questions about your package, and
+creates skeleton files for you, so you only have to fill-in the the values
+for the different variables.
+
+----
+$ ./support/script/pkg-new
+Name of the package: libfoo
+
+1) none
+2) multimedia
+3) java
+4) x11r7
+5) games
+Category of your package: 1
+
+1) autotools
+2) cmake
+3) generic
+Build-system your package is using: 1
+
+Your package skeleton files have been created; you can now edit these files
+to complete the creation of the package:
+  package/libfoo/Config.in
+  package/libfoo/libfoo.mk
+
+Do not forget to also edit 'package/Config.in' to include
+package/libfoo/Config.in in the correct location.
+----
+
+Then, you just have to edit the two generated files with appropriate values.
+Refer to the following sections for each type of build-system:
+
+* xref:generic-package-tutorial[]
+* xref:autotools-package-tutorial[]
+* xref:cmake-package-tutorial[]
diff --git a/docs/manual/adding-packages.txt b/docs/manual/adding-packages.txt
index cb75f2d..1aacaa8 100644
--- a/docs/manual/adding-packages.txt
+++ b/docs/manual/adding-packages.txt
@@ -19,4 +19,6 @@  include::adding-packages-handwritten.txt[]
 
 include::adding-packages-gettext.txt[]
 
+include::adding-packages-script.txt[]
+
 include::adding-packages-conclusion.txt[]
diff --git a/support/scripts/pkg-new b/support/scripts/pkg-new
new file mode 100755
index 0000000..4e1ddac
--- /dev/null
+++ b/support/scripts/pkg-new
@@ -0,0 +1,151 @@ 
+#!/bin/bash
+
+my_name="${0##*/}"
+
+# -----------------------------------------------------------------------------
+# Ask some questions...
+# 
+
+# List of known categories:
+CAT_LIST=( none multimedia java x11r7 games )
+# List of known build-systems:
+BS_LIST=( autotools cmake generic )
+
+# --------------------------------------
+# First, some trivial stuff: what's the package name?
+if [ -n "${1}" ]; then
+    pkg_name="${1}"
+    printf "Starting addition of new package '%s'\n" "${pkg_name}"
+else
+    read -p "Name of the package: " pkg_name
+fi
+
+# Check we do not already have this package
+pkgs="$( find package -type d -name "${pkg_name}" 2>/dev/null )"
+if [ -n "${pkgs}" ]; then
+    printf "%s: error: package '%s' already exists in:\n"   \
+           "${my_name}" "${pkg_name}"
+    for p in ${pkgs}; do
+        printf "    %s\n" "${p}"
+    done
+    exit 1
+fi
+PKG_NAME="$( tr '[:lower:]-' '[:upper:]_' <<<"${pkg_name}" )"
+
+# --------------------------------------
+# Will it be categorised?
+printf "\n"
+PS3="Category of your package: "
+select pkg_cat in "${CAT_LIST[@]}"; do
+    case "${pkg_cat}" in
+        none)   pkg_cat=""; break;;
+        ?*)     break;;
+    esac
+    printf "Please enter a number in [1..%d]\n" "${#CAT_LIST[@]}"
+done
+
+pkg_dir="package/${pkg_cat}/${pkg_name}"
+pkg_dir="${pkg_dir//\/\///}"
+
+# --------------------------------------
+# What kind of build system is it using?
+printf "\n"
+PS3="Build-system your package is using: "
+select pkg_bs in "${BS_LIST[@]}"; do
+    case "${pkg_bs}" in
+        *?)     break;;
+    esac
+    printf "Please enter a number in [1..%d]\n" "${#BS_LIST[@]}"
+done
+
+# -----------------------------------------------------------------------------
+# Now we can create the package
+#
+
+mkdir -p "${pkg_dir}"
+
+# --------------------------------------
+# Can't use 'cat <<-_EOF_', as Config.in uses leading tabs.
+sed -r -e 's/^    //;' >"${pkg_dir}/Config.in" <<_EOF_
+    config BR2_PACKAGE_${PKG_NAME}_AVAILABLE
+    	def_bool y
+    	# Here, add one 'depends on' line for each of your
+    	# package's dependencies, eg.:
+    	#depends on BR2_PACKAGE_LIBBAR_AVAILABLE
+    	#depends on BR2_LARGEFILE
+    
+    # Update this comment to tell why the package is not available:
+    comment "${pkg_name} requires XXX and YYY"
+    	depends on !BR2_PACKAGE_${PKG_NAME}_AVAILABLE
+    
+    config BR2_PACKAGE_${PKG_NAME}
+    	bool "${pkg_name}"
+    	depends on BR2_PACKAGE_${PKG_NAME}_AVAILABLE
+    	# Here, add one 'select' line for each package your
+    	# package depends on, eg.:
+    	#select BR2_PACKAGE_LIBBAR
+    	help
+    	  # Here, add a short description of your package
+    	  # For example, copy the first few description sentences
+    	  # from the package's website
+    	  
+    	  # Also, add a pointer to the package's website
+    
+    # Here, you may add optional features/options of your package:
+    if BR2_PACKAGE_${PKG_NAME}
+    endif # BR2_PACKAGE_${PKG_NAME}
+_EOF_
+
+# --------------------------------------
+# Create the package.mk file
+cat >"${pkg_dir}/${pkg_name}.mk" <<-_EOF_
+	#############################################################
+	#
+	# ${pkg_name}
+	#
+	#############################################################
+	
+	${PKG_NAME}_VERSION       = 
+	${PKG_NAME}_SOURCE        = 
+	${PKG_NAME}_SITE          = 
+	${PKG_NAME}_DEPENDENCIES  = 
+	${PKG_NAME}_LICENSE       = 
+	${PKG_NAME}_LICENSE_FILES = 
+	
+_EOF_
+
+if [ "${pkg_bs}" = "generic" ]; then
+    cat  >>"${pkg_dir}/${pkg_name}.mk" <<-_EOF_
+		# See docs/manual/ for the complete list of actions that can
+		# be defined; only the most common ones are listed below:
+		
+		define ${PKG_NAME}_CONFIGURE_CMDS
+		endef
+		
+		define ${PKG_NAME}_BUILD_CMDS
+		endef
+		
+		define ${PKG_NAME}_INSTALL_TARGET_CMDS
+		endef
+		
+		define ${PKG_NAME}_UNINSTALL_TARGET_CMDS
+		endef
+		
+	_EOF_
+fi
+
+printf '$(eval $(%s-package))\n' "${pkg_bs}" >>"${pkg_dir}/${pkg_name}.mk"
+
+# -----------------------------------------------------------------------------
+# The End
+# 
+cat <<-_EOF_
+	
+	Your package skeleton files have been created; you can now edit these files
+	to complete the creation of the package:
+	  ${pkg_dir}/Config.in
+	  ${pkg_dir}/${pkg_name}.mk
+	
+	Do not forget to also edit '${pkg_dir%/${pkg_name}}/Config.in' to include
+	${pkg_dir}/Config.in in the correct location.
+_EOF_