haiku/build/jam/OverriddenJamRules

749 lines
18 KiB
Plaintext
Raw Normal View History

# Overridden to allow spaces in file names.
actions Chmod1
{
$(CHMOD) "$(MODE)" "$(1)"
}
# Overridden to allow spaces in file names.
actions piecemeal together existing Clean
{
$(RM) "$(>)"
}
#-------------------------------------------------------------------------------
# Link rule/action are overwritten as they don't handle linking files who's name
# contain spaces very well. Also adds resources and version to executable.
#-------------------------------------------------------------------------------
rule Link
{
# Note: RESFILES must be set before invocation.
if [ on $(1) return $(PLATFORM) ] = host {
LINK on $(1) = $(HOST_LINK) ;
LINKFLAGS on $(1) = $(HOST_LINKFLAGS) [ on $(1) return $(LINKFLAGS) ] ;
} else {
LINK on $(1) = $(TARGET_LINK_$(TARGET_PACKAGING_ARCH)) ;
LINKFLAGS on $(1) = $(TARGET_LINKFLAGS_$(TARGET_PACKAGING_ARCH))
[ on $(1) return $(LINKFLAGS) ] ;
}
HAIKU_TARGET_IS_EXECUTABLE on $(1) = 1 ;
NEEDLIBS on $(1) = [ on $(1) return $(NEEDLIBS) ] ;
LINKLIBS on $(1) = [ on $(1) return $(LINKLIBS) ] ;
MODE on $(<) = $(EXEMODE) ;
on $(1) XRes $(1) : $(RESFILES) ;
if ! [ on $(1) return $(DONT_USE_BEOS_RULES) ] {
SetType $(1) ;
MimeSet $(1) : sharedObject ;
SetVersion $(1) ;
# For applications for the target also generate the MIME DB entries.
if [ on $(1) return $(PLATFORM) ] != host
&& [ on $(1) return $(RESFILES) ] {
CreateAppMimeDBEntries $(1) ;
}
# If the generic attribute emulation is enabled, make sure the tool to
# remove the attributes is built first.
if $(HOST_RM_ATTRS_TARGET) {
Depends $(1) : $(HOST_RM_ATTRS_TARGET) ;
}
}
Chmod $(<) ;
}
# When using "real" attributes (i.e. BeOS attributes or xattr/extattr) on the
# host platform, unlinking the main target by gcc will also automatically get
# rid of the attributes. When using the generic attribute emulation, which
# uses separate files, we need to remove the target explicitely first, so that
# the attributes won't be "leaked".
if $(HAIKU_HOST_USE_XATTR) = 1 {
actions Link bind NEEDLIBS LINK_BEGIN_GLUE LINK_END_GLUE VERSION_SCRIPT
{
$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(LINK_BEGIN_GLUE)" "$(2)" \
"$(NEEDLIBS)" $(LINKLIBS) "$(LINK_END_GLUE)" \
-Wl,--version-script,$(VERSION_SCRIPT)
}
} else {
actions Link bind NEEDLIBS LINK_BEGIN_GLUE LINK_END_GLUE VERSION_SCRIPT
{
$(RM) "$(1)"
$(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(LINK_BEGIN_GLUE)" "$(2)" \
"$(NEEDLIBS)" $(LINKLIBS) "$(LINK_END_GLUE)" \
-Wl,--version-script,$(VERSION_SCRIPT)
}
}
rule Object
{
# find out which headers and defines to use
local headers ;
local sysHeaders ;
local defines ;
on $(1) { # use on $(1) variable values
if ! $(PLATFORM) in $(SUPPORTED_PLATFORMS) {
return ;
}
# Save HDRS for -I$(HDRS) on compile.
# We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers
# in the .c file's directory, but generated .c files (from
# yacc, lex, etc) are located in $(LOCATE_TARGET), possibly
# different from $(SEARCH_SOURCE).
headers = $(HAIKU_CONFIG_HEADERS) $(SEARCH_SOURCE) $(SUBDIRHDRS)
$(HDRS) ;
sysHeaders = $(SUBDIRSYSHDRS) $(SYSHDRS) ;
defines = $(DEFINES) ;
if $(PLATFORM) = host {
sysHeaders += $(HOST_HDRS) ;
defines += $(HOST_DEFINES) ;
if $(USES_BE_API) {
sysHeaders += $(HOST_BE_API_HEADERS) ;
}
} else {
sysHeaders += [ FStandardHeaders $(TARGET_PACKAGING_ARCH) ]
$(TARGET_HDRS_$(TARGET_PACKAGING_ARCH)) ;
defines += $(TARGET_DEFINES_$(TARGET_PACKAGING_ARCH))
$(TARGET_DEFINES) ;
}
}
# locate object and search for source
LocalClean clean : $(<) ;
MakeLocateDebug $(<) ;
SEARCH on $(>) = $(SEARCH_SOURCE) ;
HDRS on $(<) = $(headers) ;
SYSHDRS on $(<) = $(sysHeaders) ;
# handle #includes for source: Jam scans for headers with
# the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE)
# with the scanned file as the target and the found headers
# as the sources. HDRSEARCH is the value of SEARCH used for
# the found header files. Finally, if jam must deal with
# header files of the same name in different directories,
# they can be distinguished with HDRGRIST.
# $(SEARCH_SOURCE:E) is where cc first looks for #include
# "foo.h" files. If the source file is in a distant directory,
# look there. Else, look in "" (the current directory).
HDRRULE on $(>) = HdrRule ;
HDRSCAN on $(>) = $(HDRPATTERN) ;
HDRSEARCH on $(>) = $(headers) $(sysHeaders) $(STDHDRS) ;
HDRGRIST on $(>) = $(HDRGRIST) ;
# propagate target specific-defines
DEFINES on $(1) = $(defines) ;
# if source is not .c, generate .c with specific rule
switch $(>:S)
{
case .asm : As $(<) : $(>) ;
case .nasm : AssembleNasm $(<) : $(>) ;
case .c : Cc $(<) : $(>) ;
case .C : C++ $(<) : $(>) ;
case .cc : C++ $(<) : $(>) ;
case .cpp : C++ $(<) : $(>) ;
case .f : Fortran $(<) : $(>) ;
case .l : if [ on $(2) return $(GENERATE_C++) ] {
InheritPlatform $(<:S=.cpp) : $(1) ;
C++ $(<) : $(<:S=.cpp) ;
Lex $(<:S=.cpp) : $(>) ;
} else {
InheritPlatform $(<:S=.c) : $(1) ;
Cc $(<) : $(<:S=.c) ;
Lex $(<:S=.c) : $(>) ;
}
case *.o : return ;
case .s : As $(<) : $(>) ;
case .S : As $(<) : $(>) ;
case .y : if [ on $(2) return $(GENERATE_C++) ] {
InheritPlatform $(1:S=.cpp) $(1:S=.hpp) : $(1) ;
C++ $(1) : $(1:S=.cpp) ;
Yacc $(1:S=.cpp) $(1:S=.hpp) : $(2) ;
} else {
InheritPlatform $(1:S=.c) $(1:S=.h) : $(1) ;
Cc $(1) : $(1:S=.c) ;
Yacc $(1:S=.c) $(1:S=.h) : $(2) ;
}
case * : UserObject $(<) : $(>) ;
}
}
rule As
{
local flags ;
local includesSeparator ;
local localIncludesOption ;
local systemIncludesOption ;
if [ on $(1) return $(PLATFORM) ] = host {
flags = [ on $(1) return $(HOST_ASFLAGS) $(ASFLAGS) ] ;
CC on $(1) = $(HOST_CC) ;
includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
} else {
flags = [ on $(1) return $(TARGET_ASFLAGS_$(TARGET_PACKAGING_ARCH))
$(ASFLAGS) ] ;
CC on $(1) = $(TARGET_CC_$(TARGET_PACKAGING_ARCH)) ;
includesSeparator
= $(TARGET_INCLUDES_SEPARATOR_$(TARGET_PACKAGING_ARCH)) ;
localIncludesOption
= $(TARGET_LOCAL_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
systemIncludesOption
= $(TARGET_SYSTEM_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
}
Depends $(<) : $(>) [ on $(1) return $(PLATFORM) ] ;
ASFLAGS on $(<) += $(flags) $(SUBDIRASFLAGS) ;
ASHDRS on $(<) = [ on $(<) FIncludes $(HDRS) : $(localIncludesOption) ]
$(includesSeparator)
[ on $(<) FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;
ASDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
}
# TODO: The KERNEL_CCFLAGS were used here before. Check whether we need any
# flags we don't have now.
actions As
{
$(CC) -c "$(2)" -O2 $(ASFLAGS) -D_ASSEMBLER $(ASDEFS) $(ASHDRS) -o "$(1)" ;
}
rule Lex
{
Depends $(1) : $(2) [ on $(1) return $(PLATFORM) ] ;
MakeLocateArch $(1) ;
LocalClean clean : $(1) ;
}
actions Lex
{
$(LEX) $(LEXFLAGS) -o$(1) $(2)
}
rule Yacc
{
local source = $(1[1]) ;
local header = $(1[2]) ;
local yaccSource = $(2) ;
MakeLocateArch $(source) $(header) ;
Depends $(source) $(header)
: $(yaccSource) [ on $(source) return $(PLATFORM) ] ;
Yacc1 $(source) $(header) : $(yaccSource) ;
LocalClean clean : $(source) $(header) ;
# make sure someone includes $(header) else it will be
# a deadly independent target
Includes $(source) : $(header) ;
}
actions Yacc1
{
bison $(YACCFLAGS) -o $(1[1]) $(2)
[ -f $(1[1]).h ] && mv $(1[1]).h $(1[2]) || true
}
rule Cc
{
Depends $(<) : $(>) [ on $(1) return $(PLATFORM) ] ;
on $(1) {
local flags ;
local includesSeparator ;
local localIncludesOption ;
local systemIncludesOption ;
# optimization flags
if $(DEBUG) = 0 {
flags += $(OPTIM) ;
} else {
flags += -O0 ;
}
if $(PLATFORM) = host {
# warning flags
if $(WARNINGS) != 0 {
flags += $(HOST_WARNING_CCFLAGS) ;
if $(WARNINGS) = treatAsErrors {
flags += -Werror $(HOST_WERROR_FLAGS) ;
}
}
# debug and other flags
flags += $(HOST_CCFLAGS) $(HOST_DEBUG_$(DEBUG)_CCFLAGS)
$(SUBDIRCCFLAGS) $(CCFLAGS) ;
if $(USES_BE_API) {
flags += $(HOST_BE_API_CCFLAGS) ;
}
CC on $(1) = $(HOST_CC) ;
includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
} else {
# warning flags
if $(WARNINGS) != 0 {
flags += $(TARGET_WARNING_CCFLAGS_$(TARGET_PACKAGING_ARCH)) ;
if $(WARNINGS) = treatAsErrors {
flags += -Werror
$(TARGET_WERROR_FLAGS_$(TARGET_PACKAGING_ARCH)) ;
}
}
# debug and other flags
flags += $(TARGET_CCFLAGS_$(TARGET_PACKAGING_ARCH))
$(TARGET_DEBUG_$(DEBUG)_CCFLAGS_$(TARGET_PACKAGING_ARCH))
$(SUBDIRCCFLAGS) $(CCFLAGS) ;
CC on $(1) = $(TARGET_CC_$(TARGET_PACKAGING_ARCH)) ;
includesSeparator
= $(TARGET_INCLUDES_SEPARATOR_$(TARGET_PACKAGING_ARCH)) ;
localIncludesOption
= $(TARGET_LOCAL_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
systemIncludesOption
= $(TARGET_SYSTEM_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
}
CCFLAGS on $(<) = $(flags) ;
CCHDRS on $(<) = [ FIncludes $(HDRS) : $(localIncludesOption) ]
$(includesSeparator)
[ FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;
CCDEFS on $(<) = [ FDefines $(DEFINES) ] ;
}
}
actions Cc
{
$(CC) $(CCFLAGS) -c "$(2)" $(CCDEFS) $(CCHDRS) -o "$(1)" ;
}
rule C++
{
Depends $(<) : $(>) [ on $(1) return $(PLATFORM) ] ;
on $(1) {
local flags ;
local includesSeparator ;
local localIncludesOption ;
local systemIncludesOption ;
# optimization flags
if $(DEBUG) = 0 {
flags += $(OPTIM) ;
} else {
flags += -O0 ;
}
if $(PLATFORM) = host {
# warning flags
if $(WARNINGS) != 0 {
flags += $(HOST_WARNING_C++FLAGS) ;
if $(WARNINGS) = treatAsErrors {
flags += -Werror $(HOST_WERROR_FLAGS) ;
}
}
# debug and other flags
flags += $(HOST_C++FLAGS) $(HOST_DEBUG_$(DEBUG)_C++FLAGS)
$(SUBDIRC++FLAGS) $(C++FLAGS) ;
if $(USES_BE_API) {
flags += $(HOST_BE_API_C++FLAGS) ;
}
C++ on $(1) = $(HOST_C++) ;
includesSeparator = $(HOST_INCLUDES_SEPARATOR) ;
localIncludesOption = $(HOST_LOCAL_INCLUDES_OPTION) ;
systemIncludesOption = $(HOST_SYSTEM_INCLUDES_OPTION) ;
} else {
# warning flags
if $(WARNINGS) != 0 {
flags += $(TARGET_WARNING_C++FLAGS_$(TARGET_PACKAGING_ARCH)) ;
if $(WARNINGS) = treatAsErrors {
flags += -Werror
$(TARGET_WERROR_FLAGS_$(TARGET_PACKAGING_ARCH)) ;
}
}
# debug and other flags
flags += $(TARGET_C++FLAGS_$(TARGET_PACKAGING_ARCH))
$(TARGET_DEBUG_$(DEBUG)_C++FLAGS_$(TARGET_PACKAGING_ARCH))
$(SUBDIRC++FLAGS) $(C++FLAGS) ;
C++ on $(1) = $(TARGET_C++_$(TARGET_PACKAGING_ARCH)) ;
includesSeparator
= $(TARGET_INCLUDES_SEPARATOR_$(TARGET_PACKAGING_ARCH)) ;
localIncludesOption
= $(TARGET_LOCAL_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
systemIncludesOption
= $(TARGET_SYSTEM_INCLUDES_OPTION_$(TARGET_PACKAGING_ARCH)) ;
}
C++FLAGS on $(<) = $(flags) ;
CCHDRS on $(<) = [ FIncludes $(HDRS) : $(localIncludesOption) ]
$(includesSeparator)
[ FSysIncludes $(SYSHDRS) : $(systemIncludesOption) ] ;
CCDEFS on $(<) = [ FDefines $(DEFINES) ] ;
}
}
actions C++
{
$(C++) -c "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ;
}
actions together Archive
{
# Force recreation of the archive to avoid build errors caused by
# stale dependencies after renaming or deleting object files.
$(RM) $(<)
$(AR) $(<) $(>)
}
rule Library
{
local lib = $(1) ;
local sources = [ FGristFiles $(2) ] ;
local objects = $(sources:S=$(SUFOBJ)) ;
InheritPlatform $(objects) : $(lib) ;
LibraryFromObjects $(lib) : $(objects) ;
Objects $(sources) ;
}
rule LibraryFromObjects
{
local _i _l _s ;
# Add grist to file names
# bonefish: No, don't. The Library rule does that anyway, and when we
# have an object from another dir, we certainly don't want that.
_s = $(>) ;
_l = $(<:S=$(SUFLIB)) ;
on $(_l) {
# set the tools according to the platform
if $(PLATFORM) = host {
AR on $(_l) = $(HOST_AR) $(HOST_ARFLAGS) ;
RANLIB on $(_l) = $(HOST_RANLIB) ;
} else {
AR on $(_l) = $(TARGET_AR_$(TARGET_PACKAGING_ARCH))
$(TARGET_ARFLAGS_$(TARGET_PACKAGING_ARCH)) ;
RANLIB on $(_l) = $(TARGET_RANLIB_$(TARGET_PACKAGING_ARCH)) ;
}
# library depends on its member objects
if $(KEEPOBJS)
{
LocalDepends obj : $(_s) ;
}
LocalDepends lib : $(_l) ;
# Set LOCATE for the library and its contents. The bound
# value shows up as $(NEEDLIBS) on the Link actions.
# For compatibility, we only do this if the library doesn't
# already have a path.
if ! $(_l:D)
{
# locate the library only, if it hasn't been located yet
local dir = $(LOCATE[1]) ;
if ! $(dir) {
MakeLocateDebug $(_l) ;
dir = [ on $(_l) return $(LOCATE[1]) ] ;
# Note: The "on ..." is necessary, since our environment
# isn't changed by MakeLocateDebug.
}
MakeLocate $(_l)($(_s:BS)) : $(dir) ;
}
if $(NOARSCAN)
{
# If we can't scan the library to timestamp its contents,
# we have to just make the library depend directly on the
# on-disk object files.
Depends $(_l) : $(_s) ;
}
else
{
# If we can scan the library, we make the library depend
# on its members and each member depend on the on-disk
# object file.
Depends $(_l) : $(_l)($(_s:BS)) ;
for _i in $(_s)
{
Depends $(_l)($(_i:BS)) : $(_i) ;
}
}
LocalClean clean : $(_l) ;
# bonefish: Not needed on the supported platforms. Maybe later...
# if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }
Archive $(_l) : $(_s) ;
if $(RANLIB) { Ranlib $(_l) ; }
# If we can't scan the library, we have to leave the .o's around.
if ! ( $(KEEPOBJS) || $(NOARSCAN) || $(NOARUPDATE) ) {
RmTemps $(_l) : $(_s) ;
}
}
}
rule Main
{
local target = $(1) ;
local sources = [ FGristFiles $(2) ] ;
local objects = $(sources:S=$(SUFOBJ)) ;
InheritPlatform $(objects) : $(target) ;
MainFromObjects $(target) : $(objects) ;
Objects $(sources) ;
}
rule MainFromObjects
{
local _s _t ;
# Add grist to file names
# Add suffix to exe
_s = [ FGristFiles $(>) ] ;
_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;
# so 'jam foo' works when it's really foo.exe
if $(_t) != $(<)
{
Depends $(<) : $(_t) ;
NotFile $(<) ;
}
# make compiled sources a dependency of target
LocalDepends exe : $(_t) ;
Depends $(_t) : $(_s) ;
MakeLocateDebug $(_t) ;
LocalClean clean : $(_t) ;
Link $(_t) : $(_s) ;
}
# Override Jam 2.5rc3 MakeLocate and MkDir to deal more intelligently
# with grist set on the supplied directory name. Also do nothing for already
# located files.
rule MakeLocate
{
local dir = $(2[1]) ;
if $(dir)
{
if ! $(dir:G) {
dir = $(dir:G=dir) ;
}
local target ;
for target in $(1) {
# don't relocate once located
LOCATE on $(target) += $(dir:G=) ;
if [ on $(target) return $(LOCATE) ] = $(dir:G=) {
Depends $(target) : $(dir) ;
MkDir $(dir) ;
}
}
}
}
rule MkDir
{
local dir = $(<) ;
if ! $(dir:G) {
dir = $(dir:G=dir) ;
}
# make this and all super directories
while true {
# If dir exists, don't update it
# Do this even for $(DOT).
NoUpdate $(dir) ;
# Bail out when reaching the CWD (".") or a directory we've already
# made.
if $(dir:G=) = $(DOT) || $($(dir:G=)-mkdir) {
return ;
}
local s ;
# Cheesy gate to prevent multiple invocations on same dir
# MkDir1 has the actions
# Arrange for jam dirs
$(dir:G=)-mkdir = true ;
MkDir1 $(dir) ;
LocalDepends dirs : $(dir) ;
# Recursively make parent directories.
# $(dir:P) = $(dir)'s parent, & we recurse until root
s = $(dir:P) ; # parent keeps grist
if $(s:G=) && $(s) != $(dir) {
Depends $(dir) : $(s) ;
dir = $(s) ;
} else if $(s) {
NotFile $(s) ;
break ;
}
}
}
rule ObjectCcFlags
{
# supports inheriting the global variable value
local file ;
for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {
CCFLAGS on $(file) = [ on $(file) return $(CCFLAGS) ] $(2) ;
}
}
rule ObjectC++Flags
{
# supports inheriting the global variable value
local file ;
for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {
C++FLAGS on $(file) = [ on $(file) return $(C++FLAGS) ] $(2) ;
}
}
rule ObjectDefines
{
# supports inheriting the global variable value and multiple files
if $(2) {
local file ;
for file in [ FGristFiles $(1:S=$(SUFOBJ)) ] {
DEFINES on $(file) = [ on $(file) return $(DEFINES) ] $(2) ;
CCDEFS on $(file) = [ on $(file) FDefines $(DEFINES) ] ;
}
}
}
rule ObjectHdrs
{
# ObjectHdrs <sources or objects> : <headers> : <gristed objects>
# Note: Parameter 3 <gristed objects> is an extension.
local objects = [ FGristFiles $(1:S=$(SUFOBJ)) ] $(3) ;
local headers = $(2) ;
local file ;
for file in $(objects) {
on $(file) {
local localHeaders = $(HDRS) $(headers) ;
SYSHDRS on $(file) = $(localHeaders) ;
# reformat ASHDRS and CCHDRS
local fileHeaders ;
if $(PLATFORM) = host {
fileHeaders =
[ FIncludes $(localHeaders) : $(HOST_LOCAL_INCLUDES_OPTION) ]
$(HOST_INCLUDES_SEPARATOR)
[ FSysIncludes $(SYSHDRS)
: $(HOST_SYSTEM_INCLUDES_OPTION) ] ;
} else {
local architecture = $(TARGET_PACKAGING_ARCH) ;
fileHeaders =
[ FIncludes $(localHeaders)
: $(TARGET_LOCAL_INCLUDES_OPTION_$(architecture)) ]
$(TARGET_INCLUDES_SEPARATOR_$(architecture))
[ FSysIncludes $(SYSHDRS)
: $(TARGET_SYSTEM_INCLUDES_OPTION_$(architecture)) ] ;
}
ASHDRS on $(file) = $(fileHeaders) ;
CCHDRS on $(file) = $(fileHeaders) ;
}
}
}
# Overridden to avoid calling SubDir for a directory twice (in SubInclude
# and from the Jamfile in the directory).
rule SubInclude
{
# SubInclude TOP d1 ... ;
#
# Include a subdirectory's Jamfile.
if ! $($(<[1]))
{
Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;
}
# Set up the config variables for the subdirectory.
local config = [ ConfigObject $(1) ] ;
__configured = ;
if ! [ on $(config) return $(__configured) ] {
# No custom configuration defined for the subdir. We use the variable
# values inherited by the closest ancestor.
config = $(HAIKU_INHERITED_SUBDIR_CONFIG) ;
}
# store SUBDIR_TOKENS
local oldSubDirTokens = $(SUBDIR_TOKENS) ;
on $(config) {
include [ FDirName $($(1[1])) $(1[2-) $(JAMFILE) ] ;
}
# restore SUBDIR_TOKENS
SUBDIR_TOKENS = $(oldSubDirTokens) ;
}
actions File
{
$(CP) "$(>)" "$(<)"
}