你好,世界!
GNU 是唯一一个为用户自由而开发的计算机系统。GNU 项目尊重计算机用户的自由。
你可能是一个 GNU 用户而你却不知道,因为大多数人错误地把 GNU 系统叫做 Linux,而 Linux 只是 GNU 系统的一个内核。
一个软件项目如果要成为 GNU 的软件包需要满足一定的要求,本文简单介绍一下 GNU 软件包的目录结构。
GNU 软件项目提供软件的源代码和编译系统,让用户可以自主构建二进制可执行文件。
大多数 GNU 软件项目的构建会使用 GNU autotools。autotools 主要是指 GNU autoconf 和 GNU automake,它们使软件编译和构建变得比较统一和明确。一般来说,用户下载 GNU 项目的文件包之后,只需在命令行运行命令,即可编译安装好 GNU 软件:
./configure
make && sudo make install
要达到这样的效果,GNU 项目对软件项目的目录结构就有一定的要求。我们来看一看。
一个极简的 GNU 软件项目的目录如下:
.
├── AUTHORS # a list of authors and emails
├── NEWS # release news
├── README # readme file
├── ChangeLog # a list of commit log
├── Makefile.am # Automake file used to generate the Makefile.in which configure will configure
├── configure.ac # a template file which Autoconf uses to generate the familiar configure script
├── src # a folder for source code files
这些是一个 GNU 项目必须有的最小目录结构和文件。通常,一个成熟的 GNU 软件项目会有更多的目录结构和文件,比如以一个 GNU Guile 项目为例:
.
├── AUTHORS # a list of authors and emails
├── COPYING # AGPL or GPL
├── COPYING.LESSER # LGPL if used
├── HACKING # a note for how to hack the program
├── HISTORY # a history file
├── INSTALL # installation instructions
├── NEWS # release news
├── README # readme file
├── THANKS # thank you file
├── TODO # a note for future tasks
├── ChangeLog # a list of commit log
├── Makefile.am # Automake file used to generate the Makefile.in which configure will configure
├── a.desktop # desktop file for the project
├── a.160x160.xpm # desktop icon file for the project
├── assets # project assets (e.g. images) folder
├── autogen.sh # automatic bootstrap all, if bootstrap file is missing
├── bootstrap # a simple shell script which a developer can regenerate all the GNU Build System files
├── bin # final bin output folder
├── build-aux # a folder for build the program: doc, tests, etc
│ └─ pre-inst-env.in # a shell script which set up environment variables to be able to use your code before installing it
├── configure.ac # a template file which Autoconf uses to generate the familiar configure script
├── doc # final doc output folder
├── m4 # a folder for m4 macros - yes
│ └── guile.m4 # a recent copy of Guile's m4 macros
│ └── aclocal.m4 # a possible copy of Guile's m4 macros
├── po # a folder for project po files
├── src # a folder for source code files
│ └─ skeleton.scm # some initial source code file - Guile module (skeleton)
├── src/skeleton
│ └─ hello.scm # some initial source code file - (skeleton hello) module
└── tests # a folder for test files
└─ cases-hello.scm # some basic tests for hello.scm
其中有几个文件相对比较标准,开发者可以参考。比如 'bootstrap' 或 'autogen.sh' 的内容简单为:
#!/bin/sh
# Usage: sh -x ./bootstrap [--libtoolize]
[ -f src/skeleton.scm ] || {
echo "bootstrap: run this command only in the project directory."
exit 1
}
set -e -x
######################################################################
# Invoke the auto* tools.
autoreconf -B `guile-config info datadir`/aclocal -v -i -f
######################################################################
# Done.
: Now run configure and make.
# bootstrap ends here
'configure.ac' 最少需要包含以下内容:
# program name=helloworld; version=0.1; maintainer=wxie@email
AC_INIT([helloworld], [0.1], [wxie@email])
# use automake
AM_INIT_AUTOMAKE
## use Guile compiler
# We require pkg.m4 (from pkg-config) and guile.m4 (from Guile.)
# Make sure they are available when generating the configure script.
m4_pattern_forbid([^PKG_PROG])
m4_pattern_forbid([^PKG_CHECK])
m4_pattern_forbid([^GUILE_P])
m4_pattern_allow([^GUILE_PKG_ERRORS])
m4_pattern_allow([^GUILE_PKG])
m4_pattern_allow([^GUILE_PROGS])
# Check for latest Guile development files.
# PKG_CHECK_MODULES([GUILE], [guile-3.0])
GUILE_PKG([3.0 2.2])
# Checks for programs.
GUILE_PROGS
GUILE_FLAGS
if test "x$GUILD" = "x"; then
AC_MSG_ERROR(['guild' binary not found; please check your guile installation.])
fi
dnl Guile prefix and libdir.
GUILE_PREFIX=`$PKG_CONFIG --print-errors --variable=prefix guile-$GUILE_EFFECTIVE_VERSION`
GUILE_LIBDIR=`$PKG_CONFIG --print-errors --variable=libdir guile-$GUILE_EFFECTIVE_VERSION`
AC_SUBST(GUILE_PREFIX)
AC_SUBST(GUILE_LIBDIR)
guilemoduledir="${datarootdir}/guile/site/${GUILE_EFFECTIVE_VERSION}"
AC_SUBST([guilemoduledir])
AC_SUBST([GUILE_EFFECTIVE_VERSION])
# use Makefile.in
AC_CONFIG_FILES([Makefile])
# output the script
AC_OUTPUT
'Makefile.am' 实际上就是 'Makefile' 的模板,它可以包含一个 'guile.am' 的文件,其内容如下:
# guile.am file is included by Makefile.am
# guile.am file is where we have all the code that can be shared
# between any other Guile project.
moddir=$(datadir)/guile/site/$(GUILE_EFFECTIVE_VERSION)
godir=$(libdir)/guile/$(GUILE_EFFECTIVE_VERSION)/site-ccache
GOBJECTS = $(SOURCES:%.scm=%.go)
nobase_dist_mod_DATA = $(SOURCES) $(NOCOMP_SOURCES)
nobase_go_DATA = $(GOBJECTS)
# Make sure source files are installed first, so that the mtime of
# installed compiled files is greater than that of installed source
# files. See
# <http://lists.gnu.org/archive/html/guile-devel/2010-07/msg00125.html>
# for details.
guile_install_go_files = install-nobase_goDATA
$(guile_install_go_files): install-nobase_dist_modDATA
CLEANFILES = $(GOBJECTS)
GUILE_WARNINGS = -Wunbound-variable -Warity-mismatch -Wformat
SUFFIXES = .scm .go
.scm.go:
$(AM_V_GEN)$(top_builddir)/pre-inst-env $(GUILD) compile $(GUILE_WARNINGS) -o "$@" "$<"
有了以上这几个文件模板和目录结构,创建一个 GNU 软件项目就变得比较简单而标准。
如果你希望自己能够为自由软件作出贡献,并在将来开发一个 GNU 软件项目,那么 立伯乐 或许可以帮你。
让自由软件带你进入的美好自由世界!