How To Make Linux Packages

Making a man page

  1. Write a text file to be a manpage as outlined in the "LINUX MAN-PAGE-HOWTO". Many of the following sections should normally be considered mandatory: "NAME, SYNOPSIS, DESCRIPTION, OPTIONS, FILES, EXAMPLES, AUTHOR." The following sections may be optional: "ENVIRONMENT, DIAGNOSTICS, BUGS, SEE ALSO".
  2. Modify the text file with macros that are used by various programs you will use to make and read man pages including groff and ghostscript? The macros are listed below(They are defined in the directory "/usr/lib/groff/tmac" and the normal file used is "tmac.an".):
    .AL - Creates an automatic numbered list. ".AL A" creates A,B, C.. list.
    .B - Bold
    .BI
    .BR - Bold Roman?
    .DL - Creates a dashed list using dashes rather than bullets.
    .DT - Tabs every half inch
    .EL
    .H - Heading, levels 1-7, 1 is highest. ".H 2" sets a level 2 heading
    .HP
    .I - Italics
    .IB
    .IP
    .IR
    LI - Lists, creates a bulleted list
    .LE - Ends a bulleted list
    .LP
    .ML - Creates a list with the character of your choice.
    .TH - Title header
    .PD - Set distance between lines, normally "PD 10". "PD 0" sets no space
    .PP - Paragraph break?
    .RB
    .RE
    .RS
    .S
    .SB
    .SH - Section headers
    .SM
    .SS - Subsection header
    .TH - Title header
    .TP - Sets a new paragraph. Title Paragraph?
    .de - define a new macro (EX: ".de PP" define a macro PP). The commands follow this line. The last line ".." indicates the end of the definition. This applies to the "tmac.an" file.
    .ft - Set font (EX: ".ft B" sets bold font. ".ft I" sets italics "\fB" sets bold )
    .in - Indent text (EX: ".in 0.90" indents text 9 tenths of an inch).
    .ll - Line length (EX ".ll 7I" sets the line length to seven inches)
    .nr- Number register (EX: ".nr H3 2" Restarts the numbering of third level headings at 2.
    .ps - Point size (EX: .ps 14 defines point size of 14)
    \s - Embedded point size command (EX: \s20 Changes point size to 20 within a sentence)
    .sp - Gives one blank line
    .ti - Temporary indent (EX: ".ti 2I" Temporarily indents a line 2 inches, the next line is back to normal)
    .vs - Vertical spacing (EX: .vs 14 sets vertical spacing to 14.)
    \fP - Set to the previous font
    \fR - Set font to Roman
    \fI - Set font to italics
    \fB - Set font to bold
  3. Run groff on the text file. The file I made for my project "viewmod" starts as follows:

    .TH VIEWMOD 1 "SEPTEMBER 1999" Linux "User Manuals"
    .SH NAME
    viewmod \- View or modify data in files or standard input and send results to stdout.
    .SH SYNOPSIS
    viewmod [inputfile] [option1] [option2]
    .SH DESCRIPTION
    Allows data from files or standard input to be viewed or modified with the results sent to standard output. This program can operate on any type of files whether they are binary or text files. It was originally written to search files for hidden control characters and get rid of them along with conversion of DOS based text files to UNIX based text files and vice/versa. There are two option types listed below. They are display type option and line length option. Of the display type option, there are currently eight choices. Only one of these choices may be used at a time. Choices 0 through 4 were mainly intended to be used to view file contents, but could be used to create new files by redirecting standard output to a file. Choices 5 through 7 were intended to do file conversions to strip or add additional characters to a file. Display option 1 is the default, and the default line length is set to 80 characters.

    .SH OPTIONS
    .TP
    .B \-D0
    Sends all characters to standard output as though they are ASCII characters. Adds a LF if the line length will be exceeded.

    The name of the text file is "viewmod.txt".
    To run groff, type "groff -t –man -Tascii viewmod.txt > viewmod.1"

  4. Copy the file "viewmod.1" to the subdirectory "/usr/man/man1". Note, this assumes that it is appropriate for this file to be put in the man 1 pages.

Appropriate locations to put man pages

  • 1 - User commands that may be started by everyone.
  • 2 - System calls, that is, functions provided by the kernel.
  • 3 - Subroutines, that is, library functions.
  • 4 - Devices, that is, special files in the /dev directory.
  • 5 - File format descriptions, e.g. /etc/passwd.
  • 6 - Games, self-explanatory.
  • 7 - Miscellaneous, e.g. macro packages, conventions.
  • 8 - System administration tools that only root can execute.
  • 9 - Another (Linux specific) place for kernel routine documentation.
  • n - New documentation, that may be moved to a more appropriate section.
  • o - Old documentation, that may be kept for a grace period.
  • l - Local documentation referring to this particular system.

Making makefiles

Dependencies:
The two lines below are an example of a dependency. The first line defines the dependency relationship, and the second line defines the command line. There may be several command lines.

	test_example : this.o that.o
	     cc -o george this.o that.o

In the example the dependency relationship defines this.o and that.o are required. The program george is generated. Normally the program name is the same as the dependency label "test_example".
Make predefined macros:

Below is an example Make file I created to compile and install a project with 3 source binaries (spooldata, stripchars, lmax) and 1 script file (printst) along with 3 man pages and 1 configuration file. NOTE: All commands must begin with the TAB character.

# Make file for the project myproject
SHELL = /bin/bash
BINLOC = /usr/local/tmp
CONFLOC = /usr/local/etc
MANLOC = /usr/man

EXEC1 = spooldata
EXEC2 = stripchars
EXEC3 = lmax

SHUTILS = printst
CONFFILES = spooldata.conf
MANFILES = stripchars.1 spooldata.8 spooldata.conf.5
PRUTILS = $(EXEC1) $(EXEC2) $(EXEC3)

OBJS1 = $(EXEC1:=.o)
OBJS2 = $(EXEC2:=.o)
OBJS3 = $(EXEC3:=.o)

SRCS1 = $(EXEC1:=.c)
SRCS2 = $(EXEC2:=.c)
SRCS3 = $(EXEC3:=.c)

.SUFFIXES : .c .o
# CC = gcc

# $(PRUTILS): $($@.o)   #One way to do it, but won't work with GNU make
#	$(CC) -o $@ $@.o

all: $(PRUTILS)	#invoked when "make all" typed.  Does make for EXEC1, EXEC2, EXEC3.

$(EXEC1): $(OBJS1)
	$(CC) -o $(EXEC1) $(OBJS1)

$(EXEC2): $(OBJS2)
	$(CC) -o $(EXEC2) $(OBJS2)

$(EXEC3): $(OBJS3)
	$(CC) -o $(EXEC3) $(OBJS3)

.c.o:			#Uses suffix rule to compile c file to get object file
	$(CC) -c $<

#$(OBJS1): $(SRCS1)	#These lines are replaced by suffix rule above.
#	$(CC) -c $(SRCS1)
#$(OBJS2): $(SRCS2)
#	$(CC) -c $(SRCS2)
#$(OBJS3): $(SRCS3)
#	$(CC) -c $(SRCS3)

install:
	@if \			#creates directory if necessary
	   [ ! -d $(BINLOC) ]; \
        then \
	   mkdir $(BINLOC); \
	fi

	@for i in $(PRUTILS); do \	#Copies files in PRUTILS to their proper location
	   cp $$i $(BINLOC)/$$i; \
	   chmod +x $(BINLOC)/$$i; \
	   echo copying $$i to $(BINLOC)/$$i; \
	done ; \

	@for i in $(SHUTILS); do \
	   cp $$i $(BINLOC)/$$i; \
	   chmod +x $(BINLOC)/$$i; \
	   echo copying $$i to $(BINLOC)/$$i; \
	done

	@if \
	   [ ! -d $(CONFLOC) ]; \
	then \
	   mkdir $(CONFLOC); \
	fi 

	@for i in $(CONFFILES); do \
	   cp $$i $(CONFLOC)/$$i; \
	   echo copying $$i to $(CONFLOC)/$$i; \
	done 

	@for i in $(MANFILES); do \
	   PAGENO=$${i#$${i%[0-9]}}; \
	   cp $$i $(MANLOC)/man$$PAGENO/$$i; \
	   echo copying $$i to $(MANLOC)/man$$PAGENO/$$i; \
	done 

clean:
	rm -f *.o

Making install packages

tar cf myproject.tar /usr/local/myprojectTakes all files in myproject and puts them in new archive file.
tar rf myproject.tar ./thisfileAdds thisfile to myproject.tar
gzip myproject.tarReplaces myproject.tar with the file myproject.tar.gz
gzip –9 myproject.tar Uses most compact compression, default is 6. Fastest is 1.

How to Build RPM packages

  1. Zip the files into one tarred and gzipped file. Put all the files into one directory, then perform the zip. The files are placed in the directory myprint-1.0.0 for this example. Zip the files with the command:

    tar cvfz myprint-1.0.0.tar.gz myprint-1.0.0

  2. Copy the tarred and gzipped file to /usr/src/redhat/SOURCES.

    cp myprint-1.0.0.tar.gz /usr/src/redhat/SOURCES

  3. Make a spec file called myprint-1.0.0.spec similar to the one below:
    Summary: My print package
    Name: myprint
    Version: 1.0.0
    Release: 1
    Copyright: GPL
    Group: Development/Tools
    Source: /usr/local/myprint-1.0.0.tar.gz
    
    Vendor: Mycompany
    Packager: George
    
    %description
    This print package does everything I want it to do, including sending me a notice when files are printed.
    %prep
    %setup
    %build
    make all RPM_OPT_FLAGS="$RPM_OPT_FLAGS"
    %install
    make install $RPM_BUILD_ROOT
    %clean
    make clean $RPM_BUILD_ROOT
    %files
    %defattr(-,root,root)
    %config /usr/local/etc/spooldata.conf
    /usr/local/bin/stripchars
    /usr/local/bin/printst
    /usr/local/bin/spooldata
    /usr/local/bin/lmax
    /usr/man/man1/stripchars.1
    /usr/man/man1/printst.1
    /usr/man/man1/lmax.1
    /usr/man/man8/spooldata.8
    /usr/man/man5/spooldata.conf.5
    
  4. Issue the command:

    rpm -ba myprint-1.0.0.spec

A further explanation of the spec file:

Linux Howtos Contents Page