File: parallel-installability.page

package info (click to toggle)
gnome-devel-docs 40.3-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 79,188 kB
  • sloc: javascript: 2,514; xml: 2,407; ansic: 2,229; python: 1,854; makefile: 805; sh: 499; cpp: 131
file content (319 lines) | stat: -rw-r--r-- 21,317 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
<?xml version="1.0" encoding="utf-8"?>
<page xmlns="http://projectmallard.org/1.0/" xmlns:its="http://www.w3.org/2005/11/its" type="topic" id="parallel-installability" xml:lang="ko">

  <info>
    <link type="guide" xref="index#maintainer-guidelines"/>

    <credit type="author copyright">
      <name>Havoc Pennington</name>
      <email its:translate="no">hp@pobox.com</email>
      <years>2002</years>
      <!-- Heavily based off Havoc’s original article about parallel
           installability: http://ometer.com/parallel.html.
           License CC-BY-SA 3.0 confirmed by e-mail with him. -->
    </credit>
    <credit type="author copyright">
      <name>Philip Withnall</name>
      <email its:translate="no">philip.withnall@collabora.co.uk</email>
      <years>2015</years>
    </credit>

    <include xmlns="http://www.w3.org/2001/XInclude" href="cc-by-sa-3-0.xml"/>

    <desc>동시 설치 방식으로 나중에 검증할 라이브러리를 작성합니다</desc>
  
    <mal:credit xmlns:mal="http://projectmallard.org/1.0/" type="translator copyright">
      <mal:name>조성호</mal:name>
      <mal:email>shcho@gnome.org</mal:email>
      <mal:years>2016-2018.</mal:years>
    </mal:credit>
  </info>

  <title>동시 설치 가능성</title>

  <synopsis>
    <title>요약</title>

    <p>두 패키지를 동시에 설치할 수 있다면, 일반적인 파일 이름이 붙어있지 않으며 패키지를 개발한 사람은 원하는 버전에 따라 컴파일합니다. 이 방식은 헤더 파일, 라이브러리 이진 파일에 적용하는 방식대로 데몬, 유틸리티 프로그램, 설정 파일에 적용합니다.</p>

    <list>
      <item><p>모든 라이브러리 버전을 동시에 설치할 수 있는지 확인하십시오(<link xref="#justification"/>).</p></item>
      <item><p>라이브러리로 설치한 모든 파일에 버전을 부여하십시오(<link xref="#solution"/>).</p></item>
      <item><p>so 이름 또는 libtool 버전 번호와는 별개로 패키지 버전 번호를 관리하십시오. 어떤 패키지 버전 번호 부분이 API와 바뀌는지 분명히 하십시오(<link xref="#version-numbers"/>).</p></item>
      <item><p><file><var>$(includedir)</var>/lib<var>library</var>-<var>version</var>/<var>library</var>/</file>에 C 헤더 파일을 설치하십시오(<link xref="#header-files"/>).</p></item>
      <item><p><file><var>$(libdir)</var>/lib<var>library</var>-<var>version</var>.so.<var>soname</var></file>에 라이브러리 파일을 설치하십시오(<link xref="#libraries"/>).</p></item>
      <item><p><file><var>$(libdir)</var>/pkgconfig/<var>library</var>-<var>version</var>.pc</file>에 pkg-config 파일을 설치하십시오(<link xref="#pkg-config"/>).</p></item>
      <item><p>설정 파일을 전후 호환성에 맞추든지 <file><var>$(sysconfdir)</var>/<var>library</var>-<var>version</var>/</file>에 설치하십시오(<link xref="#configuration-files"/>).</p></item>
      <item><p><code>GETTEXT_PACKAGE</code> 변수 값을 <code><var>library</var>-<var>version</var></code>에 설정하십시오(<link xref="#gettext"/>).</p></item>
      <item><p>모든 D-Bus 인터페이스 이름, 서비스 이름, 객체 경로에 버전 번호를 넣으십시오. 이를 테면 <code>org.domain.<var>Library</var><var>Version</var>.<var>Interface</var></code>, <code>org.domain.<var>Library</var><var>Version</var></code>, <code>/org/domain/<var>Library</var><var>Version</var>/</code> 과 같이 넣으십시오(<link xref="#dbus"/>).</p></item>
      <item><p>데몬 바이너리를 <file><var>$(libexecdir)</var>/<var>library</var>-daemon-<var>version</var></file>에 설치하십시오(<link xref="#programs"/>).</p></item>
      <item><p>유틸리티 바이너리를 <file><var>$(bindir)</var>/<var>library</var>-utility-<var>version</var></file> and install symbolic links to <file><var>$(bindir)</var>/<var>library</var>-utility</file>에 설치하십시오(<link xref="#programs"/>).</p></item>
    </list>
  </synopsis>

  <section id="justification">
    <title>명분</title>

    <p>모든 공개 라이브러리는 라이브러리의 생명 주기 이후 API 구조 변경이 쉽게 함께 설치할 수 있도록 설계해야합니다. 라이브러리를 여러 프로젝트에서 사용하는 상황에서 API 구조를 깨야 한다면, 모든 프로젝트를 동시에 설치한 새 API에 맞춰 이식해야 하며, 이렇게 하지 않으면 일부 프로젝트는 의존 관계상 라이브러리 버전이 맞지 않는 문제로 더이상 라이브러리와 설치할 수 없습니다.</p>

    <p>이 상태가 바로 관리할 수 없는 상태이며, 대부분의 API가 이식의 동기가 될 눈에 띄는 새 기능을 넣지 않기에, 모든 프로젝트에 새 API에 맞춰 동시에 이식을 요청하기 어렵고, 이식의 의욕을 꺾어버립니다.</p>

    <p>API의 이전 버전과 새 버전을 동시에 설치하고 컴파일 할 수 있게끔 모든 라이브러리를 동시에 설치할 수 있게 했는지 확인하면 이 문제가 처리됩니다. 동시에 설치할 수 있게 빌드하면, 굳이 근본 부분을 건드리지 않고도 프로젝트의 시작단계를 쉽게 처리할 수 있습니다.</p>

    <p>이 해결 방식은 또한 라이브러리의 어떤 버전과 그 다음 버전을 설치하는 문제에서 여러 프로그램을 이식하는 ‘닭이 먼저냐 달걀이 먼저냐’의 문제를 해결하며, 라이브러리 관리 집단이 원한다면 개발 주기를 더 빠르게 진행할 수 있으며 개발 과정상 새 기능을 넣을 수 있도록 API 구조를 훨씬 쉽게 바꿀 수 있습니다.</p>

    <p>이와 동일한 라이브러리 대상 해결책은 API 구조를 그냥 안바꾸는 방법입니다. 이 접근 방식은 <code>libc</code>에서 왔습니다.</p>
  </section>

  <section id="solution">
    <title>해결책</title>

    <p>문제 해결책은 근본적으로 라이브러리의 이름을 바꾸는 방식이며, 대부분의 경우 모든 파일을 설치하는 경로의 버전 번호를 넣는 방식입니다. 이는 라이브러리의 여러 버전을 동시에 설치할 수 있다는 의미입니다.</p>

    <p>예를 들어 <code>Foo</code> 라이브러리에서 기존에 설치한 파일이 다음과 같다고 하겠습니다:</p>
    <list>
      <item><p><file>/usr/include/foo.h</file></p></item>
      <item><p><file>/usr/include/foo-utils.h</file></p></item>
      <item><p><file>/usr/lib/libfoo.so</file></p></item>
      <item><p><file>/usr/lib/pkgconfig/foo.pc</file></p></item>
      <item><p><file>/usr/share/doc/foo/foo-manual.txt</file></p></item>
      <item><p><file>/usr/bin/foo-utility</file></p></item>
    </list>

    <p>이 파일을 설치하려면 위 대신 <code>Foo</code> 버전 4로 수정해야합니다:</p>
    <list>
      <item><p><file>/usr/include/foo-4/foo/foo.h</file></p></item>
      <item><p><file>/usr/include/foo-4/foo/utils.h</file></p></item>
      <item><p><file>/usr/lib/libfoo-4.so</file></p></item>
      <item><p><file>/usr/lib/pkgconfig/foo-4.pc</file></p></item>
      <item><p><file>/usr/share/doc/foo-4/foo-manual.txt</file></p></item>
      <item><p><file>/usr/bin/foo-utility-4</file></p></item>
    </list>

    <p>수정하고 나면 버전 5로 동시에 설치할 수 있습니다:</p>
    <list>
      <item><p><file>/usr/include/foo-5/foo/foo.h</file></p></item>
      <item><p><file>/usr/include/foo-5/foo/utils.h</file></p></item>
      <item><p><file>/usr/lib/libfoo-5.so</file></p></item>
      <item><p><file>/usr/lib/pkgconfig/foo-5.pc</file></p></item>
      <item><p><file>/usr/share/doc/foo-5/foo-manual.txt</file></p></item>
      <item><p><file>/usr/bin/foo-utility-5</file></p></item>
    </list>

    <p><link href="http://www.freedesktop.org/wiki/Software/pkg-config/"> <cmd>pkg-config</cmd></link>에서 쉽게 기능을 빌려 쓸 수 있습니다. <file>foo-4.pc</file> 파일은 include 경로에 <file>/usr/include/foo-4</file> 경로를 추가하고 링크할 라이브러리 목록에 <file>libfoo-4.so</file> 파일을 추가합니다. <file>foo-5.pc</file> 파일은 <file>/usr/include/foo-5</file> 경로와 <file>libfoo-5.so</file> 파일을 추가합니다.</p>
  </section>

  <section id="version-numbers">
    <title>버전 번호</title>

    <p>파일 이름에 붙은 버전 번호는 <em>ABI/API</em> 버전입니다. 패키지의 전체 버전 번호는 아닙니다. API 유지 상태가 깨졌는지 여부를 나타내는 부분일 뿐입니다. 프로젝트 버전 부여시 <code><var>주</var>.<var>부</var>.<var>마이크로</var></code> 표준 버전 부여 형식을 사용한다면 API 버전은 보통 주 버전 번호입니다.</p>

    <p>부 버전 출시판(보통 API를 추가하지만 바꾸거나 제거하지 <em>않음</em>)과 마이크로 버전 출시판(보통 버그 수정)은 <link xref="api-stability">API 이전 호환성</link>에 영향을 주지 않으므로 모든 파일을 옮길 필요가 없습니다.</p>

    <p>다음 부분의 예제는 다음 코드를 활용하여 <file>configure.ac</file> 파일에서 API 버전과 so 이름을 내보낸다고 가정합니다:</p>
    <listing>
      <title>autoconf의 API 버전 부여</title>
      <desc><file>configure.ac</file> 파일에 API 버전 및 so 이름을 내보낼 코드를 작성하십시오</desc>
      <code># Before making a release, the <var>LIBRARY</var>_LT_VERSION string should be modified.
# The string is of the form c:r:a. Follow these instructions sequentially:
#
#  1. If the library source code has changed at all since the last update,
#     then increment revision (‘c:r:a’ becomes ‘c:r+1:a’).
#  2. If any interfaces have been added, removed, or changed since the last update,
#     increment current, and set revision to 0.
#  3. If any interfaces have been added since the last public release,
#     then increment age.
#  4. If any interfaces have been removed or changed since the last public release,
#     then set age to 0.
AC_SUBST([<var>LIBRARY</var>_LT_VERSION],[1:0:0])

AC_SUBST([<var>LIBRARY</var>_API_VERSION],[4])</code>
    </listing>
  </section>

  <section id="header-files">
    <title>C 헤더 파일</title>

    <p>헤더 파일은 C 컴파일러의 <cmd>-I</cmd> 플래그가 요구하는 버전이 붙은 하위 디렉터리에 항상 설치해야합니다. 예를 들어, <file>foo.h</file> 헤더 파일이 있다면 프로그램에서는 다음과 같이 씁니다:</p>
    <code mime="text/x-csrc">#include &lt;foo/foo.h&gt;</code>
    <p>그 다음 이 파일을 설치하겠습니다:</p>
    <list>
      <item><p><file>/usr/include/foo-4/foo/foo.h</file></p></item>
      <item><p><file>/usr/include/foo-5/foo/foo.h</file></p></item>
    </list>

    <p>프로그램에서는 <cmd>-I/usr/include/foo-4</cmd> 또는 <cmd>-I/usr/include/foo-5</cmd> 플래그를 C 컴파일러에 보내야합니다. 다시 말하지만, <cmd>pkg-config</cmd>를 활용하면 됩니다.</p>

    <p><file>foo/</file> 추가 하위 디렉터리를 살펴보십시오. 다른 라이브러리의 파일 이름이 겹치는 일을 피하도록 <code mime="text/x-csrc">#include</code> 절에 이름 영역을 부여합니다. 예를 들자면, 서로 다른 두 라이브러리에서 <file>utils.h</file> 헤더 파일을 설치한다면 <code mime="text/x-csrc">#include &lt;utils.h&gt;</code> 헤더를 사용할 때 무얼 넣을까요?</p>

    <p>어떤 하위 디렉터리 외에 있는 헤더 파일 중 하나를 두어야 할 지 망설임이 옵니다:</p>
    <list>
      <item><p><file>/usr/include/foo.h</file></p></item>
      <item><p><file>/usr/include/foo-5/foo.h</file></p></item>
    </list>

    <p>문제는 사용자가 언제나 부주의하게 잘못된 헤더를 참조하는데, 컴파일 명령행에 <cmd>-I/usr/include</cmd>를 넣는걸 규칙인 것 처럼 생각하기 때문입니다. 만약 이렇게 해야 한다면, 최소한 라이브러리를 초기화할 때 잘못된 헤더 파일을 사용하여 프로그램을 감지하는 라이브러리가 있는지 검사하는 부분을 추가하십시오.</p>

    <p>버전을 부여한 헤더 파일은 다음 코드로 automake에서 설치할 수 있습니다:</p>
    <listing>
      <title>automake의 헤더 파일 처리</title>
      <desc><file>Makefile.am</file> 파일에 버전을 부여한 헤더 파일을 설치할 코드를 작성하십시오</desc>
      <code><var>library</var>includedir = $(includedir)/lib<var>library</var>-@<var>LIBRARY</var>_API_VERSION@/<var>library</var>
<var>library</var>_headers = \
	lib<var>library</var>/example1.h \
	lib<var>library</var>/example2.h \
	$(NULL)

# The following headers are private, and shouldn't be installed:
private_headers = \
	lib<var>library</var>/example-private.h \
	$(NULL)
# The main header simply #includes all other public headers:
main_header = lib<var>library</var>/<var>library</var>.h
public_headers = \
	$(main_header) \
	$(<var>library</var>_headers) \
	$(NULL)

<var>library</var>include_HEADERS = $(public_headers)</code>
    </listing>

    <p>버전을 올바르게 부여하는 것처럼, 설치한 헤더에 있는 모든 API의 <link xref="namespacing">공간 이름을 올바르게 부여</link>해야합니다.</p>
  </section>

  <section id="libraries">
    <title>라이브러리</title>

    <p>라이브러리 객체 파일은 다음과 같이 버전을 붙인 이름을 달고 있어야합니다:</p>
    <list>
      <item><p><file>/usr/lib/libfoo-4.so</file></p></item>
      <item><p><file>/usr/lib/libfoo-5.so</file></p></item>
    </list>

    <p>이 과정으로 컴파일을 진행하는 동안 원하는 프로그램이 제대로 나오며, 일반적으로 버전 4 및 버전 5에 파일이 없는지 확인합니다.</p>

    <p>버전을 매긴 라이브러리는 다음 코드로 automake에서 빌드하고 설치할 수 있습니다:</p>
    <listing>
      <title>automake의 라이브러리 처리</title>
      <desc><file>Makefile.am</file>에 버전을 매긴 파일을 빌드하고 설치하는 코드를 작성하십시오</desc>
      <code>lib_LTLIBRARIES = lib<var>library</var>/lib<var>library</var>-@<var>LIBRARY</var>_API_VERSION@.la

lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_SOURCES = \
	$(private_headers) \
	$(<var>library</var>_sources) \
	$(NULL)
lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_CPPFLAGS = …
lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_CFLAGS = …
lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_LIBADD = …
lib<var>library</var>_lib<var>library</var>_@<var>LIBRARY</var>_API_VERSION@_la_LDFLAGS = \
	-version-info $(<var>LIBRARY</var>_LT_VERSION) \
	$(AM_LDFLAGS) \
	$(NULL)</code>
    </listing>

    <section id="library-sonames">
      <title>라이브러리 so 이름</title>

      <p>라이브러리 so 이름(libtool 버전 번호로도 알려짐)은 앞서 컴파일한 프로그램을 연결하는 실행시 문제만을 해결합니다. 이전 버전에서 필요한 프로그램을 컴파일하는 문제를 바로잡을 수 없으며, 다른 라이브러리의 문제는 바로 잡지 않습니다.</p>

      <p>이 때문에, so 이름을 활용하지만, <em>추가로</em> 라이브러리의 이름에 버전을 붙입니다. 각각의 문제를 두가지 해결책으로 바로 잡습니다.</p>
    </section>
  </section>

  <section id="pkg-config">
    <title>pkg-config 파일</title>

    <p>다음과 같이 pkg-config 파일에 버전을 매긴 이름을 넣어야합니다:</p>
    <list>
      <item><p><file>/usr/lib/pkgconfig/foo-4.pc</file></p></item>
      <item><p><file>/usr/lib/pkgconfig/foo-5.pc</file></p></item>
    </list>

    <p>각각의 pkg-config 파일에 라이브러리 이름과 수반 경로의 버전 정보가 있기 때문에 라이브러리에 의존하는 어떤 프로젝트든지간에 <file>foo-4</file> 파일에서 <file>foo-5</file> 파일로 pkg-config check를 바꾸(고 API 이식 필요 과정을 진행하)는 방법만으로 버전을 바꿀 수 있어야합니다.</p>

    <p>버전을 부여한 pkg-config 파일은 다음 코드로 autoconf 및 automake에서 설치할 수 있어야합니다:</p>
    <listing>
      <title>autoconf와 automake의 pkg-config 파일 처리</title>
      <desc><file>configure.ac</file>파일과 <file>Makefile.am</file> 파일에 버전을 부여한 pkg-config 파일을 설치하는 코드를 작성하십시오</desc>

      <code>AC_CONFIG_FILES([
lib<var>library</var>/<var>library</var>-$<var>LIBRARY</var>_API_VERSION.pc:lib<var>library</var>/<var>library</var>.pc.in
],[],
[<var>LIBRARY</var>_API_VERSION='$<var>LIBRARY</var>_API_VERSION'])</code>

      <code># Note that the template file is called <var>library</var>.pc.in, but generates a
# versioned .pc file using some magic in AC_CONFIG_FILES.
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = lib<var>library</var>/<var>library</var>-$(<var>LIBRARY</var>_API_VERSION).pc

DISTCLEANFILES += $(pkgconfig_DATA)
EXTRA_DIST += lib<var>library</var>/<var>library</var>.pc.in</code>
    </listing>
  </section>

  <section id="configuration-files">
    <title>설정 파일</title>

    <p>사용자 관점에서, <link xref="api-stability">전후 호환성</link>(정확히 동일한 설정 파일 및 문맥을 각 라이브러리 버전에서 이해)에 따라 설정 파일 형식을 유지하는게 좋습니다. 그 다음 동일한 설정 파일을 모든 라이브러리 버전에서 활용할 수 있으며, 설정 파일 자체를 버전 관리할 필요가 없습니다.</p>

    <p>이렇게 할 수 있다면, 간단하게 설정 파일의 이름을 바꿔야 하며, 사용자는 각 라이브러리 버전 별로 따로 설정해야합니다.</p>
  </section>

  <section id="gettext">
    <title>gettext 번역</title>

    <p>autoconf와 automake의 번역 기반으로 gettext를 사용한다면 보통 <file>/usr/share/locale/<var>lang</var>/LC_MESSAGES/<var>package</var></file> 경로에 번역 파일을 설치합니다. 여기서 <var>package</var> 변수를 추가해야합니다. 그놈에서는 <file>configure.ac</file>에 이 변수를 넣는 방식을 활용합니다:</p>

    <code>GETTEXT_PACKAGE=foo-4
AC_SUBST([GETTEXT_PACKAGE])
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"])</code>

    <p>그 다음 <code mime="text/x-csrc">bindtextdomain()</code>, <code mime="text/x-csrc">textdomain()</code>, <code mime="text/x-csrc">dgettext()</code>에 패키지 이름을 전달할 목적으로 <code>GETTEXT_PACKAGE</code>를 활용합니다.</p>
  </section>

  <section id="dbus">
    <title>D-Bus 인터페이스</title>

    <p>D-Bus 인터페이스는 컴파일 시간이 아닌 실행 시간에 버전 관리를 처리할 때를 제외하고는 C API와 유사한 API의 한 유형입니다. D-Bus 인터페이스 버전 부여는 다른 C API와 별반 차이가 없습니다. 버전 숫자는 인터페이스 이름, 서비스 이름, 객체 경로에 있어야합니다.</p>

    <p>이를테면, 다음과 같이 <code>org.example.Foo</code> 서비스에는 <code>Controller</code>와 <code>Client</code>의 <code>A</code> 와 <code>B</code>, D-Bus API 버전 4와 5가 나타나야합니다:</p>
    <list>
      <title>서비스 이름</title>
      <item><p><code>org.example.Foo4</code></p></item>
      <item><p><code>org.example.Foo5</code></p></item>
    </list>
    <list>
      <title>인터페이스 이름</title>
      <item><p><code>org.example.Foo4.InterfaceA</code></p></item>
      <item><p><code>org.example.Foo4.InterfaceB</code></p></item>
      <item><p><code>org.example.Foo5.InterfaceA</code></p></item>
      <item><p><code>org.example.Foo5.InterfaceB</code></p></item>
    </list>
    <list>
      <title>객체 경로</title>
      <item><p><code>/org/example/Foo4/Controller</code></p></item>
      <item><p><code>/org/example/Foo4/Client</code></p></item>
      <item><p><code>/org/example/Foo5/Controller</code></p></item>
      <item><p><code>/org/example/Foo5/Client</code></p></item>
    </list>
  </section>

  <section id="programs">
    <title>프로그램, 데몬, 유틸리티</title>

    <p>데스크톱 프로그램은 보통 다른 모듈과 의존 관계가 없기 때문에 버전을 매길 필요가 없습니다. 그러나 데몬과 유틸리티 프로그램은 시스템의 다른 부분과 함께 동작하므로 버전을 매겨야 합니다.</p>

    <p>다음의 데몬 및 유틸리티 프로그램을:</p>
    <list>
      <item><p><file>/usr/libexec/foo-daemon</file></p></item>
      <item><p><file>/usr/bin/foo-lookup-utility</file></p></item>
    </list>
    <p>다음과 같이 버전을 부여합니다:</p>
    <list>
      <item><p><file>/usr/libexec/foo-daemon-4</file></p></item>
      <item><p><file>/usr/bin/foo-lookup-utility-4</file></p></item>
    </list>

    <p>사용자가 편리하게 쓸 수 있게 <file>/usr/bin/foo-lookup-utility</file>를 유틸리티의 추천 버전 사본으로 심볼릭 링크 사본을 설치하고 싶을 수도 있습니다.</p>
  </section>
</page>