class MxxRu::Cpp::Lib_or_dll_target

Base class for targets that may be lib or dll, or MacOS bundle.

In that cases for a project should be defined special target class. The class constructor should define two blocks:

Starting from version 1.4.10 this approach could also be used for bulding MacOS bundles.

For example:

class Prj < MxxRu::Cpp::LibOrDllTarget
  TAG = "threads_1/prj.rb"
  def initialize( a_alias = TAG )
    super( a_alias, TAG )

    target( "threads.1.3" )

    threading_mode( MxxRu::Cpp::THREADING_MULTI )

    init_dll_block(
      Proc.new {
        rtl_mode( MxxRu::Cpp::RTL_SHARED )
        implib_path( "lib" )
        define( "THREADS_1__DLL", OPT_UPSPREAD )
      })
    # This is avaliable from v.1.4.10
    init_macos_bundle_block(
      Proc.new {
        rtl_mode( MxxRu::Cpp::RTL_SHARED )
      }
    )

    cpp_source( "threads.cpp" )
    cpp_source( "micro_time.cpp" )

    if toolset.tag( "target_os" ) == "mswin"
      define( "__WIN32__" )
      cpp_source( "win32/os_thread.cpp" )
    elsif toolset.tag( "target_os" ) == "unix"
      cpp_source( "posix/os_thread.cpp" )
    end

    define( "THREADS_1__PRJ" )
  end
end

After definition of such class for the target, project may allow to use itself by the other projects using two methods.

Manual execution of as_lib, as_dll, as_macos_bundle methods

If project defines one class only, inherited from LibOrDllTarget, then all clients of that project should explicitly call as_lib or as_dll, or as_macos_bundle method during a reference to required_prj:

class MyPrj < MxxRu::Cpp::ExeTarget
  def initialize( a_alias = "my_prj.rb" )
    super( a_alias )
    required_prj( "threads_1/prj.rb" ).as_dll( self )
  end
end

Such approach is not good because if in composite project several projects at the same time uses threads_1/prj.rb, then in one of them it's easy to forget to call as_dll. And it wouldn't be incorrect, because as_dll may be called by other projects in composite project.

Definition of auxiliary target classes

To make usage of target that may be lib or dll easier, project may define two auxiliary classes, which would call methods as_lib, as_dll and as_macos_bundle inside their constructors:

class Prj < MxxRu::Cpp::LibOrDllTarget
  def initialize( a_alias = "threads_1/prj.rb" )
    super( a_alias, "threads_1" )
    ...
  end
end
class Lib < Prj
  def super( a_alias = "threads_1/lib.rb" )
    super( a_alias )
    as_lib
  end
end
class Dll < Prj
  def super( a_alias = "threads_1/dll.rb" )
    super( a_alias )
    as_dll
  end
end
class MacOSBundle < Prj
  def super( a_alias = "threads_1/macos_bundle.rb" )
    super( a_alias )
    as_macos_bundle
  end
end

Then for using the target it would be enough to do that:

class MyPrj < MxxRu::Cpp::ExeTarget
  def initialize( a_alias = "my_prj.rb" )
    super( a_alias )
    required_prj( "threads_1/dll.rb" )
  end
end

Constants

Type_already_defined_ex

Exception type, which is thrown if target type was already defined.

Type_not_defined_ex

Exception type, which is thrown if target type is undefined.

Public Class Methods

new( a_prj_alias, a_prj_tag ) click to toggle source

Constructor.

a_prj_alias

Project alias.

a_prj_tag

Unique value, which identifies target given. This value used to avoid conflicts in the next situations:

class Prj < MxxRu::Cpp::LibOrDllTarget ... end
class Lib < Prj ... end
class Dll < Prj ... end
class MacOSBundle < Prj ... end
class MyExe < MxxRu::Cpp::ExeTarget
  def initialize( a_alias = "my_exe.rb" )
    super( a_alias )
    required_prj( "threads_1/dll.rb" )
  end
end
class MyDll < MxxRu::Cpp::DllTarget
  def initialize( a_alias = "my_dll.rb" )
    super( a_alias )
    required_prj( "threads_1/lib.rb" )
  end
end

If both MyExe and MyDll are used in one composite project, then it's a conflict of usage of threads_1/dll.rb and threads_1/lib.rb.

Calls superclass method MxxRu::Cpp::Target::new
# File lib/mxx_ru/cpp/target.rb, line 1391
def initialize( a_prj_alias, a_prj_tag )
  super( a_prj_alias )

  @mxx_prj_tag = a_prj_tag

  # Block, which is run if lib is a target.
  @mxx_init_lib_block = nil
  # Block, which is run if dll is a target.
  @mxx_init_dll_block = nil
  # Block, which is run if MacOS bundle is a target.
  @mxx_init_macos_bundle_block = nil
  # Target type should be defined or by as_lib method, or by as_dll method,
  # or by as_macos_bundle.
  @mxx_target_type = nil

end

Public Instance Methods

as_dll() click to toggle source

Set dll as target type.

# File lib/mxx_ru/cpp/target.rb, line 1419
def as_dll
  if ensure_type_not_set_yet( DllTargetType::TYPE )
    @mxx_target_type = DllTargetType.new
    if nil != @mxx_init_dll_block
      @mxx_init_dll_block.call
    end
  end
end
as_lib() click to toggle source

Set lib as target type.

# File lib/mxx_ru/cpp/target.rb, line 1409
def as_lib
  if ensure_type_not_set_yet( LibTargetType::TYPE )
    @mxx_target_type = LibTargetType.new
    if nil != @mxx_init_lib_block
      @mxx_init_lib_block.call
    end
  end
end
as_macos_bundle() click to toggle source

Set MacOS bundle as target type.

# File lib/mxx_ru/cpp/target.rb, line 1429
def as_macos_bundle
  if ensure_type_not_set_yet( MacOSBundleTargetType::TYPE )
    @mxx_target_type = MacOSBundleTargetType.new
    if nil != @mxx_init_macos_bundle_block
      @mxx_init_macos_bundle_block.call
    end
  end
end
target_type() click to toggle source

Return current value of mxx_target_type.

# File lib/mxx_ru/cpp/target.rb, line 1439
def target_type
  if nil == @mxx_target_type
    raise TypeNotDefinedEx.new( prj_alias )
  end

  return @mxx_target_type
end

Protected Instance Methods

init_dll_block( a_block ) click to toggle source

Set initialization block for dll. This block will be executed in as_dll method.

# File lib/mxx_ru/cpp/target.rb, line 1456
def init_dll_block( a_block )
  @mxx_init_dll_block = a_block
end
init_lib_block( a_block ) click to toggle source

Set initialization block for lib. This block will be executed in as_lib method.

# File lib/mxx_ru/cpp/target.rb, line 1450
def init_lib_block( a_block )
  @mxx_init_lib_block = a_block
end
init_macos_bundle_block( a_block ) click to toggle source

Set initialization block for MacOS bundle. This block will be executed in as_macos_bundle method.

# File lib/mxx_ru/cpp/target.rb, line 1462
def init_macos_bundle_block( a_block )
  @mxx_init_macos_bundle_block = a_block
end

Private Instance Methods

ensure_type_not_set_yet( a_type_name ) click to toggle source

If someone already defined other target type, exception is thrown. If already defined target type is the same, false returned. If target type is not defined, true is returned.

a_type_name

Name of target type defined.

# File lib/mxx_ru/cpp/target.rb, line 1472
def ensure_type_not_set_yet( a_type_name )
  if @@mxx_tags.key?( @mxx_prj_tag ) &&
    @@mxx_tags[ @mxx_prj_tag ] != a_type_name
    raise TypeAlreadyDefinedEx.new(
      @mxx_prj_tag, a_type_name )
  end

  @@mxx_tags[ @mxx_prj_tag ] = a_type_name

  return ( nil == @mxx_target_type )
end