什么是"aerodynamicallyy linked executable

linux动态链接库导出函数控制
windows 环境的vc的话,可以方便的指定__declspec(dllexport) 关键字来控制是否把dll中的函数导出。 我也来测试一下linux下面是如何做的: 先看gcc 和ld的相关选项
====================================== gcc 选项
Produce a shared object which can then be linked with other
to form an executable.
Not all systems support this option.
predictable results, you must also specify the same set of
that were used to generate code (-fpic, -fPIC, or model
suboptions)
when you specify this option.[1]
Generate position-independent code (PIC) suitable for use in
shared library, if supported for the target machine.
accesses all constant addresses through a global offset
The dynamic loader resolves the GOT entries when the
program starts (the dynamic loader is not part of GCC; it is
of the operating system).
If the GOT size for the linked
executable exceeds a machine-specific maximum size, you get
error message from the linker indicating that -
in that case, recompile with -fPIC instead.
(These maximums
on the SPARC and 32k on the m68k and RS/6000.
The 386 has
Position-independent code requires special support, and
works only on certain machines.
For the 386, GCC supports
System V but not for the Sun 386i.
Code generated for the
RS/6000 is always position-independent.
When this flag is set, the macros "__pic__" and "__PIC__"
defined to 1.
If supported for the target machine, emit
position-independent
code, suitable for dynamic linking and avoiding any limit on
size of the global offset table.
This option makes a
difference on
the m68k, PowerPC and SPARC.
Position-independent code requires special support, and
works only on certain machines.
When this flag is set, the macros "__pic__" and "__PIC__"
defined to 2.
Pass the flag -export-dynamic to the ELF linker, on targets
support it. This instructs the linker to add all symbols,
used ones, to the dynamic symbol table. This option is
needed for
some uses of "dlopen" or to allow obtaining backtraces from
a program.
-fvisibility=default|internal|hidden|protected
Set the default ELF image symbol visibility to the specified
option---all symbols will be marked with this unless
overridden
within the code.
Using this feature can very substantially
linking and load times of shared object libraries, produce
optimized code, provide near-perfect API export and prevent
It is strongly recommended that you use this in
shared objects you distribute.
Despite the nomenclature, "default" alw
available to be linked against from outside the shared
"protected" and "internal" are pretty useless in real-world
so the only other commonly used option will be "hidden".
default if -fvisibility isn't specified is "default", i.e.,
every symbol public---this causes the same behavior as
versions of GCC.
A good explanation of the benefits offered by ensuring
ELF symbols
have the correct visibility is given by "How To Write Shared
Libraries" by Ulrich Drepper (which can be found at
&/~drepper/&)---however
a superior solution
made possible by this option to marking things hidden when
default is public is to make the default hidden and mark
This is the norm with DLL's on Windows and with
-fvisibility=hidden and "__attribute__
((visibility("default")))"
instead of "__declspec(dllexport)" you get almost identical
semantics with identical syntax.
This is a great boon to
working with cross-platform projects.
For those adding visibility support to existing code, you
#pragma GCC visibility of use.
This works by you enclosing
declarations you wish to set visibility for with (for
#pragma GCC visibility push(hidden) and #pragma GCC
visibility pop.
Bear in mind that symbol visibility should be viewed as part
API interface contract and thus all new code should always
visibility when it i declarations only
within the local DSO should always be marked explicitly as
as so to avoid PLT indirection overheads---making this
abundantly
clear also aids readability and self-documentation of the
Note that due to ISO C++ specification requirements,
operator new
and operator delete must always be of default visibility.
Be aware that headers from outside your project, in
particular
system headers and headers from any other library you use,
be expecting to be compiled with visibility other than the
You may need to explicitly say #pragma GCC visibility
push(default)
before including any such headers.
extern declarations are not affected by -fvisibility, so a
code can be recompiled with -fvisibility=hidden with no
modifications.
However, this means that calls to extern
with no explicit visibility will use the PLT, so it is more
effective to use __attribute ((visibility)) and/or #pragma
visibility to tell the compiler which extern declarations
treated as hidden.
Note that -fvisibility does affect C++ vague linkage
entities. This
means that, for instance, an exception class that will be
between DSOs must be explicitly marked with default
visibility so
that the type_info nodes will be unified between the DSOs.
An overview of these techniques, their benefits and how
to use them
is at &http://gcc.gnu.org/wiki/Visibility&.
=================================== ld命令选项
--export-dynamic
--no-export-dynamic
When creating a dynamically linked executable, using the -E
or the --export-dynamic option causes the linker to add all
to the dynamic symbol table.
The dynamic symbol table is
of symbols which are visible from dynamic objects at run
If you do not use either of these options (or use the
--no-export-dynamic option to restore the default behavior),
dynamic symbol table will normally contain only those
symbols which
are referenced by some dynamic object mentioned in the link.
If you use "dlopen" to load a dynamic object which needs
back to the symbols defined by the program, rather than some
dynamic object, then you will probably need to use this
option when
linking the program itself.
You can also use the dynamic list to control what symbols
added to the dynamic symbol table if the output format
supports it.
See the description of --dynamic-list.
Note that this option is specific to ELF targeted ports.
targets support a similar function to export all symbols
from a DLL
or EXE; see the description of --export-all-symbols below.
--dynamic-list=dynamic-list-file
Specify the name of a dynamic list file to the linker.
typically used when creating shared libraries to specify a
global symbols whose references shouldn't be bound to the
definition within the shared library, or creating
dynamically
linked executables to specify a list of symbols which should
added to the symbol table in the executable.
This option is
meaningful on ELF platforms which support shared libraries.
The format of the dynamic list is the same as the version
without scope and node name.
See VERSION for more
information.
--dynamic-list-data
Include all global data symbols to the dynamic list.
--version-script=version-scriptfile
Specify the name of a version script to the linker.
typically used when creating shared libraries to
specify additional information about the version hierarchy
for the library being created.
This option is only
fully supported on ELF platforms which suppo see VERSION.
It is partially supported on PE
platforms, which can use version scripts to filter symbol
visibility in auto-export mode: any symbols marked
local in the version script will not be exported.
#VERSION 文件格式可以参考这里
http://sourceware.org/binutils/docs-2.20/ld/VERSION.html#VERSION =========================================
测试看看:
-----------------------main.c ----------------------------------- #include&stdio.h& #include&string.h& #include&stdlib.h&
#include&dlfcn.h&
int test (int i) {
printf("i=%d\n" ,i); }
int main()
int (*test2)(int);
int (*test3)(int);
handler=(int*)dlopen("test.so", RTLD_LAZY);
if (!handler) {
printf( "加载模块错误 %s\n", dlerror() );
test3 = dlsym(handler, "test3");
if (test3) test3(3);
test2 = dlsym(handler, "test2");
if (test2) test2(2);
dlclose(handler);
------------------------------------------------------------------ $ gcc -rdynamic main.c -o main -ldl
$ readelf -s main
Symbol table '.dynsym' contains 25 entries:
UND __gmon_start__
_Jv_RegisterClasses
GLOBAL DEFAULT
UND dlclose@GLIBC_2.0
GLOBAL DEFAULT
UND __libc_start_main@GLIBC_2.0
GLOBAL DEFAULT
UND dlsym@GLIBC_2.0
GLOBAL DEFAULT
UND dlopen@GLIBC_2.1
GLOBAL DEFAULT
UND printf@GLIBC_2.0
GLOBAL DEFAULT
UND dlerror@GLIBC_2.0
GLOBAL DEFAULT
UND exit@GLIBC_2.0
GLOBAL DEFAULT
24 __data_start
GLOBAL DEFAULT
GLOBAL DEFAULT
GLOBAL DEFAULT
ABS _edata
24 data_start
GLOBAL DEFAULT
GLOBAL DEFAULT
17: 080488fc
GLOBAL DEFAULT
16 _IO_stdin_used
GLOBAL DEFAULT
14 __libc_csu_init
GLOBAL DEFAULT
ABS __bss_start
GLOBAL DEFAULT
在这里导出了
GLOBAL DEFAULT
22: 080485ec
GLOBAL DEFAULT
GLOBAL DEFAULT
14 __libc_csu_fini
24: 080488dc
GLOBAL DEFAULT
----------------------------------------------------------------------------------
$ gcc main.c -o main -ldl
$ readelf -s main
Symbol table '.dynsym' contains 11 entries:
UND __gmon_start__
_Jv_RegisterClasses
GLOBAL DEFAULT
UND dlclose@GLIBC_2.0
GLOBAL DEFAULT
UND __libc_start_main@GLIBC_2.0
GLOBAL DEFAULT
UND dlsym@GLIBC_2.0
GLOBAL DEFAULT
UND dlopen@GLIBC_2.1
GLOBAL DEFAULT
UND printf@GLIBC_2.0
GLOBAL DEFAULT
UND dlerror@GLIBC_2.0
///没有把 test函数导出
GLOBAL DEFAULT
UND exit@GLIBC_2.0
10: 080486fc
GLOBAL DEFAULT
16 _IO_stdin_used
==================================================================== $ gcc -rdynamic -fPIC
main.c -o main -ldl
可以看到有
节有把函数导出
=======================================================================
------test.c--------------------- #include&stdio.h& #include&string.h& #include&stdlib.h&
extern int test (int i);
int test2 (int i) {
printf("this is test2\n"); }
int test3 (int i) {
printf("this is test 3\n"); } -----------------------------------------------
$ gcc -shared -fPIC test.c -o test.so
$ readelf -s test.so
节里把所有函数导出
====================================================================
$ ./main 加载模块错误 test.so: cannot open shared object file: No such file or
找不到 test.so文件,他不会自动在当前目录下搜索啊。 那就设置好这个LD_LIBRARY_PATH这个环境变量吧,我是不想复制到系统目录去了
$ echo $LD_LIBRARY_PATH
$ export LD_LIBRARY_PATH=`pwd` $ echo $LD_LIBRARY_PATH /home/widebright/桌面/测试用例
-------------------------- gcc -rdynamic -fPIC
main.c -o main -ldl gcc -shared -fPIC test.c -o test.so 使用上面编译选线,结果
$ ./main this is test 3 i=2 this is test2 -------------------------------- gcc -fPIC
main.c -o main -ldl gcc -shared -fPIC test.c -o test.so 使用上面编译选线,结果test.so就找不到 main中export出来的test函数了 $ ./main
this is test 3 ./main: symbol lookup error: /home/widebright/桌面/测试用例/test.so: undefined
symbol: test -------------------------------- gcc -rdynamic main.c -o main -ldl gcc -shared -fPIC test.c -o test.so 使用上面编译选线,结果还是可以执行,说明 -fPIC对程序来说好像用处不大。 $ ./main this is test 3 i=2 this is test2 ------------------------------------------------ gcc -rdynamic main.c -o main -ldl gcc -shared
test.c -o test.so 使用上面编译选线,也还能正确运行 -fPIC 有什么作用啊,不明显 $ ./main this is test 3 i=2 this is test2 ---------------------------------------------
----visibility.txt------------------ {
local: *; }; -------------------
gcc -rdynamic main.c -o main -ldl gcc -shared
test.c -o test.so -Wl,--version-script=visibility.txt
$ gcc -shared
test.c -o test.so -Wl,--version-script=visibility.txt $ ./main
this is test 3
可以看到 使用--version-script=visibility.txt 参数控制之后,只有test3才被导出了
:~/桌面/测试readelf -s test.so
Symbol table '.dynsym' contains 7 entries:
UND __gmon_start__
_Jv_RegisterClasses
GLOBAL DEFAULT
GLOBAL DEFAULT
UND puts@GLIBC_2.0
UND __cxa_finalize@GLIBC_2.1.3
6: 0000041b
GLOBAL DEFAULT
//visibility.txt文件里面指定了 test3才导出了, test2不再导出了
======================================
gcc -shared
test.c -o test.so
-fvisibility=hidden
----当 -fvisibility=hidden 设置为hidden之后,所有的都函数不再导出了。 readelf -s test.so
Symbol table '.dynsym' contains 11 entries:
UND __gmon_start__
_Jv_RegisterClasses
GLOBAL DEFAULT
///这个还是会在这里,知道是外部函数来的
GLOBAL DEFAULT
UND puts@GLIBC_2.0
UND __cxa_finalize@GLIBC_2.1.3
6: 0000202c
GLOBAL DEFAULT
GLOBAL DEFAULT
ABS _edata
GLOBAL DEFAULT
ABS __bss_start
9: 0000035c
GLOBAL DEFAULT
GLOBAL DEFAULT
==============================================
我们给要导出到函数加上 属性控制,改成这样, ----------test.c----------------- #include&stdio.h& #include&string.h& #include&stdlib.h&
extern int test (int i);
__attribute ((visibility)) int test2 (int i) {
printf("this is test2\n"); }
__attribute ((visibility)) int test3 (int i) {
printf("this is test 3\n"); }
-------------------------------
$ gcc -shared
test.c -o test.so
-fvisibility=hidden $
$ readelf -s test.so
Symbol table '.dynsym' contains 13 entries:
UND __gmon_start__
_Jv_RegisterClasses
GLOBAL DEFAULT
GLOBAL DEFAULT
UND puts@GLIBC_2.0
UND __cxa_finalize@GLIBC_2.1.3
6: 0000202c
GLOBAL DEFAULT
GLOBAL DEFAULT
ABS _edata
8: 000004bc
GLOBAL DEFAULT
//这次就会导出了
GLOBAL DEFAULT
ABS __bss_start
GLOBAL DEFAULT
GLOBAL DEFAULT
12: 000004db
GLOBAL DEFAULT
this is test 3 i=2 this is test2 -----------------------------------------------------
通过gcc命令的-fvisibility=hidden 选项和
"__attribute__
((visibility("default")))" 语法扩展 可以得到 vc中 __declspec(dllexport)"的效果。
--version-script=version-scriptfile 参数 类似vc中到
文件,也可以用来统一链接库到输出与否。
测完才发现,gcc帮助文档提到的 “How To Write Shared Libraries” 这篇文章上面解释的更完整一些, 一个pdf文档,在google搜索一下就可以找到了。
其他的办法还包括: 1. static 定义函数
2、libtool的-export-symbols参数 $ libtool --mode=link gcc -o libfoo.la \
foo.lo -export-symbols=foo.sym
3.使用alias属性来隐藏具体的函数名 int next (void) {
return ++last_
extern __typeof (next) next_int
__attribute ((alias ("next"),
visibility ("hidden")));
请正确填写下面信息
标 签:linux动态链接库导出函数控制
是否保存此网页快照
是否公开此收藏Ubuntu Policy Manual - Binary packages
<link href="ap-pkg-alternatives.html" rel="appendix" title="F Alternative versions of an interface - update-alternatives (from old Packaging Manual)">
<link href="ch-source.html#s-dpkgchangelog" rel="section" title="4.4 Ubuntu changelog: debian/changelog">
<link href="ch-source.html#s-dpkgcopyright" rel="section" title="4.5 Copyright: debian/copyright">
<link href="ch-source.html#s-debianrules" rel="section" title="4.9 Main building script: debian/rules">
<link href="ch-source.html#s-substvars" rel="section" title="4.10 Variable substitutions: debian/substvars">
<link href="ch-source.html#s-debianwatch" rel="section" title="4.11 Optional upstream source location: debian/watch">
<link href="ch-source.html#s-debianfiles" rel="section" title="4.12 Generated files list: debian/files">
<link href="ch-source.html#s-readmesource" rel="section" title="4.14 Source package handling: debian/README.source">
<link href="ch-controlfields.html#s-sourcecontrolfiles" rel="section" title="5.2 Source package control files -- debian/control">
<link href="ch-controlfields.html#s-binarycontrolfiles" rel="section" title="5.3 Binary package control files -- DEBIAN/control">
<link href="ch-controlfields.html#s-debiansourcecontrolfiles" rel="section" title="5.4 Debian source control files -- .dsc">
<link href="ch-controlfields.html#s-debianchangesfiles" rel="section" title="5.5 Debian changes files -- .changes">
<link href="ch-relationships.html#s-binarydeps" rel="section" title="7.2 Binary Dependencies - Depends, Recommends, Suggests, Enhances, Pre-Depends">
<link href="ch-relationships.html#s-breaks" rel="section" title="7.3 Packages which break other packages - Breaks">
<link href="ch-relationships.html#s-conflicts" rel="section" title="7.4 Conflicting binary packages - Conflicts">
<link href="ch-relationships.html#s-virtual" rel="section" title="7.5 Virtual packages - Provides">
<link href="ch-relationships.html#s-replaces" rel="section" title="7.6 Overwriting files and replacing packages - Replaces">
<link href="ch-relationships.html#s-sourcebinarydeps" rel="section" title="7.7 Relationships between source and binary packages - Build-Depends, Build-Depends-Indep, Build-Conflicts, Build-Conflicts-Indep">
<link href="ch-sharedlibs.html#s-sharedlibs-shlibdeps" rel="section" title="8.6 Dependencies between the library and other packages - the shlibs system">
<link href="ch-opersys.html#s-sysvinit" rel="section" title="9.3 System run levels and init.d scripts">
<link href="ch-opersys.html#s9.4" rel="section" title="9.4 Console messages from init.d scripts">
<link href="ap-pkg-binarypkg.html#s-pkg-bincreating" rel="section" title="B.1 Creating package files - dpkg-deb">
<link href="ap-pkg-binarypkg.html#s-pkg-controlfile" rel="section" title="B.3 The main control information file: control">
<link href="ap-pkg-sourcepkg.html#sC.4" rel="section" title="C.4 Unpacking a Debian source package without dpkg-source">
<link href="ap-pkg-conffiles.html#sE.1" rel="section" title="E.1 Automatic handling of configuration files by dpkg">
<link href="ch-source.html#s-debianrules-options" rel="subsection" title="4.9.1 debian/rules and DEB_BUILD_OPTIONS">
<link href="ch-controlfields.html#s-f-Source" rel="subsection" title="5.6.1 Source">
<link href="ch-controlfields.html#s-f-Maintainer" rel="subsection" title="5.6.2 Maintainer">
<link href="ch-controlfields.html#s-f-Uploaders" rel="subsection" title="5.6.3 Uploaders">
<link href="ch-controlfields.html#s-f-Changed-By" rel="subsection" title="5.6.4 Changed-By">
<link href="ch-controlfields.html#s-f-Section" rel="subsection" title="5.6.5 Section">
<link href="ch-controlfields.html#s-f-Priority" rel="subsection" title="5.6.6 Priority">
<link href="ch-controlfields.html#s-f-Package" rel="subsection" title="5.6.7 Package">
<link href="ch-controlfields.html#s-f-Architecture" rel="subsection" title="5.6.8 Architecture">
<link href="ch-controlfields.html#s-f-Essential" rel="subsection" title="5.6.9 Essential">
<link href="ch-controlfields.html#s5.6.10" rel="subsection" title="5.6.10 Package interrelationship fields: Depends, Pre-Depends, Recommends, Suggests, Breaks, Conflicts, Provides, Replaces, Enhances">
<link href="ch-controlfields.html#s-f-Standards-Version" rel="subsection" title="5.6.11 Standards-Version">
<link href="ch-controlfields.html#s-f-Version" rel="subsection" title="5.6.12 Version">
<link href="ch-controlfields.html#s-f-Description" rel="subsection" title="5.6.13 Description">
<link href="ch-controlfields.html#s-f-Distribution" rel="subsection" title="5.6.14 Distribution">
<link href="ch-controlfields.html#s-f-Date" rel="subsection" title="5.6.15 Date">
<link href="ch-controlfields.html#s-f-Format" rel="subsection" title="5.6.16 Format">
<link href="ch-controlfields.html#s-f-Urgency" rel="subsection" title="5.6.17 Urgency">
<link href="ch-controlfields.html#s-f-Changes" rel="subsection" title="5.6.18 Changes">
<link href="ch-controlfields.html#s-f-Binary" rel="subsection" title="5.6.19 Binary">
<link href="ch-controlfields.html#s-f-Installed-Size" rel="subsection" title="5.6.20 Installed-Size">
<link href="ch-controlfields.html#s-f-Files" rel="subsection" title="5.6.21 Files">
<link href="ch-controlfields.html#s-f-Closes" rel="subsection" title="5.6.22 Closes">
<link href="ch-controlfields.html#s-f-Launchpad-Bugs-Fixed" rel="subsection" title="5.6.23 Launchpad-Bugs-Fixed">
<link href="ch-controlfields.html#s-f-Homepage" rel="subsection" title="5.6.24 Homepage">
<link href="ch-sharedlibs.html#s-ldconfig" rel="subsection" title="8.1.1 ldconfig">
<link href="ch-sharedlibs.html#s8.6.1" rel="subsection" title="8.6.1 The shlibs files present on the system">
<link href="ch-sharedlibs.html#s8.6.2" rel="subsection" title="8.6.2 How to use dpkg-shlibdeps and the shlibs files">
<link href="ch-sharedlibs.html#s-shlibs" rel="subsection" title="8.6.3 The shlibs File Format">
<link href="ch-sharedlibs.html#s8.6.4" rel="subsection" title="8.6.4 Providing a shlibs file">
<link href="ch-sharedlibs.html#s-shlibslocal" rel="subsection" title="8.6.5 Writing the debian/shlibs.local file">
<link href="ch-files.html#s10.9.1" rel="subsection" title="10.9.1 The use of dpkg-statoverride">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkg-source" rel="subsection" title="C.1.1 dpkg-source - packs and unpacks Debian source packages">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkg-buildpackage" rel="subsection" title="C.1.2 dpkg-buildpackage - overall package-building control script">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkg-gencontrol" rel="subsection" title="C.1.3 dpkg-gencontrol - generates binary package control files">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkg-shlibdeps" rel="subsection" title="C.1.4 dpkg-shlibdeps - calculates shared library dependencies">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkg-distaddfile" rel="subsection" title="C.1.5 dpkg-distaddfile - adds a file to debian/files">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkg-genchanges" rel="subsection" title="C.1.6 dpkg-genchanges - generates a .changes upload control file">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkg-parsechangelog" rel="subsection" title="C.1.7 dpkg-parsechangelog - produces parsed representation of a changelog">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkg-architecture" rel="subsection" title="C.1.8 dpkg-architecture - information about the build and host system">
<link href="ap-pkg-sourcepkg.html#s-pkg-debianrules" rel="subsection" title="C.2.1 debian/rules - the main building script">
<link href="ap-pkg-sourcepkg.html#s-pkg-dpkgchangelog" rel="subsection" title="C.2.2 debian/changelog">
<link href="ap-pkg-sourcepkg.html#s-pkg-srcsubstvars" rel="subsection" title="C.2.3 debian/substvars and variable substitutions">
<link href="ap-pkg-sourcepkg.html#sC.2.4" rel="subsection" title="C.2.4 debian/files">
<link href="ap-pkg-sourcepkg.html#sC.2.5" rel="subsection" title="C.2.5 debian/tmp">
<link href="ap-pkg-controlfields.html#s-pkg-f-Filename" rel="subsection" title="D.2.1 Filename and MSDOS-Filename">
<link href="ap-pkg-controlfields.html#s-pkg-f-Size" rel="subsection" title="D.2.2 Size and MD5sum">
<link href="ap-pkg-controlfields.html#s-pkg-f-Status" rel="subsection" title="D.2.3 Status">
<link href="ap-pkg-controlfields.html#s-pkg-f-Config-Version" rel="subsection" title="D.2.4 Config-Version">
<link href="ap-pkg-controlfields.html#s-pkg-f-Conffiles" rel="subsection" title="D.2.5 Conffiles">
Ubuntu Policy Manual
Chapter 3 - Binary packages
The Ubuntu distribution is based on the Debian package management system,
called dpkg.
Thus, all packages in the Ubuntu distribution must
be provided in the .deb file format.
3.1 The package name
Every package must have a name that's unique within the Ubuntu archive.
The package name is included in the control field Package, the
format of which is described in Package, Section
The package name is also included as a part of the file name of the
.deb file.
3.2 The version of a package
Every package has a version number recorded in its Version control
file field, described in Version, Section
The package management system imposes an ordering on version numbers, so that
it can tell whether packages are being up- or downgraded and so that package
system front end applications can tell whether a package it finds available is
newer than the one installed on the system.
The version number format has the
most significant parts (as far as comparison is concerned) at the beginning.
If an upstream package has problematic version numbers they should be converted
to a sane form for use in the Version field.
3.2.1 Version numbers based on dates
In general, Ubuntu packages should use the same version numbers as the upstream
However, in some cases where the upstream version number is based on a date
(e.g., a development &snapshot& release) the package management
system cannot handle these version numbers without epochs.
For example, dpkg
will consider &96May01& to be greater than &96Dec24&.
To prevent having to use epochs for every new upstream version, the date based
portion of the version number should be changed to the following format in such
cases: &&, &&.
It is up to the maintainer
whether they want to bother the upstream maintainer to change the version
numbers upstream, too.
Note that other version formats based on dates which are parsed correctly by
the package management system should not be changed.
Native Debian or Ubuntu packages (i.e., packages which have been written
especially for Debian or Ubuntu) whose version numbers include dates should
always use the &YYYYMMDD& format.
3.3 The maintainer of a package
Every package must have a Debian maintainer (the maintainer may be one person
or a group of people reachable from a common email address, such as a mailing
The maintainer is responsible for ensuring that the package is placed
in the appropriate distributions.
The maintainer must be specified in the Maintainer control field
with their correct name and a working email address.
If one person maintains
several packages, they should try to avoid having different forms of their name
and email address in the Maintainer fields of those packages.
The format of the Maintainer control field is described in Maintainer, Section
If the maintainer of a package quits from the Debian project, &Debian QA
Group& packages@qa.debian.org takes
over the maintainer-ship of the package until someone else volunteers for that
These packages are called orphaned packages.[8]
Ubuntu: Packages that are modified in Ubuntu should have an Ubuntu-specific
Maintainer field.[]
All Ubuntu binary packages, and Ubuntu source packages that are modified
relative to Debian (that is, its version number contains the string
&ubuntu&), should have their Maintainer field adjusted
as follows:
If the Maintainer field contains an < email
address, or one associated with an Ubuntu developer, then no modifications
should be made.
If the package is in main or restricted, the
Maintainer field should be set to Ubuntu Core Developers ubuntu-devel-discuss@.
If the package is in universe or multiverse, the
Maintainer field should be set to Ubuntu MOTU Developers ubuntu-motu@.
If the Maintainer field is modified, then the old value must be
saved in a field named XSBC-Original-Maintainer.
Because it is
mandated and very common, it is not necessary or appropriate to document this
change in debian/changelog, unless it is the only change involved
in the upload.
3.4 The description of a package
Every Ubuntu package must have an extended description stored in the
appropriate field of the control record.
The technical information about the
format of the Description field is in Description, Section
The description should describe the package (the program) to a user (system
administrator) who has never met it before so that they have enough information
to decide whether they want to install it.
This description should not just be
copied verbatim from the program's documentation.
Put important information first, both in the synopsis and extended description.
Sometimes only the first part of the synopsis or of the description will be
displayed.
You can assume that there will usually be a way to see the whole
extended description.
The description should also give information about the significant dependencies
and conflicts between this package and others, so that the user knows why these
dependencies and conflicts have been declared.
Instructions for configuring or using the package should not be included (that
is what installation scripts, manual pages, info files, etc., are for).
Copyright statements and other administrivia should not be included either
(that is what the copyright file is for).
3.4.1 The single line synopsis
The single line synopsis should be kept brief - certainly under 80 characters.
Do not include the package name in the synopsis line.
The display software
knows how to display this already, and you do not need to state it.
that in many situations the user may only see the synopsis line - make it as
informative as you can.
3.4.2 The extended description
Do not try to continue the single line synopsis into the extended description.
This will not work correctly when the full description is displayed, and makes
no sense where only the summary (the single line synopsis) is available.
The extended description should describe what the package does and how it
relates to the rest of the system (in terms of, for example, which subsystem it
is which part of).
The description field needs to make sense to anyone, even people who have no
idea about any of the things the package deals with.[10]
3.5 Dependencies
Every package must specify the dependency information about other packages that
are required for the first to work correctly.
For example, a dependency entry must be provided for any shared libraries
required by a dynamically-linked executable binary in a package.
Packages are not required to declare any dependencies they have on other
packages which are marked Essential (see below), and should not do
so unless they depend on a particular version of that package.[11]
Sometimes, a package requires another package to be installed and
configured before it can be installed.
In this case, you must specify a
Pre-Depends entry for the package.
You should not specify a Pre-Depends entry for a package before
this has been discussed on the ubuntu-devel mailing list and a
consensus about doing that has been reached.
The format of the package interrelationship control fields is described in Declaring relationships between packages, Chapter
3.6 Virtual packages
Sometimes, there are several packages which offer more-or-less the same
functionality.
In this case, it's useful to define a virtual package
whose name describes that common functionality.
(The virtual packages only
exist logically, that's why they are called virtual.)
The packages with this particular function will then provide the
virtual package.
Thus, any other package requiring that function can simply
depend on the virtual package without having to specify all possible packages
individually.
All packages should use virtual package names where appropriate, and arrange to
create new ones if necessary.
They should not use virtual package names
(except privately, amongst a cooperating group of packages) unless they have
been agreed upon and appear in the list of virtual package names.
(See also Virtual packages -
Provides, Section 7.5)
The latest version of the authoritative list of virtual package names can be
found in the debian-policy package.
It is also available from the
Debian web mirrors at /doc/packaging-manuals/virtual-package-names-list.txt.
The procedure for updating the list is described in the preface to the list.
3.7 Base system
The base system is a minimum subset of the Ubuntu system that is
installed before everything else on a new system.
Only very few packages are
allowed to form part of the base system, in order to keep the required disk
usage very small.
The base system consists of all those packages with priority
required or important.
Many of them will be tagged
essential (see below).
3.8 Essential packages
Essential is defined as the minimal set of functionality that must be available
and usable on the system at all times, even when packages are in an
unconfigured (but unpacked) state.
Packages are tagged essential
for a system using the Essential control file field.
The format
of the Essential control field is described in Essential, Section
Since these packages cannot be easily removed (one has to specify an extra
force option to dpkg to do so), this flag must not be
used unless absolutely necessary.
A shared library package must not be tagged
essential; dependencies will prevent its premature removal, and we
need to be able to remove it when it has been superseded.
Since dpkg will not prevent upgrading of other packages while an
essential package is in an unconfigured state, all
essential packages must supply all of their core functionality
even when unconfigured.
If the package cannot satisfy this requirement it must
not be tagged as essential, and any packages depending on this package must
instead have explicit dependency fields as appropriate.
Maintainers should take great care in adding any programs, interfaces, or
functionality to essential packages.
Packages may assume that
functionality provided by essential packages is always available
without declaring explicit dependencies, which means that removing
functionality from the Essential set is very difficult and is almost never
Any capability added to an essential package therefore
creates an obligation to support that capability as part of the Essential set
in perpetuity.
You must not tag any packages essential before this has been
discussed on the ubuntu-devel mailing list and a consensus about
doing that has been reached.
3.9 Maintainer Scripts
The package installation scripts should avoid producing output which is
unnecessary for the user to see and should rely on dpkg to stave
off boredom on the part of a user installing many packages.
This means,
amongst other things, using the --quiet option on
install-info.
Errors which occur during the execution of an installation script must be
checked and the installation must not continue after an error.
Note that in general
applies to package maintainer scripts, too.
You should not use dpkg-divert on a file belonging to another
package without consulting the maintainer of that package first.
All packages which supply an instance of a common command name (or, in general,
filename) should generally use update-alternatives, so that they
may be installed together.
If update-alternatives is not used,
then each package must use Conflicts to ensure that other packages
are de-installed.
(In this case, it may be appropriate to specify a conflict
against earlier versions of something that previously did not use
update-alternatives; this is an exception to the usual rule that
versioned conflicts should be avoided.)
3.9.1 Prompting in maintainer scripts
Package maintainer scripts may prompt the user if necessary.
Prompting must be
done by communicating through a program, such as debconf, which
conforms to the Debian Configuration Management Specification, version 2 or
Packages which are essential, or which are dependencies of essential packages,
may fall back on another prompting method if no such interface is available
when they are executed.
The Debian Configuration Management Specification is included in the
debconf_specification files in the debian-policy
It is also available from the Debian web mirrors at /doc/packaging-manuals/debconf_specification.html.
Packages which use the Debian Configuration Management Specification may
contain an additional config script and a templates
file in their control archive[].
The config script might be run before the preinst
script, and before the package is unpacked or any of its dependencies or
pre-dependencies are satisfied.
Therefore it must work using only the tools
present in essential packages.[]
Packages which use the Debian Configuration Management Specification must allow
for translation of their user-visible messages by using a gettext-based system
such as the one provided by the po-debconf package.
Packages should try to minimize the amount of prompting they need to do, and
they should ensure that the user will only ever be asked each question once.
This means that packages should try to use appropriate shared configuration
files (such as /etc/papersize and /etc/news/server),
and shared debconf variables rather than each prompting for their
own list of required pieces of information.
It also means that an upgrade should not ask the same questions again, unless
the user has used dpkg --purge to remove the package's
configuration.
The answers to configuration questions should be stored in an
appropriate place in /etc so that the user can modify them, and
how this has been done should be documented.
If a package has a vitally important piece of information to pass to the user
(such as &don't run me as I am, you must edit the following configuration
files first or you risk your system emitting badly-formatted messages&),
it should display this in the config or postinst
script and prompt the user to hit return to acknowledge the message.
messages do not count as vitally important (they belong in
/usr/share/doc/package/copyright); neither do
instructions on how to use a program (these should be in on-line documentation,
where all the users can see them).
Any necessary prompting should almost always be confined to the
config or postinst script.
If it is done in the
postinst, it should be protected with a conditional so that
unnecessary prompting doesn't happen if a package's installation fails and the
postinst is called with abort-upgrade,
abort-remove or abort-deconfigure.
Ubuntu Policy Manual
version 3.8.2.0ubuntu1,}

我要回帖

更多关于 dynamically 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信