Print this page
4027 remove CLOSED_BUILD
4028 remove CLOSED_IS_PRESENT
4029 remove tonic build bits
Reviewed by: Andy Stormont <andyjstormont@gmail.com>
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/Makefile
+++ new/usr/src/lib/Makefile
1 1 #
2 2 # CDDL HEADER START
3 3 #
4 4 # The contents of this file are subject to the terms of the
5 5 # Common Development and Distribution License (the "License").
6 6 # You may not use this file except in compliance with the License.
7 7 #
8 8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 # or http://www.opensolaris.org/os/licensing.
10 10 # See the License for the specific language governing permissions
11 11 # and limitations under the License.
12 12 #
13 13 # When distributing Covered Code, include this CDDL HEADER in each
14 14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 # If applicable, add the following below this CDDL HEADER, with the
16 16 # fields enclosed by brackets "[]" replaced with your own identifying
17 17 # information: Portions Copyright [yyyy] [name of copyright owner]
18 18 #
19 19 # CDDL HEADER END
20 20 #
21 21
22 22 # Copyright 2011 Nexenta Systems, Inc. All rights reserved.
23 23 # Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 # Copyright (c) 2012 by Delphix. All rights reserved.
25 25 # Copyright (c) 2012, Joyent, Inc. All rights reserved.
26 26 # Copyright (c) 2013 Gary Mills
27 27
28 28 include ../Makefile.master
29 29
30 30 # Note that libcurses installs commands along with its library.
31 31 # This is a minor bug which probably should be fixed.
32 32 # Note also that a few extra libraries are kept in cmd source.
33 33 #
34 34 # Certain libraries are linked with, hence depend on, other libraries.
35 35 #
36 36 # Although we have historically used .WAIT to express dependencies, it
37 37 # reduces the amount of parallelism and thus lengthens the time it
↓ open down ↓ |
37 lines elided |
↑ open up ↑ |
38 38 # takes to build the libraries. Thus, we now require that any new
39 39 # libraries explicitly call out their dependencies. Eventually, all
40 40 # the library dependencies will be called out explicitly. See
41 41 # "Library interdependencies" near the end of this file.
42 42 #
43 43 # Aside from explicit dependencies (and legacy .WAITs), all libraries
44 44 # are built in parallel.
45 45 #
46 46 .PARALLEL:
47 47
48 -#
49 -# The $(CLOSED_BUILD) additions to SUBDIRS & MSGSUBDIRS are unfortunate,
50 -# but required due to the "dependencies" of using .WAIT to barrier the
51 -# parallel dmake builds. once 4631488 has been fixed, they can be
52 -# consolidated into one $(CLOSED_BUILD)SUBDIRS += (all closed libs) as
53 -# shown in HDRSUBDIRS
54 -#
55 48 SUBDIRS= \
56 49 common .WAIT \
57 50 ../cmd/sgs/libconv \
58 51 ../cmd/sgs/libdl .WAIT
59 52
60 53 SUBDIRS += \
61 54 libc .WAIT \
62 55 ../cmd/sgs/libelf .WAIT \
63 56 c_synonyms \
64 57 libmd \
65 58 libmd5 \
66 59 librsm \
67 60 libmp .WAIT \
68 61 libnsl \
69 62 libsecdb .WAIT \
70 63 librpcsvc \
71 64 libsocket .WAIT \
72 65 libsctp \
73 66 libsip \
74 67 libcommputil \
75 68 libresolv \
76 69 libresolv2 .WAIT \
77 70 libw .WAIT \
78 71 libintl .WAIT \
79 72 ../cmd/sgs/librtld_db \
80 73 libaio \
81 74 libast \
82 75 libdll \
83 76 libcmd \
84 77 libshell \
85 78 libsum \
86 79 librt \
87 80 libadm \
88 81 libctf \
89 82 libdtrace \
90 83 libdtrace_jni \
91 84 libcurses \
92 85 libtermcap \
93 86 libgen \
94 87 libgss \
95 88 libpam \
96 89 libuuid \
97 90 libthread \
98 91 libpthread .WAIT \
99 92 libslp \
100 93 libbsdmalloc \
101 94 libdoor \
102 95 libdevinfo \
103 96 libdladm \
104 97 libdlpi \
105 98 libeti \
106 99 libcrypt \
107 100 libdns_sd \
108 101 libefi \
109 102 libfstyp \
110 103 libwanboot \
111 104 libwanbootutil \
112 105 libcryptoutil \
113 106 libinetutil \
114 107 libipadm \
115 108 libipmp \
116 109 libiscsit \
117 110 libkmf \
118 111 libkstat \
119 112 libkvm \
120 113 liblm \
121 114 libmalloc \
122 115 libmapmalloc \
123 116 libmtmalloc \
124 117 libnls \
125 118 libnwam \
126 119 libsmbios \
127 120 libtecla \
128 121 libumem \
129 122 libnvpair .WAIT \
130 123 libexacct \
131 124 libsasl \
132 125 libldap5 \
133 126 libsldap .WAIT \
134 127 libbsm \
135 128 libsys \
136 129 libsysevent \
137 130 libnisdb \
138 131 libpool \
139 132 libpp \
140 133 libproc \
141 134 libproject \
142 135 libsendfile \
143 136 nametoaddr \
144 137 ncad_addr \
145 138 hbaapi \
146 139 smhba \
147 140 sun_fc \
148 141 sun_sas \
149 142 gss_mechs/mech_krb5 .WAIT \
150 143 libkrb5 .WAIT \
151 144 krb5 .WAIT \
152 145 libsmbfs \
153 146 libfcoe \
154 147 libsrpt \
155 148 libstmf \
156 149 libstmfproxy \
157 150 libnsctl \
158 151 libunistat \
159 152 libdscfg \
160 153 librdc \
161 154 libinstzones \
162 155 libpkg \
163 156 libpcidb
164 157
165 158 SUBDIRS += \
166 159 passwdutil \
167 160 pam_modules \
168 161 crypt_modules \
169 162 libadt_jni \
170 163 abi \
171 164 auditd_plugins \
172 165 libvolmgt \
173 166 libdevice \
174 167 libdevid \
175 168 libdhcpsvc \
↓ open down ↓ |
111 lines elided |
↑ open up ↑ |
176 169 libc_db \
177 170 libndmp \
178 171 libsec \
179 172 libtnfprobe \
180 173 libtnf \
181 174 libtnfctl \
182 175 libdhcpagent \
183 176 libdhcpdu \
184 177 libdhcputil \
185 178 libxnet \
186 - libipsecutil
187 -$(CLOSED_BUILD)SUBDIRS += \
188 - $(CLOSED)/lib/libike
189 -SUBDIRS += \
179 + libipsecutil \
190 180 nsswitch \
191 181 print \
192 182 libuutil \
193 183 libscf \
194 184 libinetsvc \
195 185 librestart \
196 186 libsched \
197 187 libelfsign \
198 188 pkcs11 .WAIT \
199 189 libpctx .WAIT \
200 190 libcpc \
201 191 getloginx \
202 192 watchmalloc \
203 193 extendedFILE \
204 194 madv \
205 195 mpss \
206 196 libdisasm \
207 197 libwrap \
208 198 libxcurses \
209 199 libxcurses2 \
210 200 libbrand .WAIT \
211 201 libzonecfg \
212 202 libzoneinfo \
213 203 libzonestat \
214 204 libtsnet \
215 205 libtsol \
216 206 gss_mechs/mech_spnego \
217 207 gss_mechs/mech_dummy \
218 208 gss_mechs/mech_dh \
219 209 rpcsec_gss \
220 210 libraidcfg .WAIT \
221 211 librcm .WAIT \
222 212 libcfgadm .WAIT \
223 213 libpicl .WAIT \
224 214 libpicltree .WAIT \
225 215 raidcfg_plugins \
226 216 cfgadm_plugins \
227 217 libmail \
228 218 lvm \
229 219 libsmedia \
230 220 libipp \
231 221 libdiskmgt \
232 222 liblgrp \
233 223 libfsmgt \
234 224 fm \
235 225 libavl \
236 226 libcmdutils \
237 227 libcontract \
238 228 ../cmd/sendmail/libmilter \
239 229 sasl_plugins \
240 230 udapl \
241 231 libzpool \
242 232 libzfs_core \
243 233 libzfs \
244 234 libbe \
245 235 pylibbe \
246 236 libzfs_jni \
247 237 pyzfs \
248 238 pysolaris \
249 239 libmapid \
250 240 brand \
251 241 policykit \
252 242 hal \
253 243 libshare \
254 244 libsqlite \
255 245 libidmap \
256 246 libadutils \
257 247 libipmi \
258 248 libexacct/demo \
259 249 libvrrpadm \
260 250 libvscan \
261 251 libgrubmgmt \
262 252 smbsrv \
263 253 libilb \
264 254 scsi \
265 255 libima \
266 256 libsun_ima \
267 257 mpapi \
268 258 librstp \
269 259 libreparse \
270 260 libhotplug \
271 261 libfruutils .WAIT \
272 262 libfru \
273 263 $($(MACH)_SUBDIRS)
274 264
275 265 i386_SUBDIRS= \
276 266 libntfs \
277 267 libparted \
278 268 libfdisk \
279 269 libsaveargs
280 270
281 271 sparc_SUBDIRS= .WAIT \
282 272 efcode \
283 273 libds \
284 274 libdscp \
285 275 libprtdiag .WAIT \
286 276 libprtdiag_psr \
287 277 libpri \
288 278 librsc \
289 279 storage \
290 280 libpcp \
291 281 libtsalarm \
292 282 libv12n
293 283
294 284 FM_sparc_DEPLIBS= libpri
295 285
296 286 fm: \
297 287 libexacct \
298 288 libipmi \
299 289 libzfs \
300 290 scsi \
301 291 $(FM_$(MACH)_DEPLIBS)
302 292
303 293 #
304 294 # Create a special version of $(SUBDIRS) with no .WAIT's, for use with the
305 295 # clean and clobber targets (for more information, see those targets, below).
306 296 #
307 297 NOWAIT_SUBDIRS= $(SUBDIRS:.WAIT=)
308 298
309 299 DCSUBDIRS = \
310 300 lvm
311 301
312 302 MSGSUBDIRS= \
313 303 abi \
314 304 auditd_plugins \
315 305 brand \
316 306 cfgadm_plugins \
317 307 gss_mechs/mech_dh \
318 308 gss_mechs/mech_krb5 \
319 309 krb5 \
320 310 libast \
321 311 libbsm \
322 312 libc \
323 313 libcfgadm \
324 314 libcmd \
325 315 libcontract \
326 316 libcurses \
327 317 libdhcpsvc \
328 318 libdhcputil \
329 319 libipsecutil \
330 320 libdiskmgt \
331 321 libdladm \
332 322 libdll \
333 323 libgrubmgmt \
334 324 libgss \
335 325 libidmap \
336 326 libipmp \
337 327 libilb \
338 328 libinetutil \
339 329 libinstzones \
340 330 libipadm \
341 331 libnsl \
342 332 libnwam \
343 333 libpam \
344 334 libpicl \
345 335 libpool \
346 336 libpkg \
347 337 libpp \
348 338 libscf \
349 339 libsasl \
350 340 libldap5 \
351 341 libsecdb \
352 342 libshare \
353 343 libshell \
354 344 libsldap \
355 345 libslp \
356 346 libsmbfs \
357 347 libsmedia \
358 348 libsum \
359 349 libtsol \
360 350 libuutil \
361 351 libvrrpadm \
362 352 libvscan \
363 353 libwanboot \
364 354 libwanbootutil \
365 355 libzfs \
366 356 libzonecfg \
367 357 lvm \
368 358 madv \
369 359 mpss \
370 360 pam_modules \
371 361 pyzfs \
372 362 pysolaris \
373 363 rpcsec_gss \
374 364 libreparse
375 365 MSGSUBDIRS += \
376 366 $($(MACH)_MSGSUBDIRS)
377 367
378 368 sparc_MSGSUBDIRS= \
379 369 libprtdiag \
380 370 libprtdiag_psr
381 371
382 372 i386_MSGSUBDIRS= libfdisk
383 373
384 374 HDRSUBDIRS= \
385 375 auditd_plugins \
386 376 libast \
387 377 libbrand \
388 378 libbsm \
389 379 libc \
390 380 libcmd \
391 381 libcmdutils \
392 382 libcommputil \
393 383 libcontract \
394 384 libcpc \
395 385 libctf \
396 386 libcurses \
397 387 libtermcap \
398 388 libcryptoutil \
399 389 libdevice \
400 390 libdevid \
401 391 libdevinfo \
402 392 libdiskmgt \
403 393 libdladm \
404 394 libdll \
405 395 libdlpi \
406 396 libdhcpagent \
407 397 libdhcpsvc \
408 398 libdhcputil \
409 399 libdisasm \
410 400 libdns_sd \
411 401 libdscfg \
412 402 libdtrace \
413 403 libdtrace_jni \
414 404 libelfsign \
415 405 libeti \
416 406 libfru \
417 407 libfstyp \
418 408 libgen \
419 409 libipadm \
420 410 libipsecutil \
421 411 libinetsvc \
422 412 libinetutil \
423 413 libinstzones \
424 414 libipmi \
425 415 libipmp \
426 416 libipp \
427 417 libiscsit \
428 418 libkstat \
429 419 libkvm \
430 420 libmail \
431 421 libmd \
432 422 libmtmalloc \
433 423 libndmp \
434 424 libnvpair \
435 425 libnsctl \
436 426 libnsl \
437 427 libnwam \
438 428 libpam \
439 429 libpcidb \
440 430 libpctx \
441 431 libpicl \
442 432 libpicltree \
443 433 libpool \
444 434 libpp \
445 435 libproc \
446 436 libraidcfg \
447 437 librcm \
448 438 librdc \
449 439 libscf \
450 440 libsip \
451 441 libsmbios \
452 442 librestart \
453 443 librpcsvc \
454 444 librsm \
455 445 librstp \
456 446 libsasl \
457 447 libsec \
458 448 libshell \
459 449 libslp \
460 450 libsmedia \
461 451 libsocket \
462 452 libsqlite \
463 453 libfcoe \
464 454 libsrpt \
465 455 libstmf \
466 456 libstmfproxy \
467 457 libsum \
468 458 libsysevent \
469 459 libtecla \
470 460 libtnf \
471 461 libtnfctl \
472 462 libtnfprobe \
473 463 libtsnet \
474 464 libtsol \
475 465 libvrrpadm \
476 466 libvolmgt \
477 467 libumem \
478 468 libunistat \
479 469 libuutil \
480 470 libwanboot \
481 471 libwanbootutil \
482 472 libwrap \
483 473 libxcurses2 \
484 474 libzfs \
485 475 libzfs_core \
486 476 libzfs_jni \
487 477 libzoneinfo \
488 478 libzonestat \
489 479 hal \
490 480 policykit \
491 481 lvm \
492 482 pkcs11 \
493 483 passwdutil \
494 484 ../cmd/sendmail/libmilter \
495 485 fm \
496 486 udapl \
497 487 libmapid \
498 488 libkrb5 \
499 489 libsmbfs \
500 490 libshare \
501 491 libidmap \
502 492 libvscan \
503 493 libgrubmgmt \
504 494 smbsrv \
↓ open down ↓ |
305 lines elided |
↑ open up ↑ |
505 495 libilb \
506 496 scsi \
507 497 hbaapi \
508 498 smhba \
509 499 libima \
510 500 libsun_ima \
511 501 mpapi \
512 502 libreparse \
513 503 $($(MACH)_HDRSUBDIRS)
514 504
515 -$(CLOSED_BUILD)HDRSUBDIRS += \
516 - $(CLOSED)/lib/libike
517 -
518 505 i386_HDRSUBDIRS= \
519 506 libparted \
520 507 libfdisk \
521 508 libsaveargs
522 509
523 510 sparc_HDRSUBDIRS= \
524 511 libds \
525 512 libdscp \
526 513 libpri \
527 514 libv12n \
528 515 storage
529 516
530 517 all := TARGET= all
531 518 check := TARGET= check
532 519 clean := TARGET= clean
533 520 clobber := TARGET= clobber
534 521 install := TARGET= install
535 522 install_h := TARGET= install_h
536 523 lint := TARGET= lint
537 524 _dc := TARGET= _dc
538 525 _msg := TARGET= _msg
539 526
540 527 .KEEP_STATE:
541 528
542 529 #
543 530 # For the all and install targets, we clearly must respect library
544 531 # dependencies so that the libraries link correctly. However, for
545 532 # the remaining targets (check, clean, clobber, install_h, lint, _dc
546 533 # and _msg), libraries do not have any dependencies on one another
547 534 # and thus respecting dependencies just slows down the build.
548 535 # As such, for these rules, we use pattern replacement to explicitly
549 536 # avoid triggering the dependency information. Note that for clean,
550 537 # clobber and lint, we must use $(NOWAIT_SUBDIRS) rather than
551 538 # $(SUBDIRS), to prevent `.WAIT' from expanding to `.WAIT-nodepend'.
552 539 #
553 540
554 541 all: $(SUBDIRS)
555 542
556 543 install: $(SUBDIRS) .WAIT install_extra
557 544
558 545 # extra libraries kept in other source areas
559 546 install_extra:
560 547 @cd ../cmd/sgs; pwd; $(MAKE) install_lib
561 548 @pwd
562 549
563 550 clean clobber lint: $(NOWAIT_SUBDIRS:%=%-nodepend)
564 551
565 552 install_h check: $(HDRSUBDIRS:%=%-nodepend)
566 553
567 554 _msg: $(MSGSUBDIRS:%=%-nodepend) .WAIT _dc
568 555
569 556 _dc: $(DCSUBDIRS:%=%-nodepend)
570 557
571 558 #
572 559 # Library interdependencies are called out explicitly here
573 560 #
574 561 auditd_plugins: libbsm libnsl libsecdb
575 562 gss_mechs/mech_krb5: libgss libnsl libsocket libresolv pkcs11
576 563 libadt_jni: libbsm
577 564 libast: libsocket
578 565 libadutils: libldap5 libresolv libsocket libnsl
579 566 nsswitch: libadutils libidmap
580 567 libbe: libzfs
581 568 libbsm: libtsol
582 569 libcmd: libsum libast libsocket libnsl
583 570 libcmdutils: libavl
584 571 libcontract: libnvpair
585 572 libdevid: libdevinfo
586 573 libdevinfo: libnvpair libsec
587 574 libdhcpagent: libsocket libdhcputil libuuid libdlpi libcontract
588 575 libdhcpsvc: libinetutil
589 576 libdhcputil: libnsl libgen libinetutil libdlpi
590 577 libdladm: libdevinfo libinetutil libsocket libscf librcm libnvpair \
591 578 libexacct libnsl libkstat libcurses
592 579 libdll: libast
593 580 libdlpi: libinetutil libdladm
594 581 libds: libsysevent
595 582 libdscfg: libnsctl libunistat libsocket libnsl
596 583 libdtrace: libproc libgen libctf
597 584 libdtrace_jni: libuutil libdtrace
598 585 libefi: libuuid
599 586 libfstyp: libnvpair
↓ open down ↓ |
72 lines elided |
↑ open up ↑ |
600 587 libelfsign: libcryptoutil libkmf
601 588 libidmap: libadutils libldap5 libavl libsldap libuutil
602 589 libipadm: libnsl libinetutil libsocket libdlpi libnvpair libdhcpagent \
603 590 libdladm libsecdb
604 591 libiscsit: libc libnvpair libstmf libuuid libnsl
605 592 libkmf: libcryptoutil pkcs11
606 593 libnsl: libmd5
607 594 libmapid: libresolv
608 595 librdc: libsocket libnsl libnsctl libunistat libdscfg
609 596 libuuid: libdlpi
610 -$(CLOSED_BUILD)libike: libipsecutil libxnet libcryptoutil
611 597 libinetutil: libsocket
612 598 libipsecutil: libtecla libsocket
613 599 libinstzones: libzonecfg libcontract
614 600 libpkg: libwanboot libscf libadm
615 601 libnwam: libscf
616 602 libsecdb: libnsl
617 603 libsasl: libgss libsocket pkcs11 libmd
618 604 sasl_plugins: pkcs11 libgss libsocket libsasl
619 605 libsctp: libsocket
620 606 libshell: libast libcmd libdll libsocket libsecdb
621 607 libsip: libmd5
622 608 libsmbfs: libcmdutils libsocket libnsl libkrb5
623 609 libsocket: libnsl
624 610 libstmfproxy: libstmf libsocket libnsl libpthread
625 611 libsum: libast
626 612 libsysevent: libsecdb
627 613 libldap5: libsasl libsocket libnsl libmd
628 614 libsldap: libldap5 libtsol libnsl libc libscf libresolv
629 615 libpool: libnvpair libexacct
630 616 libpp: libast
631 617 libzonecfg: libc libsocket libnsl libuuid libnvpair libsysevent libsec \
632 618 libbrand libpool libscf
633 619 libproc: ../cmd/sgs/librtld_db ../cmd/sgs/libelf libctf libsaveargs
634 620 libproject: libpool libproc libsecdb
635 621 libtermcap: libcurses
636 622 libtsnet: libnsl libtsol libsecdb
637 623 libwrap: libnsl libsocket
638 624 libwanboot: libnvpair libresolv libnsl libsocket libdevinfo libinetutil \
639 625 libdhcputil
640 626 libwanbootutil: libnsl
641 627 pam_modules: libproject passwdutil smbsrv
642 628 libscf: libuutil libmd libgen libsmbios libnsl
643 629 libinetsvc: libscf
644 630 librestart: libuutil libscf
645 631 libsaveargs: libdisasm
646 632 ../cmd/sgs/libdl: ../cmd/sgs/libconv
647 633 ../cmd/sgs/libelf: ../cmd/sgs/libconv
648 634 pkcs11: libcryptoutil
649 635 print: libldap5
650 636 udapl/udapl_tavor: udapl/libdat
651 637 libzfs: libdevid libgen libnvpair libuutil \
652 638 libadm libavl libefi libidmap libmd libzfs_core
653 639 libzfs_core: libnvpair
654 640 libzfs_jni: libdiskmgt libnvpair libzfs
655 641 libzpool: libavl libumem libnvpair libcmdutils
656 642 libsec: libavl libidmap
657 643 brand: libc libsocket
658 644 libshare: libscf libzfs libuuid libfsmgt libsecdb libumem libsmbfs
659 645 libexacct/demo: libexacct libproject libsocket libnsl
660 646 libtsalarm: libpcp
661 647 smbsrv: libsocket libnsl libmd libxnet libpthread librt \
662 648 libshare libidmap pkcs11 libsqlite libcryptoutil \
663 649 libreparse libcmdutils
664 650 libv12n: libds libuuid
665 651 libvrrpadm: libsocket libdladm libscf
666 652 libvscan: libscf
667 653 libfru: libfruutils
668 654 scsi: libnvpair libfru
669 655 mpapi: libpthread libdevinfo libsysevent libnvpair
670 656 sun_fc: libdevinfo libsysevent libnvpair
671 657 libsun_ima: libdevinfo libsysevent libnsl
672 658 sun_sas: libdevinfo libsysevent libnvpair libkstat libdevid
673 659 libgrubmgmt: libdevinfo libzfs libfstyp
674 660 pylibbe: libbe libzfs
675 661 pyzfs: libnvpair libzfs
676 662 pysolaris: libsec libidmap
677 663 libreparse: libnvpair
678 664 libhotplug: libnvpair
679 665 cfgadm_plugins: libhotplug
680 666 libilb: libsocket
681 667 $(INTEL_BUILD)libdiskmgt:libfdisk
682 668
683 669 #
684 670 # The reason this rule checks for the existence of the
685 671 # Makefile is that some of the directories do not exist
686 672 # in certain situations (e.g., exportable source builds,
687 673 # OpenSolaris).
688 674 #
689 675 $(SUBDIRS): FRC
690 676 @if [ -f $@/Makefile ]; then \
691 677 cd $@; pwd; $(MAKE) $(TARGET); \
692 678 else \
693 679 true; \
694 680 fi
695 681
696 682 $(SUBDIRS:%=%-nodepend):
697 683 @if [ -f $(@:%-nodepend=%)/Makefile ]; then \
698 684 cd $(@:%-nodepend=%); pwd; $(MAKE) $(TARGET); \
699 685 else \
700 686 true; \
701 687 fi
702 688
703 689 FRC:
↓ open down ↓ |
83 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX