1#  Copyright (c) 2015 Artur Shepilko
2#
3#  Use, modification and distribution is subject to the Boost Software
4#  License Version 1.0. (See accompanying file LICENSE_1_0.txt or
5#  http://www.boost.org/LICENSE_1_0.txt)
6
7# Implements OpenVMS-based HP DECC/C++ toolset.
8# Relies on POSIX-style path handling bjam/Boost.Build implementation for VMS.
9
10import "class" : new ;
11import property ;
12import generators ;
13import os ;
14import toolset : flags ;
15import feature ;
16import type ;
17import common ;
18import unix ;
19import path ;
20
21
22if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
23{
24    .debug-configuration = true ;
25}
26
27feature.extend toolset : vmsdecc ;
28
29toolset.inherit-generators  vmsdecc : unix : unix.link unix.link.dll ;
30toolset.inherit-flags vmsdecc : unix ;
31toolset.inherit-rules vmsdecc : unix ;
32
33generators.override vmsdecc.archive-generator : builtin.archive-generator ;
34generators.override vmsdecc.prebuilt : builtin.prebuilt ;
35generators.override vmsdecc.searched-lib-generator : searched-lib-generator ;
36
37type.set-generated-target-suffix EXE : <toolset>vmsdecc <target-os>vms : exe ;
38type.set-generated-target-suffix OBJ : <toolset>vmsdecc <target-os>vms : obj ;
39type.set-generated-target-suffix PREPROCESSED_C : <toolset>vmsdecc <target-os>vms : i ;
40type.set-generated-target-suffix PREPROCESSED_CPP : <toolset>vmsdecc <target-os>vms : ixx ;
41type.set-generated-target-suffix STATIC_LIB : <toolset>vmsdecc <target-os>vms : olb ; ## xxx.olb
42
43type.register-suffixes exe : SHARED_LIB ;
44type.set-generated-target-prefix SHARED_LIB : <toolset>vmsdecc <target-os>vms : shr ; ## shrxxx.exe
45type.set-generated-target-suffix SHARED_LIB : <toolset>vmsdecc <target-os>vms : exe ; ## shrxxx.exe
46
47.OBJ = .obj ; ## suffix
48.nl = "
49" ;
50
51rule init ( version ? : command * : options * )
52{
53    local argv = [ modules.peek : ARGV ] ;
54
55    local condition = [
56      common.check-init-parameters vmsdecc : version $(version) ] ;
57
58    # CC and CXX are CLI commands, so no need to search for the executables
59    command = CXX ;
60    toolset.flags vmsdecc .CXX $(condition) : CXX ;
61    common.handle-options vmsdecc : $(condition) : $(command) : $(options) ;
62
63    local command_c = $(command[1--2]) $(command[-1]:B=CC) ;
64    toolset.flags vmsdecc .CC $(condition) : $(command_c) ;
65
66    local linker = [ feature.get-values <linker> : $(options) ] ;
67    linker ?= CXXLINK ;
68    toolset.flags vmsdecc.link .LD $(condition) :  $(linker) ;
69    if $(.debug-configuration)
70    {
71        ECHO notice\: using linker "::" $(condition) "::" $(linker[1]) ;
72    }
73
74    local archiver = LIB ;
75    toolset.flags vmsdecc.archive .AR $(condition) :  $(archiver) ;
76
77    local b2 = $(argv[1]) ;
78    toolset.flags vmsdecc .B2 $(condition) :  $(b2) ;
79}
80
81# Declare generators
82generators.register-c-compiler vmsdecc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>vmsdecc ;
83generators.register-c-compiler vmsdecc.compile.c.preprocess   : C   : PREPROCESSED_C   : <toolset>vmsdecc ;
84generators.register-c-compiler vmsdecc.compile.c : C : OBJ : <toolset>vmsdecc ;
85generators.register-c-compiler vmsdecc.compile.c++ : CPP : OBJ : <toolset>vmsdecc ;
86
87# Declare flags and actions for compilation
88flags vmsdecc.compile OPTIONS <debug-symbols>on : /DEBUG ;
89flags vmsdecc.compile OPTIONS <profiling>on : /DEBUG ;   ## needs PCA link options
90flags vmsdecc.compile OPTIONS <optimization>off : /NOOPT ;
91flags vmsdecc.compile OPTIONS <optimization>speed : /OPT=INLINE=SPEED/OPT=NOINLINE ;
92flags vmsdecc.compile OPTIONS <optimization>space : /OPT=INLINE=SIZE/OPT=NOINLINE ;
93flags vmsdecc.compile OPTIONS <warnings>off : /NOWARN ;
94flags vmsdecc.compile OPTIONS <warnings>on : /WARN ;
95flags vmsdecc.compile OPTIONS <warnings>all  : /WARN=ENABLE=ALL ;
96
97flags vmsdecc.compile.c++ OPTIONS <inlining>off : /OPT=NOINLINE ;
98
99flags vmsdecc OPTIONS <address-model>32 : /POINTER=32 ;
100flags vmsdecc OPTIONS <address-model>64 : /POINTER=64 ; ## /POINTER=64=ARGV argv-64
101
102flags vmsdecc.compile OPTIONS <cflags> ;
103flags vmsdecc.compile.c++ OPTIONS <cxxflags> ;
104flags vmsdecc.compile DEFINES <define> ;
105flags vmsdecc.compile UNDEFS <undef> ;
106flags vmsdecc.compile INCLUDES <include> ;
107flags vmsdecc.compile.c++ TEMPLATE_DEPTH <c++-template-depth> ;
108
109feature.feature cxx-repository          :                 : free path ; #order-sensitive ;
110flags vmsdecc CXX-REPOS <cxx-repository> ;
111
112
113local rule get-includes ( sources * : includes * )
114{
115    local result ;
116
117    ## Expect POSIX-style path, quote in double-quotes
118    for local d in $(sources:D) $(includes)
119    {
120        if $(d)
121        {
122            local QUOTE = \" ;
123            local SEP = / ;
124
125            local enquote = false ;
126            local addsep = false ;
127
128            s = [ SPLIT_BY_CHARACTERS $(d) : $(QUOTE) ] ;
129
130            if $(s) = $(d) { enquote = true ; }
131            if [ SPLIT_BY_CHARACTERS $(s) : $(SEP) ] = $(s) { addsep = true ; }
132
133            if $(addsep)
134            {
135                d = $(s)$(SEP) ;
136                enquote = true ;
137            }
138
139            if $(enquote)
140            {
141                d = $(QUOTE)$(d)$(QUOTE) ;
142            }
143
144            if ! $(d) in $(result)
145            {
146                result += $(d) ;
147            }
148        }
149    }
150
151    return $(result) ;
152}
153
154CXX-REPO-NAME = cxx_repository ;
155
156local rule get-target-cxx-repo ( target )
157{
158    return [ path.join $(target) $(CXX-REPO-NAME) ] ;
159}
160
161rule compile.c++ ( targets * : sources * : properties * )
162{
163  DEPENDS $(targets) : [ on $(targets) return $(SOURCE-INCLUDES) ] ;
164  DEPENDS $(targets) : [ on $(targets) return $(CXX-REPOS) ] ;
165
166  DEFINES on $(targets) = [ on $(targets) return "__USE_STD_IOSTREAM" $(DEFINES) ] ;
167
168  INCLUDES on $(targets) = [ on $(targets) get-includes $(sources) : $(INCLUDES) ] ;
169
170  TARGET-CXX-REPO on $(targets) =  [ on $(targets[1]) get-target-cxx-repo $(LOCATE) ] ;
171  CXX-REPOS on $(targets) = [ on $(targets) return $(TARGET-CXX-REPO) $(CXX-REPOS) ] ;
172}
173
174
175rule compile.c ( targets * : sources * : properties * )
176{
177  DEPENDS $(targets) : [ on $(targets) return $(SOURCE-INCLUDES) ] ;
178
179  INCLUDES on $(targets) = [ on $(targets) get-includes $(sources) : $(INCLUDES) ] ;
180}
181
182actions compile.c
183{
184    $(.CC) $(OPTIONS) /DEF=("$(DEFINES:J=",")") /UNDEF=("$(UNDEFS:J=",")") /INC=($(INCLUDES:J=,)) /OBJ=$(<:W) $(>:W)
185}
186
187actions compile.c++
188{
189    $(.CXX) $(OPTIONS) /DEF=("$(DEFINES:J=",")") /UNDEF=("$(UNDEFS:J=",")") /INC=($(INCLUDES:J=,)) /REPO=($(CXX-REPOS:WJ=,)) /OBJ=$(<:W) $(>:W)
190}
191
192
193
194# Custom linking generator to separate dependency libraries and optfiles from
195# the list of sources. The objfiles, libraries, and optfiles are then referenced
196# via properties. This allows separate qualification of object-files and libraries
197# on linker command line.
198#
199class vmsdecc-linking-generator : linking-generator
200{
201    rule run ( project name ? : property-set : sources + )
202    {
203        local result = [ linking-generator.run $(project) $(name) : $(property-set)
204            : $(sources) ] ;
205
206        return $(result) ;
207    }
208
209    rule generated-targets ( sources + : property-set : project name ? )
210    {
211        local sources2 ;     # Sources to pass to inherited rule.
212        local properties2 ;  # Properties to pass to inherited rule.
213        local objfiles ;     # Object files.
214        local libraries ;    # Library sources.
215
216        properties2 = [ $(property-set).raw ] ;
217
218        for local s in $(sources)
219        {
220            if [ type.is-derived [ $(s).type ] OBJ ]
221            {
222                objfiles += $(s) ;
223                properties2 += <link-objfile>$(s) ;
224            }
225            else if [ type.is-derived [ $(s).type ] STATIC_LIB ]
226            {
227                libraries += $(s) ;
228                properties2 += <link-staticlib>$(s) ;
229            }
230            else if [ type.is-derived [ $(s).type ] SHARED_LIB ]
231            {
232                libraries += $(s) ;
233                properties2 += <link-sharedlib>$(s) ;
234            }
235        }
236
237
238        return [ linking-generator.generated-targets $(sources)
239            : [ property-set.create $(properties2) ] : $(project) $(name) ] ;
240    }
241}
242
243
244generators.register [ new vmsdecc-linking-generator vmsdecc.link :
245    OBJ SEARCHED_LIB STATIC_LIB SHARED_LIB : EXE : <toolset>vmsdecc ] ;
246
247generators.register [ new vmsdecc-linking-generator vmsdecc.link.dll :
248    OBJ SEARCHED_LIB STATIC_LIB SHARED_LIB : SHARED_LIB : <toolset>vmsdecc ] ;
249
250
251
252# Declare flags and actions for linking
253flags vmsdecc.link OPTIONS <debug-symbols>on : /DEBUG ;
254# Strip the binary when no debugging is needed
255flags vmsdecc.link OPTIONS <debug-symbols>off : /NODEBUG ;
256flags vmsdecc.link OPTIONS <profiling>on : /DEBUG ; ## need "DEFINE LIB$DEBUG PCA$COLLECTOR"
257flags vmsdecc.link OPTIONS <linkflags> ;
258flags vmsdecc.link LINKPATH <library-path> ;
259flags vmsdecc.link FINDLIBS-ST <find-static-library> ;
260flags vmsdecc.link FINDLIBS-SA <find-shared-library> ;
261flags vmsdecc.link LIBRARIES <library-file> ;
262flags vmsdecc.link LINK-RUNTIME <runtime-link>static : static ;
263flags vmsdecc.link LINK-RUNTIME <runtime-link>shared : dynamic ;
264flags vmsdecc.link RPATH <dll-path> ;
265flags vmsdecc.link FINDLIBS-SA ;
266
267feature.feature "link-objfile"          :                 : free dependency path incidental ;
268flags vmsdecc.link LINK-OBJS <link-objfile> ;
269
270feature.feature "link-libmodule"          :                 : free dependency incidental ;
271flags vmsdecc.link LINK-LIBMODULES <link-libmodule> ;
272
273feature.feature "link-staticlib"          :                 : free dependency path incidental ;
274flags vmsdecc.link LINK-LIBS <link-staticlib> ;
275
276feature.feature "link-sharedlib"          :                 : free dependency path incidental ;
277flags vmsdecc.link LINK-SHAREDLIBS <link-sharedlib> ;
278
279feature.feature "link-optfile"          :                 : free dependency path incidental ;
280flags vmsdecc.link LINK-OPTS <link-optfile> ;
281
282
283local rule export-target-var-contents ( var-name : values * )
284{
285    local result ;
286    local nl = "
287" ;
288    local locate ;
289
290    if $(var-name)
291    {
292        result +=
293            "$(nl)$(var-name) =" ;
294        for local f in $(values)
295        {
296            locate = [ on $(f) return $(LOCATE) ] ;
297            result +=
298                "$(nl)\"$(f:TG=:R=$(locate))\"" ;
299        }
300        result += "$(nl)    ;" ;
301    }
302
303    return $(result) ;
304}
305
306# VMS linker usually expects an explicit object module that contains main().
307# Yet on *NIX, the main module can be automatically resolved from a library --
308# this may arguably be convenient with dynamic linking, and is also used with
309# Boost.Test.
310# To handle such cases on VMS, one needs first to locate the library module
311# containing main(), then include it in sources for the link command.
312# GLOB_ARCHIVE built-in can locate the module name (globbing by symbol MAIN).
313# To be able to use its result during jam-parsing stage, we need to execute it
314# from a separate jam-file that produces a pre-defined option file for link.
315#
316
317actions write-jam-file-contents
318{
319    SET FILE /VER=1 @($(<:W):E= $(>) )
320}
321
322
323local rule mainmod-link-opt.generate ( jam-file : opt-file : objs * : libs * : sharedlibs * )
324{
325    local nl = "
326" ;
327    local $ = $ ;
328    local @ = @ ;
329
330    if $(jam-file) && $(opt-file)
331    {
332        local .contents on $(jam-file) =
333            "# This file was auto-generated by <toolset>$(__name__)." ;
334
335        .contents on $(jam-file) +=
336            "$(nl)OPT-FILE = $(opt-file) ;" ;
337
338        .contents on $(jam-file) += [ on $(jam-file)
339            export-target-var-contents "OBJS" : $(objs) ] ;
340
341        .contents on $(jam-file) += [ on $(jam-file)
342            export-target-var-contents "LIBS" : $(libs) ] ;
343
344        .contents on $(jam-file) += [ on $(jam-file)
345            export-target-var-contents "SHAREDLIBS" : $(sharedlibs) ] ;
346
347        .contents on $(jam-file) +=
348            "$(nl).nl = \"$(nl)\" ;"
349            ;
350        .contents on $(jam-file) +=
351            "$(nl)local rule get-main-members ( libs * : symbol-main ? )"
352            "$(nl){"
353            "$(nl)    local result ;"
354            "$(nl)    symbol-main ?= \"MAIN\" ;"
355            "$(nl)    for local libfile in $($)(libs)"
356            "$(nl)    {"
357            "$(nl)        local main = [ GLOB_ARCHIVE $($)(libfile) : : : $($)(symbol-main) ] ;"
358            "$(nl)        if $($)(main)"
359            "$(nl)        {"
360            "$(nl)            result += $($)(main) ;"
361            "$(nl)        }"
362            "$(nl)    }"
363            "$(nl)    return  $($)(result) ;"
364            "$(nl)}"
365            ;
366        .contents on $(jam-file) +=
367            "$(nl)local rule get-libmods ( members * )"
368            "$(nl){"
369            "$(nl)    local result ;"
370            "$(nl)    for local m in $($)(members)"
371            "$(nl)    {"
372            "$(nl)        local lib = $($)(m:WDBS) ;"
373            "$(nl)        local mem = $($)(m:M) ;"
374            "$(nl)        if $($)(mem)"
375            "$(nl)        {"
376            "$(nl)            local mod = [ SPLIT_BY_CHARACTERS $($)(mem) : \"()\" ] ;"
377            "$(nl)            result += $($)(lib)/INC=($($)(mod:B))/LIB ;"
378            "$(nl)        }"
379            "$(nl)    }"
380            "$(nl)    return $($)(result) ;"
381            "$(nl)}"
382            ;
383        .contents on $(jam-file) +=
384            "$(nl)rule mainmod-link-opt ( opt-file : libs * : objs * )"
385            "$(nl){"
386            "$(nl)    local main-members = [ on $($)(opt-file[1]) get-main-members $($)(libs) ] ;"
387            "$(nl)    LIBMODULES on $($)(opt-file[1]) = [ on $($)(opt-file[1]) get-libmods $($)(main-members[1]) ] ;"
388            "$(nl)}"
389            ;
390        .contents on $(jam-file) +=
391            "$(nl)actions mainmod-link-opt bind OBJS LIBMODULES"
392            "$(nl){"
393            "$(nl)    SET FILE /VER=1 $(@)($($)(<:W):E= $($)(LIBMODULES:J=,-$($)(.nl))-$($)(.nl) )"
394            "$(nl)}"
395            ;
396        .contents on $(jam-file) +=
397            "$(nl)local rule make"
398            "$(nl){"
399            "$(nl)    if $($)(OPT-FILE)"
400            "$(nl)    {"
401            "$(nl)        DEPENDS all : $($)(OPT-FILE) ;"
402            "$(nl)        DEPENDS $($)(OPT-FILE) : $($)(LIBS) $($)(OBJS) ;"
403            "$(nl)        mainmod-link-opt $($)(OPT-FILE) : $($)(LIBS) : $($)(OBJS) ;"
404            "$(nl)    }"
405            "$(nl)}"
406            "$(nl)make all ;"
407            ;
408
409        write-jam-file-contents $(jam-file) : [ on $(jam-file) return $(.contents) ] ;
410
411    }
412}
413
414
415rule link ( targets * : sources * : properties * )
416{
417    DEPENDS $(targets) : [ on $(targets) return $(CXX-REPOS) ] ;
418    DEPENDS $(targets) : [ on $(targets) return $(LINK-OBJS) ] ;
419    DEPENDS $(targets) : [ on $(targets) return $(LINK-LIBS) ] ;
420    DEPENDS $(targets) : [ on $(targets) return $(LINK-SHAREDLIBS) ] ;
421    DEPENDS $(targets) : [ on $(targets) return $(LINK-OPTS) ] ;
422    DEPENDS $(targets) : [ on $(targets) return $(LIBRARIES) ] ;
423
424
425    for local s in $(sources)
426    {
427        local r = [ on $(s) return $(TARGET-CXX-REPO) ] ;
428
429        if ! $(r) in [ on $(targets[1]) return $(CXX-REPOS) ]
430        {
431            CXX-REPOS on $(targets[1]) += $(r) ;
432        }
433    }
434
435    local locate = [ on $(targets[1]) return $(LOCATE) ] ;
436    LINK-MAINMOD-OPT on $(targets[1]) = $(targets[1]:TG=:R=$(locate):S=$MAINMOD.opt) ;
437    LINK-MAINMOD-JAM on $(targets[1]) = $(targets[1]:TG=:R=$(locate):S=$MAINMOD.jam) ;
438    #on $(targets[1]) TEMPORARY $(LINK-MAINMOD-JAM) ;
439
440    DEPENDS $(targets) : [ on $(targets) return $(LINK-MAINMOD-OPT) ] ;
441    DEPENDS $(targets) : [ on $(targets) return $(LINK-MAINMOD-JAM) ] ;
442    on $(targets[1]) DEPENDS $(LINK-MAINMOD-OPT) : $(LINK-MAINMOD-JAM) ;
443
444    on $(targets[1]) mainmod-link-opt.generate $(LINK-MAINMOD-JAM)
445        : $(LINK-MAINMOD-OPT) : $(LINK-OBJS) : $(LINK-LIBS) $(LIBRARIES) : $(LINK-SHAREDLIBS) ;
446
447
448}
449
450actions link bind LINK-OBJS LINK-MAINMOD-JAM LINK-MAINMOD-OPT LINK-LIBS LIBRARIES LINK-SHAREDLIBS LINK-OPTS CXX-REPOS
451{
452    CXX_REPOS = "" +"$(CXX-REPOS:WJ=,)"
453    IF (CXX_REPOS .EQS. "") THEN  CXX_REPOS = "NL:"
454    DEF /NOLOG REPOS 'CXX_REPOS'
455    SET FILE /VER=1 @($(<:WS=$INPUT.opt):E= $(LINK-OBJS:WJ=,-$(.nl))-$(.nl) ,$(LINK-LIBS:WJ=/LIB,-$(.nl))/LIB-$(.nl) ,$(LIBRARIES:WJ=/LIB,-$(.nl))/LIB-$(.nl) ,$(LINK-SHAREDLIBS:WJ=/SHARE,-$(.nl))/SHARE-$(.nl) )
456    MC $(.B2) -f $(LINK-MAINMOD-JAM:W)
457    $(.LD) $(OPTIONS) /REPO=(REPOS:) /EXE=$(<:W) $(LINK-MAINMOD-OPT:W)/OPT, $(<:WS=$INPUT.opt)/OPT ,$(LINK-OPTS:WJ=/OPT,)/OPT
458}
459
460# Slight mods for dlls
461rule link.dll ( targets * : sources * : properties * )
462{
463    DEPENDS $(targets) : [ on $(targets) return $(CXX-REPOS) ] ;
464    DEPENDS $(targets) : [ on $(targets) return $(LINK-OBJS) ] ;
465    DEPENDS $(targets) : [ on $(targets) return $(LINK-LIBS) ] ;
466    DEPENDS $(targets) : [ on $(targets) return $(LINK-SHAREDLIBS) ] ;
467    DEPENDS $(targets) : [ on $(targets) return $(LINK-OPTS) ] ;
468    DEPENDS $(targets) : [ on $(targets) return $(LIBRARIES) ] ;
469
470    for local s in $(sources)
471    {
472        local r = [ on $(s) return $(TARGET-CXX-REPO) ] ;
473
474        if ! $(r) in [ on $(targets[1]) return $(CXX-REPOS) ]
475        {
476            CXX-REPOS on $(targets[1]) += $(r) ;
477        }
478    }
479
480
481    local locate = [ on $(targets[1]) return $(LOCATE) ] ;
482    LINK-MAINMOD-OPT on $(targets[1]) = $(targets[1]:TG=:R=$(locate):S=$MAINMOD.opt) ;
483    LINK-MAINMOD-JAM on $(targets[1]) = $(targets[1]:TG=:R=$(locate):S=$MAINMOD.jam) ;
484    #on $(targets[1]) TEMPORARY $(LINK-MAINMOD-JAM) ;
485
486    DEPENDS $(targets) : [ on $(targets) return $(LINK-MAINMOD-OPT) ] ;
487    DEPENDS $(targets) : [ on $(targets) return $(LINK-MAINMOD-JAM) ] ;
488    on $(targets[1]) DEPENDS $(LINK-MAINMOD-OPT) : $(LINK-MAINMOD-JAM) ;
489
490    on $(targets[1]) mainmod-link-opt.generate $(LINK-MAINMOD-JAM)
491        : $(LINK-MAINMOD-OPT) : $(LINK-OBJS) : $(LINK-LIBS) $(LIBRARIES) : $(LINK-SHAREDLIBS) ;
492
493}
494
495actions link.dll bind LINK-OBJS LINK-MAINMOD-JAM LINK-MAINMOD-OPT LINK-LIB LINK-LIBS LIBRARIES LINK-SHAREDLIBS LINK-OPTS CXX-REPOS
496{
497    CXX_REPOS = "" +"$(CXX-REPOS:WJ=,)"
498    IF (CXX_REPOS .EQS. "") THEN  CXX_REPOS = "NL:"
499    DEF /NOLOG REPOS 'CXX_REPOS'
500    SET FILE /VER=1 @($(<:WS=$INPUT.opt):E= $(LINK-OBJS:WJ=,-$(.nl))-$(.nl) ,$(LINK-LIBS:WJ=/LIB,-$(.nl))/LIB-$(.nl) ,$(LIBRARIES:WJ=/LIB,-$(.nl))/LIB-$(.nl) ,$(LINK-SHAREDLIBS:WJ=/SHARE,-$(.nl))/SHARE-$(.nl) )
501    MC $(.B2) -f $(LINK-MAINMOD-JAM:W)
502    $(.LD) $(OPTIONS) /REPO=(REPOS:) /SHARE=$(<:W) $(LINK-MAINMOD-OPT:W)/OPT, $(<:WS=$INPUT.opt)/OPT ,$(LINK-OPTS:WJ=/OPT,)/OPT
503}
504
505
506
507flags vmsdecc.archive AROPTIONS <archiveflags> ;
508
509
510local rule vms-join-wildcard-name ( path * : name )
511{
512    local files ;
513
514    if $(name)
515    {
516        for local d in $(path)
517        {
518            files += $(d)$(name) ;
519        }
520
521        files ?= $(name) ;
522
523    }
524
525    return $(files) ;
526}
527
528
529rule archive ( targets + : sources * : properties * )
530{
531    local clean.a = $(targets[1])(clean) ;
532    TEMPORARY $(clean.a) ;
533    NOCARE $(clean.a) ;
534    LOCATE on $(clean.a) = [ on $(targets[1]) return $(LOCATE) ] ;
535    DEPENDS $(clean.a) : $(sources) ;
536    DEPENDS $(targets) : $(clean.a) ;
537    common.RmTemps $(clean.a) : $(targets) ;
538
539
540    #CXX-REPOS on $(targets[1]) = null ;  ## reset
541
542    for local s in $(sources)
543    {
544        local r = [ on $(s) return $(TARGET-CXX-REPO) ] ;
545
546        if ! $(r) in [ on $(targets[1]) return $(CXX-REPOS) ]
547        {
548            CXX-REPOS on $(targets[1]) += $(r) ;
549        }
550    }
551
552    if [ on $(targets[1]) return $(CXX-REPOS) ]
553    {
554        CXX-REPO-OBJS on $(targets[1]) = [ on $(targets[1]) return [ vms-join-wildcard-name $(CXX-REPOS:W) : *$(.OBJ) ] ] ;
555
556        #DEPENDS $(targets) : [ on $(targets[1]) return $(CXX-REPO-OBJS) ] ;
557    }
558}
559
560# Declare action for creating static libraries
561actions piecemeal archive
562{
563    HAVE_REPO_OBJS = "F"
564    IF ("" +"$(CXX-REPO-OBJS[1])" .NES. "")
565    THEN
566       IF ( "" +F$SEARCH("$(CXX-REPO-OBJS[1])") .NES. "")
567       THEN
568          HAVE_REPO_OBJS = "T"
569       ENDIF
570    ENDIF
571    $(.AR) /CREATE /REPL $(AROPTIONS) $(<:W) $(>:WJ=,)
572    IF (HAVE_REPO_OBJS)
573    THEN
574        $(.AR) /REPL $(AROPTIONS) $(<:W) $(CXX-REPO-OBJS:J=,)
575        PIPE DEL /NOLOG /NOCONF $(CXX-REPO-OBJS:J=;*,);* 2>NL: >NL:
576    ENDIF
577}
578
579