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: