From c19407c6040f89a1ba54a69e142aab38220a1a16 Mon Sep 17 00:00:00 2001 From: Rene Rivera Date: Mon, 21 Jan 2002 22:25:03 +0000 Subject: [PATCH] - Moved code to support it for all target types. - Added feature. - Added and to all toolsets. - Documented existing changes to "variant" inheritance. [SVN r12408] --- boost-base.jam | 16 +++++----------- borland-tools.jam | 2 ++ build_system.htm | 38 +++++++++++++++++++++++++++++++++++--- como-tools.jam | 2 ++ features.jam | 1 + gcc-stlport-tools.jam | 13 ++++++++----- gcc-tools.jam | 3 ++- intel-linux-tools.jam | 3 +++ kcc-tools.jam | 2 ++ metrowerks-tools.jam | 1 + mipspro-tools.jam | 2 ++ msvc-tools.jam | 2 ++ tru64cxx-tools.jam | 2 ++ v1/boost-base.jam | 16 +++++----------- v1/borland-tools.jam | 2 ++ v1/build_system.htm | 38 +++++++++++++++++++++++++++++++++++--- v1/como-tools.jam | 2 ++ v1/features.jam | 1 + v1/gcc-stlport-tools.jam | 13 ++++++++----- v1/gcc-tools.jam | 3 ++- v1/intel-linux-tools.jam | 3 +++ v1/kcc-tools.jam | 2 ++ v1/metrowerks-tools.jam | 1 + v1/mipspro-tools.jam | 2 ++ v1/msvc-tools.jam | 2 ++ v1/tru64cxx-tools.jam | 2 ++ v1/vacpp-tools.jam | 2 ++ vacpp-tools.jam | 2 ++ 28 files changed, 138 insertions(+), 40 deletions(-) diff --git a/boost-base.jam b/boost-base.jam index dd9a23804..02008a30e 100644 --- a/boost-base.jam +++ b/boost-base.jam @@ -1051,6 +1051,10 @@ rule declare-local-target "$(gTARGET_TYPE($(target-id)))" "$(5)" ; } + # Supress the regular build of this target + local suppress = [ get-values : $(4) ] ; + local gSUPPRESS_FAKE_TARGETS = $(suppress[1]) ; + # Just gather information if we are including a library's Jamfile for a # dependent target. Don't generate build instructions here. if ! $(gIN_LIB_INCLUDE) @@ -1468,17 +1472,7 @@ gGENERATOR_FUNCTION(LIB) = library-file ; # Declare a statically-linked library target. rule lib { - local suppress = [ get-values : $(4) ] ; - if $(suppress) - { - local gSUPPRESS_FAKE_TARGETS = $(suppress[1]) ; - declare-local-target $(<) : $(2) : $(3) : - [ difference $(4) : [ get-properties : $(4) ] ] : LIB ; - } - else - { - declare-local-target $(<) : $(2) : $(3) : $(4) : LIB ; - } + declare-local-target $(<) : $(2) : $(3) : $(4) : LIB ; } # unit-test target : sources : requirements : local-build diff --git a/borland-tools.jam b/borland-tools.jam index 62f53397d..240e40ad3 100644 --- a/borland-tools.jam +++ b/borland-tools.jam @@ -62,6 +62,8 @@ flags borland C++FLAGS ; flags borland DEFINES ; flags borland UNDEFS ; flags borland HDRS ; +flags borland STDHDRS ; +flags borland LINKFLAGS ; flags borland STDHDRS : $(BCCROOT)$(SLASH)include ; flags borland STDLIBPATH : $(BCCROOT)$(SLASH)lib ; diff --git a/build_system.htm b/build_system.htm index 81349e842..3f6dedc7f 100644 --- a/build_system.htm +++ b/build_system.htm @@ -809,7 +809,22 @@ project-root ; When multiple values are specified, it causes all the implied - configurations to be built by default. + configurations to be built by default. It is also possible to prevent + any default builds from occuring on this target by using <suppress>true + . This suppresses any local targets, either implicit or explicit, from building. + But, this does not prevent implied targets as required by a dependency by + another target to this one from being built. This is usefull, for example, + for defining a set of libraries generically and having them built only when + another target like an exe is built. Such use might look like: +
+
+lib basic : basic.cpp : : <suppress>true ;

exe test : test.cpp <lib>basic ;
+
+
+ With that the basic library will only be built when the test + executable is built, and only the variations required by the executable + will be built.
+

NOTE: for simple features in both default-BUILD ## : debug release @@ -866,6 +882,8 @@ exe foo : foo.cpp src/bar.cpp <lib>../bazlib/baz

  • ...GCC release builds require optimization for space.
  • Requires multithread support on compilers where it's relevant. + +
  • Adds /usr/local/foolib/include to the #include <*> path

    The default-BUILD section: @@ -896,8 +914,22 @@ variant name : [<toolset-name>]<feature>value.. The variant rule specifies the list of properties comprising a variant. Properties may be optionally qualified with a toolset name, which - specifies that the property applies only to that toolset. Examples can be - found in features.jam. + specifies that the property applies only to that toolset. One or + more parent variants may be specified to inherit the properties  from those + parent(s). For inherited properties precedence is given on a left to right + order, making the immediate properties override those in the parent(s). This + can be used to great effect for describing global properties that are shared + amongst various variants, and therefore targets. For example: +

    +
    +variant my-globals : <rtti>off ;
    +
    +variant my-debug : my-globals debug ;
    +
    +variant mym-release : my-globals releaase ;
    +
    +
    + More examples can be found in features.jam.

    Toolset Description Files

    diff --git a/como-tools.jam b/como-tools.jam index 45c240def..b40379c2d 100644 --- a/como-tools.jam +++ b/como-tools.jam @@ -43,6 +43,8 @@ flags como C++FLAGS ; flags como DEFINES ; flags como UNDEFS ; flags como HDRS ; +flags como STDHDRS ; +flags como LINKFLAGS ; flags como STDHDRS : $(COMO_INCLUDE_PATH) ; flags como STDLIBPATH : $(COMO_STDLIB_PATH)$(SLASH) ; diff --git a/features.jam b/features.jam index 66ee5c77e..7f6ceed21 100644 --- a/features.jam +++ b/features.jam @@ -25,6 +25,7 @@ feature exception-handling : on off ; feature rtti : on off ; free-feature cflags ; +free-feature linkflags ; free-feature cxxflags ; free-feature define ; # PYTHON=foo free-feature undef ; # PYTHON=foo diff --git a/gcc-stlport-tools.jam b/gcc-stlport-tools.jam index d102bdf07..4e6a95647 100644 --- a/gcc-stlport-tools.jam +++ b/gcc-stlport-tools.jam @@ -18,14 +18,17 @@ else STDHDRS = ; STDLIBPATH = ; -flags gcc STDHDRS ; +flags gcc-stlport STDHDRS ; -flags gcc-stlport STDHDRS : $(STLPORT_ROOT)$(SLASH)stlport $(GCC_INCLUDE_DIRECTORY) ; -flags gcc-stlport STDLIBPATH : $(STLPORT_ROOT)$(SLASH)lib $(GCC_STDLIB_DIRECTORY) ; +STLPORT_INCLUDE_DIRECTORY ?= stlport ; +STLPORT_LIB_DIRECTORY ?= lib ; + +flags gcc-stlport STDHDRS : $(STLPORT_ROOT)$(SLASH)$(STLPORT_INCLUDE_DIRECTORY) $(GCC_INCLUDE_DIRECTORY) ; +flags gcc-stlport STDLIBPATH : $(STLPORT_ROOT)$(SLASH)$(STLPORT_LIB_DIRECTORY) $(GCC_STDLIB_DIRECTORY) ; flags gcc-stlport DEFINES debug : _STLP_DEBUG ; -flags gcc-stlport FINDLIBS static/debug : libstlport_$(GCC_STLPORT_LIB_ID)_stldebug ; -flags gcc-stlport FINDLIBS static/release : libstlport_$(GCC_STLPORT_LIB_ID) ; +flags gcc-stlport FINDLIBS static/debug : stlport_$(GCC_STLPORT_LIB_ID)_stldebug ; +flags gcc-stlport FINDLIBS static/release : stlport_$(GCC_STLPORT_LIB_ID) ; flags gcc-stlport FINDLIBS dynamic/debug : stlport_$(GCC_STLPORT_LIB_ID)_stldebug ; flags gcc-stlport FINDLIBS dynamic/release : stlport_$(GCC_STLPORT_LIB_ID) ; flags gcc-stlport CFLAGS dynamic : -D_STLP_USE_DYNAMIC_LIB ; diff --git a/gcc-tools.jam b/gcc-tools.jam index ef69c2207..7fa8548c4 100644 --- a/gcc-tools.jam +++ b/gcc-tools.jam @@ -5,7 +5,7 @@ # to its suitability for any purpose. # compute directories for invoking GCC -local SPACE = " " ; +SPACE ?= " " ; GCC_BIN_DIRECTORY ?= $(GCC_ROOT_DIRECTORY)$(SLASH)bin$(SLASH) ; GCC_BIN_DIRECTORY ?= "" ; # Don't clobber tool names if GCC_ROOT_DIRECTORY not set GCC_INCLUDE_DIRECTORY ?= $(GCC_ROOT_DIRECTORY)$(SLASH)include ; @@ -43,6 +43,7 @@ flags gcc DEFINES ; flags gcc UNDEFS ; flags gcc HDRS ; flags gcc STDHDRS ; +flags gcc LINKFLAGS ; flags gcc STDHDRS : $(GCC_INCLUDE_DIRECTORY) ; flags gcc STDLIBPATH : $(GCC_STDLIB_DIRECTORY) ; diff --git a/intel-linux-tools.jam b/intel-linux-tools.jam index 0b3df0066..e593a4a09 100644 --- a/intel-linux-tools.jam +++ b/intel-linux-tools.jam @@ -65,6 +65,9 @@ flags intel-linux LIBPATH ; flags intel-linux NEEDLIBS ; flags intel-linux FINDLIBS ; +flags intel-linux STDHDRS ; +flags intel-linux LINKFLAGS ; + #### Cc #### rule Cc-action diff --git a/kcc-tools.jam b/kcc-tools.jam index edd2388d6..c747bac1b 100644 --- a/kcc-tools.jam +++ b/kcc-tools.jam @@ -26,6 +26,8 @@ flags kcc C++FLAGS ; flags kcc DEFINES ; flags kcc UNDEFS ; flags kcc HDRS ; +flags kcc STDHDRS ; +flags kcc LINKFLAGS ; flags kcc LIBPATH ; flags kcc NEEDLIBS ; diff --git a/metrowerks-tools.jam b/metrowerks-tools.jam index 15e0b65f1..972844760 100644 --- a/metrowerks-tools.jam +++ b/metrowerks-tools.jam @@ -25,6 +25,7 @@ flags metrowerks DEFINES ; flags metrowerks UNDEFS ; flags metrowerks HDRS ; flags metrowerks STDHDRS ; +flags metrowerks LINKFLAGS ; flags metrowerks CFLAGS on : -g ; flags metrowerks LINKFLAGS on : -g ; diff --git a/mipspro-tools.jam b/mipspro-tools.jam index 93b0788fa..61e81e737 100644 --- a/mipspro-tools.jam +++ b/mipspro-tools.jam @@ -41,6 +41,8 @@ flags mipspro C++FLAGS ; flags mipspro LIBPATH ; flags mipspro NEEDLIBS ; flags mipspro FINDLIBS ; +flags mipspro STDHDRS ; +flags mipspro LINKFLAGS ; #### Link (for C++) #### diff --git a/msvc-tools.jam b/msvc-tools.jam index d62721323..78c86be5b 100644 --- a/msvc-tools.jam +++ b/msvc-tools.jam @@ -51,6 +51,8 @@ flags msvc C++FLAGS ; flags msvc DEFINES ; flags msvc UNDEFS ; flags msvc HDRS ; +flags msvc STDHDRS ; +flags msvc LINKFLAGS ; flags msvc STDHDRS : $(MSVCDir)$(SLASH)include ; flags msvc STDLIBPATH : $(MSVCDir)$(SLASH)lib ; diff --git a/tru64cxx-tools.jam b/tru64cxx-tools.jam index a9bc80dd7..eb61f81d6 100644 --- a/tru64cxx-tools.jam +++ b/tru64cxx-tools.jam @@ -37,6 +37,8 @@ flags tru64cxx C++FLAGS ; flags tru64cxx DEFINES ; flags tru64cxx UNDEFS ; flags tru64cxx HDRS ; +flags tru64cxx STDHDRS ; +flags tru64cxx LINKFLAGS ; # Vincenzo BOOST_COMPATIBILITY ?= $(BOOST_ROOT)$(SLASH)boost$(SLASH)compatibility$(SLASH)cpp_c_headers ; diff --git a/v1/boost-base.jam b/v1/boost-base.jam index dd9a23804..02008a30e 100644 --- a/v1/boost-base.jam +++ b/v1/boost-base.jam @@ -1051,6 +1051,10 @@ rule declare-local-target "$(gTARGET_TYPE($(target-id)))" "$(5)" ; } + # Supress the regular build of this target + local suppress = [ get-values : $(4) ] ; + local gSUPPRESS_FAKE_TARGETS = $(suppress[1]) ; + # Just gather information if we are including a library's Jamfile for a # dependent target. Don't generate build instructions here. if ! $(gIN_LIB_INCLUDE) @@ -1468,17 +1472,7 @@ gGENERATOR_FUNCTION(LIB) = library-file ; # Declare a statically-linked library target. rule lib { - local suppress = [ get-values : $(4) ] ; - if $(suppress) - { - local gSUPPRESS_FAKE_TARGETS = $(suppress[1]) ; - declare-local-target $(<) : $(2) : $(3) : - [ difference $(4) : [ get-properties : $(4) ] ] : LIB ; - } - else - { - declare-local-target $(<) : $(2) : $(3) : $(4) : LIB ; - } + declare-local-target $(<) : $(2) : $(3) : $(4) : LIB ; } # unit-test target : sources : requirements : local-build diff --git a/v1/borland-tools.jam b/v1/borland-tools.jam index 62f53397d..240e40ad3 100644 --- a/v1/borland-tools.jam +++ b/v1/borland-tools.jam @@ -62,6 +62,8 @@ flags borland C++FLAGS ; flags borland DEFINES ; flags borland UNDEFS ; flags borland HDRS ; +flags borland STDHDRS ; +flags borland LINKFLAGS ; flags borland STDHDRS : $(BCCROOT)$(SLASH)include ; flags borland STDLIBPATH : $(BCCROOT)$(SLASH)lib ; diff --git a/v1/build_system.htm b/v1/build_system.htm index 81349e842..3f6dedc7f 100644 --- a/v1/build_system.htm +++ b/v1/build_system.htm @@ -809,7 +809,22 @@ project-root ; When multiple values are specified, it causes all the implied - configurations to be built by default. + configurations to be built by default. It is also possible to prevent + any default builds from occuring on this target by using <suppress>true + . This suppresses any local targets, either implicit or explicit, from building. + But, this does not prevent implied targets as required by a dependency by + another target to this one from being built. This is usefull, for example, + for defining a set of libraries generically and having them built only when + another target like an exe is built. Such use might look like: +
    +
    +lib basic : basic.cpp : : <suppress>true ;

    exe test : test.cpp <lib>basic ;
    +
    +
    + With that the basic library will only be built when the test + executable is built, and only the variations required by the executable + will be built.
    +
  • NOTE: for simple features in both default-BUILD ## : debug release @@ -866,6 +882,8 @@ exe foo : foo.cpp src/bar.cpp <lib>../bazlib/baz

  • ...GCC release builds require optimization for space.
  • Requires multithread support on compilers where it's relevant. + +
  • Adds /usr/local/foolib/include to the #include <*> path

    The default-BUILD section: @@ -896,8 +914,22 @@ variant name : [<toolset-name>]<feature>value.. The variant rule specifies the list of properties comprising a variant. Properties may be optionally qualified with a toolset name, which - specifies that the property applies only to that toolset. Examples can be - found in features.jam. + specifies that the property applies only to that toolset. One or + more parent variants may be specified to inherit the properties  from those + parent(s). For inherited properties precedence is given on a left to right + order, making the immediate properties override those in the parent(s). This + can be used to great effect for describing global properties that are shared + amongst various variants, and therefore targets. For example: +

    +
    +variant my-globals : <rtti>off ;
    +
    +variant my-debug : my-globals debug ;
    +
    +variant mym-release : my-globals releaase ;
    +
    +
    + More examples can be found in features.jam.

    Toolset Description Files

    diff --git a/v1/como-tools.jam b/v1/como-tools.jam index 45c240def..b40379c2d 100644 --- a/v1/como-tools.jam +++ b/v1/como-tools.jam @@ -43,6 +43,8 @@ flags como C++FLAGS ; flags como DEFINES ; flags como UNDEFS ; flags como HDRS ; +flags como STDHDRS ; +flags como LINKFLAGS ; flags como STDHDRS : $(COMO_INCLUDE_PATH) ; flags como STDLIBPATH : $(COMO_STDLIB_PATH)$(SLASH) ; diff --git a/v1/features.jam b/v1/features.jam index 66ee5c77e..7f6ceed21 100644 --- a/v1/features.jam +++ b/v1/features.jam @@ -25,6 +25,7 @@ feature exception-handling : on off ; feature rtti : on off ; free-feature cflags ; +free-feature linkflags ; free-feature cxxflags ; free-feature define ; # PYTHON=foo free-feature undef ; # PYTHON=foo diff --git a/v1/gcc-stlport-tools.jam b/v1/gcc-stlport-tools.jam index d102bdf07..4e6a95647 100644 --- a/v1/gcc-stlport-tools.jam +++ b/v1/gcc-stlport-tools.jam @@ -18,14 +18,17 @@ else STDHDRS = ; STDLIBPATH = ; -flags gcc STDHDRS ; +flags gcc-stlport STDHDRS ; -flags gcc-stlport STDHDRS : $(STLPORT_ROOT)$(SLASH)stlport $(GCC_INCLUDE_DIRECTORY) ; -flags gcc-stlport STDLIBPATH : $(STLPORT_ROOT)$(SLASH)lib $(GCC_STDLIB_DIRECTORY) ; +STLPORT_INCLUDE_DIRECTORY ?= stlport ; +STLPORT_LIB_DIRECTORY ?= lib ; + +flags gcc-stlport STDHDRS : $(STLPORT_ROOT)$(SLASH)$(STLPORT_INCLUDE_DIRECTORY) $(GCC_INCLUDE_DIRECTORY) ; +flags gcc-stlport STDLIBPATH : $(STLPORT_ROOT)$(SLASH)$(STLPORT_LIB_DIRECTORY) $(GCC_STDLIB_DIRECTORY) ; flags gcc-stlport DEFINES debug : _STLP_DEBUG ; -flags gcc-stlport FINDLIBS static/debug : libstlport_$(GCC_STLPORT_LIB_ID)_stldebug ; -flags gcc-stlport FINDLIBS static/release : libstlport_$(GCC_STLPORT_LIB_ID) ; +flags gcc-stlport FINDLIBS static/debug : stlport_$(GCC_STLPORT_LIB_ID)_stldebug ; +flags gcc-stlport FINDLIBS static/release : stlport_$(GCC_STLPORT_LIB_ID) ; flags gcc-stlport FINDLIBS dynamic/debug : stlport_$(GCC_STLPORT_LIB_ID)_stldebug ; flags gcc-stlport FINDLIBS dynamic/release : stlport_$(GCC_STLPORT_LIB_ID) ; flags gcc-stlport CFLAGS dynamic : -D_STLP_USE_DYNAMIC_LIB ; diff --git a/v1/gcc-tools.jam b/v1/gcc-tools.jam index ef69c2207..7fa8548c4 100644 --- a/v1/gcc-tools.jam +++ b/v1/gcc-tools.jam @@ -5,7 +5,7 @@ # to its suitability for any purpose. # compute directories for invoking GCC -local SPACE = " " ; +SPACE ?= " " ; GCC_BIN_DIRECTORY ?= $(GCC_ROOT_DIRECTORY)$(SLASH)bin$(SLASH) ; GCC_BIN_DIRECTORY ?= "" ; # Don't clobber tool names if GCC_ROOT_DIRECTORY not set GCC_INCLUDE_DIRECTORY ?= $(GCC_ROOT_DIRECTORY)$(SLASH)include ; @@ -43,6 +43,7 @@ flags gcc DEFINES ; flags gcc UNDEFS ; flags gcc HDRS ; flags gcc STDHDRS ; +flags gcc LINKFLAGS ; flags gcc STDHDRS : $(GCC_INCLUDE_DIRECTORY) ; flags gcc STDLIBPATH : $(GCC_STDLIB_DIRECTORY) ; diff --git a/v1/intel-linux-tools.jam b/v1/intel-linux-tools.jam index 0b3df0066..e593a4a09 100644 --- a/v1/intel-linux-tools.jam +++ b/v1/intel-linux-tools.jam @@ -65,6 +65,9 @@ flags intel-linux LIBPATH ; flags intel-linux NEEDLIBS ; flags intel-linux FINDLIBS ; +flags intel-linux STDHDRS ; +flags intel-linux LINKFLAGS ; + #### Cc #### rule Cc-action diff --git a/v1/kcc-tools.jam b/v1/kcc-tools.jam index edd2388d6..c747bac1b 100644 --- a/v1/kcc-tools.jam +++ b/v1/kcc-tools.jam @@ -26,6 +26,8 @@ flags kcc C++FLAGS ; flags kcc DEFINES ; flags kcc UNDEFS ; flags kcc HDRS ; +flags kcc STDHDRS ; +flags kcc LINKFLAGS ; flags kcc LIBPATH ; flags kcc NEEDLIBS ; diff --git a/v1/metrowerks-tools.jam b/v1/metrowerks-tools.jam index 15e0b65f1..972844760 100644 --- a/v1/metrowerks-tools.jam +++ b/v1/metrowerks-tools.jam @@ -25,6 +25,7 @@ flags metrowerks DEFINES ; flags metrowerks UNDEFS ; flags metrowerks HDRS ; flags metrowerks STDHDRS ; +flags metrowerks LINKFLAGS ; flags metrowerks CFLAGS on : -g ; flags metrowerks LINKFLAGS on : -g ; diff --git a/v1/mipspro-tools.jam b/v1/mipspro-tools.jam index 93b0788fa..61e81e737 100644 --- a/v1/mipspro-tools.jam +++ b/v1/mipspro-tools.jam @@ -41,6 +41,8 @@ flags mipspro C++FLAGS ; flags mipspro LIBPATH ; flags mipspro NEEDLIBS ; flags mipspro FINDLIBS ; +flags mipspro STDHDRS ; +flags mipspro LINKFLAGS ; #### Link (for C++) #### diff --git a/v1/msvc-tools.jam b/v1/msvc-tools.jam index d62721323..78c86be5b 100644 --- a/v1/msvc-tools.jam +++ b/v1/msvc-tools.jam @@ -51,6 +51,8 @@ flags msvc C++FLAGS ; flags msvc DEFINES ; flags msvc UNDEFS ; flags msvc HDRS ; +flags msvc STDHDRS ; +flags msvc LINKFLAGS ; flags msvc STDHDRS : $(MSVCDir)$(SLASH)include ; flags msvc STDLIBPATH : $(MSVCDir)$(SLASH)lib ; diff --git a/v1/tru64cxx-tools.jam b/v1/tru64cxx-tools.jam index a9bc80dd7..eb61f81d6 100644 --- a/v1/tru64cxx-tools.jam +++ b/v1/tru64cxx-tools.jam @@ -37,6 +37,8 @@ flags tru64cxx C++FLAGS ; flags tru64cxx DEFINES ; flags tru64cxx UNDEFS ; flags tru64cxx HDRS ; +flags tru64cxx STDHDRS ; +flags tru64cxx LINKFLAGS ; # Vincenzo BOOST_COMPATIBILITY ?= $(BOOST_ROOT)$(SLASH)boost$(SLASH)compatibility$(SLASH)cpp_c_headers ; diff --git a/v1/vacpp-tools.jam b/v1/vacpp-tools.jam index 07c48a60e..ca9ad8c23 100644 --- a/v1/vacpp-tools.jam +++ b/v1/vacpp-tools.jam @@ -31,6 +31,8 @@ flags xlc C++FLAGS ; flags xlc DEFINES ; flags xlc UNDEFS ; flags xlc HDRS ; +flags xlc STDHDRS ; +flags xlc LINKFLAGS ; #### Link #### diff --git a/vacpp-tools.jam b/vacpp-tools.jam index 07c48a60e..ca9ad8c23 100644 --- a/vacpp-tools.jam +++ b/vacpp-tools.jam @@ -31,6 +31,8 @@ flags xlc C++FLAGS ; flags xlc DEFINES ; flags xlc UNDEFS ; flags xlc HDRS ; +flags xlc STDHDRS ; +flags xlc LINKFLAGS ; #### Link ####