[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

rules makefile and packaging basics



Hey Mentors,

I've just started making my own deb packages and I'm struggling to get
them working properly. You'll have to excuse my lack of technical
knowledge, as I've only been programming for a few months. I'm doing
this as a learning task with a view to becoming a contributer /
maintainer in the future.

To start with, I've made a basic python script that produces a simple
GTK based GUI from a text file:

<code>

#!/usr/bin/python

# Code Name: gtk-link-lizard
# Created By: Jim Frize, <http://sonodrome.co.uk>
# Copyright (C) 2011 Jim Frize, <jim@sonodrome.co.uk>

# Licence: GTK Link Lizard is free software: you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version. 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, see
<http://www.gnu.org/licenses/>

# Version: 1.4
# Description: Simple GUI for storing and displaying web links

import pygtk
pygtk.require("2.0")
import gtk
import sys
import re
import os

path = os.getenv("HOME")

class link_lizard():
    def __init__(self):
        self.load_main()

    #################
    # Load main GUI #
    #################
    def load_main(self, data=None):
        # Create main window
        self.main_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        # Quit main function when window is destroyed
        self.main_window.connect("destroy", gtk.main_quit)
        self.main_window.set_size_request(600, 600)
        self.main_window.set_position(gtk.WIN_POS_CENTER)
        self.main_window.set_opacity(0.9)
        self.main_window.set_title("GTK Link Lizard")
        self.main_window.set_keep_above(True)

        # Create scrolled window
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)

        # Create placement boxes and dictionaries
        main_box = gtk.VBox(homogeneous=False)
        link_box = gtk.VBox(homogeneous=False)
        linkbutton = {}
        label = {}

        # Create edit button
        edit_button = gtk.Button("Edit Links")
        edit_button.connect("clicked", self.load_edit)

        # Open text file and count number of lines
        self.text_file = open(path +
"/Documents/gtk-link-lizard-1.4/links.txt","r")
        number_lines = len(self.text_file.readlines())

        # Reset counter and check through each line of text
        count = 0
        while(count < number_lines):
            self.text_file = open(path +
"/Documents/gtk-link-lizard-1.4/links.txt","r")
            all_lines = self.text_file.readlines()
            current_line = all_lines[count]
            match = re.search("http://";, current_line)
            match2 = re.search("https://";, current_line)
            match3 = re.search("www.", current_line)

            # If http link is found, make a linkButton
            if match:
                current_url = match.group()
                # Remove http://
                split_line = current_line.split("http://";)

                if match3:
                    # Remove www.
                    split_line = split_line[1].split("www.")

                linkbutton[count] = gtk.LinkButton(current_line, split_line[1])
                linkbutton[count].set_size_request(600, 30)
                link_box.pack_start(linkbutton[count], expand=False)

            # If https link is found, make a linkButton
            elif match2:
                current_url = match2.group()
                # Remove https://
                split_line = current_line.split("https://";)

                if match3:
                    # Remove www.
                    split_line = split_line[1].split("www.")

                linkbutton[count] = gtk.LinkButton(current_line, split_line[1])
                linkbutton[count].set_size_request(600, 30)
                link_box.pack_start(linkbutton[count], expand=False)


            # If no link is found, add text as a label
            else:
                label[count] = gtk.Label(current_line)
                label[count].set_size_request(600, 20)
                link_box.pack_start(label[count], expand=False)

            count+=1

        # Add everything
        main_box.pack_start(edit_button, expand=False)
        scrolled_window.add_with_viewport(link_box)
        main_box.add(scrolled_window)
        self.main_window.add(main_box)
        self.main_window.show_all()

    #################
    # Load edit GUI #
    #################
    def load_edit(self, data=None):
        # Hide main window
        self.main_window.hide()
        # Create edit window
        self.edit_window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        # Return to main window when edit window is destroyed
        self.edit_window.connect("destroy", self.load_main)
        self.edit_window.set_size_request(600, 600)
        self.edit_window.set_position(gtk.WIN_POS_CENTER)
        self.edit_window.set_title("GTK Link Lizard (Editing Links)")

        # Create scrolled window
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)

        # Create boxes for layout
        main_box = gtk.VBox(homogeneous=False)
        text_box = gtk.VBox(homogeneous=False)
        button_box = gtk.HBox(homogeneous=False)

        # Create buttons
        save_button = gtk.Button("Save")
        save_button.connect("clicked", self.save_edit)
        cancel_button = gtk.Button("Cancel")
        cancel_button.connect("clicked", self.cancel_edit)

        # Open file and display in text viewer
        text_file = open(path + "/Documents/gtk-link-lizard-1.4/links.txt","r")
        all_text = text_file.read()
        text_buffer = gtk.TextBuffer()
        text_buffer.set_text(all_text)
        self.text_view = gtk.TextView(text_buffer)

        # Add everything
        button_box.add(save_button)
        button_box.add(cancel_button)
        text_box.add(self.text_view)
        scrolled_window.add_with_viewport(text_box)
        main_box.pack_start(button_box, expand=False)
        main_box.add(scrolled_window)
        self.edit_window.add(main_box)
        self.edit_window.show_all()

    #############
    # Save edit #
    #############
    def save_edit(self, data=None):
        save_buffer = self.text_view.get_buffer()
        save_text = save_buffer.get_text(save_buffer.get_start_iter()
, save_buffer.get_end_iter())
        self.text_file = open(path +
"/Documents/gtk-link-lizard-1.4/links.txt","w")
        self.text_file.write(save_text)
        self.edit_window.destroy()

    ###############
    # Cancel edit #
    ###############
    def cancel_edit(self, data=None):
        self.edit_window.destroy()

    #################
    # Main function #
    #################
    def main(self):
        gtk.main()

# Run main function when class is called
if __name__ == "__main__":
    new_link_lizard = link_lizard()
    new_link_lizard.main()

</code>

The rules file I've used is based on the example found here -->
/usr/share/doc/debhelper/examples/rules.arch
I've just added a few lines to copy my files to the relevant destination paths:

<code>

#!/usr/bin/make -f

build: build-stamp
build-stamp:
	dh_testdir

	# Add commands to compile the package here

	touch build-stamp

clean:
	dh_testdir
	dh_testroot
	rm -f build-stamp

	# Add commands to clean up after the build process here

	dh_clean

install: build
	dh_testdir
	dh_testroot
	dh_prep
	dh_installdirs

	# Add commands to install the package here

	mkdir -m 755 -p /usr/share/gtk-link-lizard-1.4
	mkdir -m 777 -p ~/Documents/gtk-link-lizard-1.4
	install -m 755 $(CURDIR)/gtk-link-lizard.py /usr/share/gtk-link-lizard-1.4
	install -m 755 $(CURDIR)/link-lizard-icon.png /usr/share/gtk-link-lizard-1.4
	install -m 777 $(CURDIR)/links.txt ~/Documents/gtk-link-lizard-1.4
	install -m 755 $(CURDIR)"/GTK Link Lizard.desktop" /usr/share/applications

binary-indep: build install

	# Build architecture-independent files here

	dh_testdir
	dh_testroot
	dh_installchangelogs
	dh_installdocs
	dh_installexamples
#	dh_installmenu
#	dh_installdebconf
#	dh_installlogrotate
#	dh_installemacsen
#	dh_installcatalogs
#	dh_installpam
#	dh_installmime
#	dh_installinit
#	dh_installcron
#	dh_installinfo
#	dh_installwm
#	dh_installudev
#	dh_lintian
#	dh_bugfiles
#	dh_undocumented
	dh_installman
	dh_link
	dh_compress
	dh_fixperms
#	dh_perl
	dh_installdeb
	dh_gencontrol
	dh_md5sums
	dh_builddeb

binary-arch: build install
	# Build architecture-dependent files here

binary: binary-indep binary-arch
.PHONY: build clean binary-indep binary-arch binary install

</code>

So, I've used this rules file to make a deb package which will install
properly on my system, the files all copy/install in the right place
and the program functions properly. I do want the package to
automatically add the desktop launcher to the gnome menu system, but
I'm yet to get that to work.

desktop launcher:

<code>

#!/usr/bin/env xdg-open

[Desktop Entry]
Version=1.0
Type=Application
Terminal=false
Exec=/usr/share/gtk-link-lizard-1.4/gtk-link-lizard.py
Name=GTK Link Lizard
Icon=/usr/share/gtk-link-lizard-1.4/link-lizard-icon.png

</code>

Another thing I'm not able to do is build a package that removes all
it's files on uninstall, it will uninstall from synaptic, but all the
files remain. Also from Ubuntu software center the package cannot be
uninstalled only reinstalled.

The last issue to point out is the fact that the package will not
install properly on my other system (Ubuntu 10.04, Linux kernel
2.6.32-28-generic and GNOME 2.30.2), it works fine on my main system
which is running Ubuntu 10.10, Linux kernel 2.6.35-25-generic and
GNOME 2.32.0. When I try to install it on my other system none of the
files copy over and none of the directories are created, the only
files that are copied properly are the documents that install a folder
and files in the destination path usr/share/doc.

Obviously I'm not getting how this is all supposed to work, I've been
search and reading for about 3 days now but I'm struggling to find the
right info (probably due to my lack of technical knowledge and my
unfamiliarity with various terms and nomenclature).

I'd appreciate some help demystifying the packaging process, plus I'd
like to know of any glaring omissions in my code or any tips tricks
that might make my package better.

Thanks for reading

Jim.


Reply to: