免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: haoji
打印 上一主题 下一主题

The Art of Unix Programming [复制链接]

论坛徽章:
0
461 [报告]
发表于 2008-05-18 05:35 |只看该作者
Chapter 17. Open Source

Home Best practices for working with
open-source developers

论坛徽章:
0
462 [报告]
发表于 2008-05-18 05:35 |只看该作者
Best practices for working with open-source developers

Prev Chapter 17. Open Source

Next



Best practices for working with open-source developers

Much of what constitutes best practice in the open-source community is a natural adaptation to distributed
development; you'll read a lot in the rest of this chapter about behaviors that maintain good communication with
other developers. Where Unix conventions are arbitrary (such is the standard names of files that convey meta-
information about a source distribution) they often trace back either to Usenet in the early 1980s, or the
conventions and standards of the GNU project .

Good patching practice

Most people get involved in open-source software by writing patches for other peoples' software before releasing
projects of their own. Suppose you've written a set of source-code changes for someone else's baseline code. Now
put yourself in that person's shoes. How is he to judge whether to include the patch?

It is very difficult to judge the quality of code. So developers tend to evaluate patches by the quality of the
submission. They look for clues in the submitter's style and communications behavior instead 鈥

论坛徽章:
0
463 [报告]
发表于 2008-05-18 05:36 |只看该作者
As a patch submitter, it is your responsibility to track the state of the source and send the maintainer a minimal
patch that expresses what you want done to the main-line codebase. That means sending a patch against the current
version.

Don't include patches for generated files.

Before you send your patch, walk through it and delete any patch bands for files in it that are going to be
automatically regenerated once he applies the patch and remakes. The classic examples of this error are C files
generated by Bison or Flex.

These days the most common mistake of this kind is sending a diff with a huge band that is nothing but changebars
between your configure script and his. This file is generated by autoconf.

This is inconsiderate. It means your recipient is put to the trouble of separating the real content of the patch from a
lot of bulky noise. It's a minor error, not as important as some of the things we'll get to further on 鈥

论坛徽章:
0
464 [报告]
发表于 2008-05-18 05:36 |只看该作者
software.

Good documentation is usually the most visible sign of what separates a solid contribution from a quick and dirty
hack. If you take the time and care necessary to produce it, you'll find you're already 85% of the way to having
your patch accepted with most developers.

Do include an explanation with your patch

Your patch should include cover notes explaining why you think the patch is necessary or useful. This is
explanation directed not to the users of the software but to the maintainer to whom you are sending the patch.

The note can be short 鈥

论坛徽章:
0
465 [报告]
发表于 2008-05-18 05:37 |只看该作者
This conveys no information. It's nothing but a muddy territorial bootprint you're planting in the middle of the
maintainer's code. If he takes your patch (which you've made less likely) he will almost certainly strip out this
comment. If you want a credit, include a patch band for the project NEWS or HISTORY file. He'll probably take
that.

Here's an example of a good comment:

/*
* This conditional needs to be guarded so that crunch_data()
* never gets passed a NULL pointer. <norman_newbie@foosite.com>
*/

This comment shows that you understand not only the maintainer's code but the kind of information that he needs
to have confidence in your changes. This kind of comment gives me confidence in your changes.

Good project- and archive- naming practice

As the load on maintainers of archives like Metalab, SourceForge, and CPAN increases, there is an increasing
trend for submissions to be processed partly or wholly by programs (rather than entirely by a human).

This makes it more important for project and archive-file names to fit regular patterns that computer programs can
parse and understand.

Use GNU-style names with a stem and major.minor.patch numbering.

It's helpful to everybody if your archive files all have GNU-like names -- all-lower-case alphanumeric stem prefix,
followed by a dash, followed by a version number, extension, and other suffixes.

Let's suppose you have a project you call 鈥榝oobar鈥

论坛徽章:
0
466 [报告]
发表于 2008-05-18 05:37 |只看该作者
This looks to many programs like an archive for a project called `foobar1' at version 2.3.
foobar-v1.2.3.tar.gz
Many programs think this goes with a project called `foobar-v1'.
foo_bar-1.2.3.tar.gz
The underscore is hard for people to speak, type, and remember.
FooBar-1.2.3.tar.gz
Unless you like looking like a marketing weenie. This is also hard for people to speak, type, and remember.


If you have to differentiate between source and binary archives, or between different kinds of binary, or express
some kind of build option in the file name, please treat that as a file extension to go after the version number. That
is, please do this:

foobar-1.2.3.src.tar.gz
sources
foobar-1.2.3.bin.tar.gz
binaries, type not specified
foobar-1.2.3.bin.ELF.tar.gz
ELF binaries
foobar-1.2.3.bin.ELF.static.tar.gz
ELF binaries statically linked
foobar-1.2.3.bin.SPARC.tar.gz
SPARC binaries


Please don't use names like 鈥榝oobar-ELF-1.2.3.tar.gz鈥

论坛徽章:
0
467 [报告]
发表于 2008-05-18 05:38 |只看该作者
3.
version number
4.
dot
5.
"src" or "bin" (optional)
6.
dot or dash (dot preferred)
7.
binary type and options (optional)
8.
archiving and compression extensions


But respect local conventions where appropriate

Some projects and communities have well-defined conventions for names and version numbers that aren't
necessarily compatible with the above advice. For instance, Apache modules are generally named like mod_foo,
and have both their own version number and the version of Apache with which they work. Likewise, Perl modules
have version numbers that can be treated as floating point numbers (e.g., you might see 1.303 rather than 1.3.3),
and the distributions are generally named Foo-Bar-1.303.tar.gz for version 1.303 of module Foo::Bar. (Perl itself,
on the other hand, switched to using the conventions described here in late 1999.)

Look for and respect the conventions of specialized communities and developers; for general use, follow the above
guidelines.

Try hard to choose a name prefix that is unique and easy to type

The stem prefix should be common to all a project's files, and it should be easy to read, type, and remember. So
please don't use underscores. And don't capitalize or BiCapitalize without extremely good reason 鈥

论坛徽章:
0
468 [报告]
发表于 2008-05-18 05:39 |只看该作者
they allow the package to adapt at compile-time to the environment it finds. This is critical as it allows the package
to run on platforms its developers have never seen, and it allows the software's community of users to do their own
ports. Only the largest of development teams can afford to buy all of the hardware and hire enough employees to
support even a limited number of platforms.

Therefore: use the GNU autotools to handle portability issues, do system-configuration probes, and tailor your
makefiles. People building from sources today expect to be able to type "configure; make; make install" and get a
clean build 鈥

论坛徽章:
0
469 [报告]
发表于 2008-05-18 05:39 |只看该作者
Spell-check your documentation, README files and error messages in your software. Sloppy code, code that
produces warning messages when compiled, and spelling errors in README files or error messages, leads users to
believe the engineering behind it is also haphazard and sloppy.

Recommended C/C++ portability practices

If you are writing C, feel free to use the full ANSI features. Specifically, do use function prototypes, which will
help you spot cross-module inconsistencies. The old-style K&R compilers are ancient history.

Do not assume compiler-specific features such as the GCC "-pipe" option or nested functions are available. These
will come around and bite you the second somebody ports to a non-Linux, non-GCC system.

Code required for portability should be isolated to a single area and a single set of source files (for example, an
"os" subdirectory). Compiler, library and operating system interfaces with portability issues should be abstracted to
files in this directory. This includes variables such as "errno", library interfaces such as "malloc", and operating
system interfaces such as "mmap".

Portability layers make it easier to do new software ports. It is often the case that no member of the development
team knows the porting platform (for example, there are literally hundreds of different embedded operating
systems, and nobody knows any significant fraction of them). By creating a separate portability layer it is possible
for someone who knows the port platform to port your software without having to understand it.

Portability layers simplify applications. Software rarely needs the full functionality of more complex system calls
such as mmap or stat, and programmers commonly configure such complex interfaces incorrectly. A portability
layer with abstracted interfaces ("__file_exists" instead of a call to stat) allows you to export only the limited,
necessary functionality from the system, simplifying the code in your application.

Always write your portability layer to select based on a feature, never based on a platform. Trying to create a
separate portability layer for each supported platform results in a multiple update problem maintenance nightmare.
A "platform" is always selected on at least two axes: the compiler and the library/operating system release. In some
cases there are three axes, as when Linux vendors select a C library independently of the operating system release.
With M vendors, N compilers and O operating system releases, the number of "platforms" quickly scales out of
reach of any but the largest development teams. By using language and systems standards such as ANSI and
POSIX 1003.1, the set of features is relatively constrained.

Portability choices can be made along either lines of code or compiled files. It doesn't make a difference if you
select alternate lines of code on a platform, or one of a few different files. A rule of thumb is to move portability
code for different platforms into separate files when the implementations diverged significantly (shared memory
mapping on Unix vs. Windows), and leave portability code in a single file when the differences are minimal (using
gettimeofday, clock_gettime, ftime or time to find out the current time-of-day).

Avoid using complex types such as "off_t" and "size_t". They vary in size from system to system, especially on 64-
bit systems. Limit your usage of "off_t" to the portability layer, and your usage of "size_t" to mean only the length
of a string in memory, and nothing else.

Never step on the namespace of any other part of the system, (including file names, error return values and
function names). Where the namespace is shared, document the portion of the namespace that you use.

论坛徽章:
0
470 [报告]
发表于 2008-05-18 05:40 |只看该作者
Choose a coding standard. The debate over the choice of standard can go on forever 鈥
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP