Class: MxxRu::Cpp::Target

Inherits:
BinaryTarget show all
Defined in:
lib/mxx_ru/cpp/target.rb,
lib/mxx_ru/cpp/toolsets/vc8_family.rb

Overview

Expand class Target to store source and actual manifest descriptions.

Direct Known Subclasses

CompositeTarget, ExeTarget, LibOrDllTarget

Defined Under Namespace

Classes: GlobalObjPlacementInfo

Constant Summary collapse

Global_obj_placement_info =

For compatibility with previous versions.

GlobalObjPlacementInfo
OPT_UPSPREAD =

Attribute that the option should be upspreadable.

"upspread"
OPT_LOCAL =

Attribute that the option should be local.

"local"
@@mxx_runtime_mode =

Runtime mode storage.

GlobalSingleValueOption.new(
"runtime_mode", RUNTIME_DEFAULT,
[ RUNTIME_RELEASE, RUNTIME_DEBUG ] )
@@mxx_rtti_mode =

RTTI mode storage.

GlobalSingleValueOption.new(
"rtti_mode", RTTI_DEFAULT,
[ RTTI_ENABLED, RTTI_DISABLED ] )
@@mxx_rtl_mode =

RTL mode storage.

GlobalSingleValueOption.new(
"rtl_mode", RTL_DEFAULT,
[ RTL_SHARED, RTL_STATIC ] )
@@mxx_threading_mode =

Threading mode storage.

GlobalSingleValueOption.new(
"threading_mode", THREADING_DEFAULT,
[ THREADING_MULTI, THREADING_SINGLE ] )
@@mxx_global_obj_placement =

The storage of global description of obj_placement.

GlobalObjPlacementInfo.new

Instance Attribute Summary collapse

Attributes inherited from AbstractTarget

#mxx_full_targets_names, #mxx_generators, #mxx_required_prjs

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from BinaryTarget

check_libraries_types, #lib, #lib_shared, #lib_static, #mxx_add_required_lib, #mxx_add_required_lib_path, #mxx_required_lib_paths, #mxx_required_libs

Methods inherited from AbstractTarget

define_plural_form_method, #generator, #mxx_add_full_target_name, #prj_alias, #required_prj, run

Constructor Details

#initialize(a_prj_alias) ⇒ Target

Constructor

a_prj_alias

Project identifier.



626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
# File 'lib/mxx_ru/cpp/target.rb', line 626

def initialize( a_prj_alias )

  super( a_prj_alias )

  @mxx_target_root = ""

  @mxx_target_exe = nil

  @mxx_sources_root = File.dirname( a_prj_alias )

  @mxx_screen_mode = SCREEN_CONSOLE

  @mxx_c_files = Array.new
  @mxx_cpp_files = Array.new

  @mxx_mswin_rc_file = nil
  @mxx_mswin_res_file = nil

  @mxx_obj_files = Array.new

  # The storage of local options.
  # The key is a String, the value is SpreadableOption.
  @mxx_locals = Hash.new

  @mxx_implib_path = nil

  # Object, which defines accommodation of object files.
  @mxx_obj_placement = nil

  @mxx_target_name = nil

  @mxx_optimization = OPTIM_SPEED

  # Result of work of the previous reference to a build method.
  # During a repeted calls of build method target build is not performed,
  # and this value is returned.
  @mxx_last_build_result = nil

  # True if toolset has completely defined all compiler and linker options required.
  @mxx_all_options_defined = false

  @mxx_encoding = Encoding.find("Binary")

  Target::initialize_spreadable_option_instance_variables( self )
end

Instance Attribute Details

#mxx_c_filesObject (readonly)

The list of source C-files. Array of MxxRu::Cpp::CppSourceFile objects.



489
490
491
# File 'lib/mxx_ru/cpp/target.rb', line 489

def mxx_c_files
  @mxx_c_files
end

#mxx_cpp_filesObject (readonly)

The list of source C++-files. Array of MxxRu::Cpp::CppSourceFile objects.



492
493
494
# File 'lib/mxx_ru/cpp/target.rb', line 492

def mxx_cpp_files
  @mxx_cpp_files
end

#mxx_encodingObject (readonly)

Default encoding source files.



512
513
514
# File 'lib/mxx_ru/cpp/target.rb', line 512

def mxx_encoding
  @mxx_encoding
end

#mxx_implib_pathObject (readonly)

Import library folder. May contain nil value.



505
506
507
# File 'lib/mxx_ru/cpp/target.rb', line 505

def mxx_implib_path
  @mxx_implib_path
end

#mxx_mswin_rc_fileObject (readonly)

Name of mswin resource file. Should be object of MxxRu::Cpp::MswinRcFile type. May contain nil value, if resources are not used.



498
499
500
# File 'lib/mxx_ru/cpp/target.rb', line 498

def mxx_mswin_rc_file
  @mxx_mswin_rc_file
end

#mxx_mswin_res_fileObject (readonly)

The name of compiled mswin resource file. Should be a string. May contain nil value, if resources are not used.



502
503
504
# File 'lib/mxx_ru/cpp/target.rb', line 502

def mxx_mswin_res_file
  @mxx_mswin_res_file
end

#mxx_obj_filesObject (readonly)

Object files list.



494
495
496
# File 'lib/mxx_ru/cpp/target.rb', line 494

def mxx_obj_files
  @mxx_obj_files
end

#mxx_optimizationObject (readonly)

Optimization mode. By default, speed optimization is used.



510
511
512
# File 'lib/mxx_ru/cpp/target.rb', line 510

def mxx_optimization
  @mxx_optimization
end

#mxx_screen_modeObject (readonly)

Screen mode. Console by default.



486
487
488
# File 'lib/mxx_ru/cpp/target.rb', line 486

def mxx_screen_mode
  @mxx_screen_mode
end

#mxx_sources_rootObject (readonly)

Path, the names of source files are related to.



484
485
486
# File 'lib/mxx_ru/cpp/target.rb', line 484

def mxx_sources_root
  @mxx_sources_root
end

#mxx_target_extObject (readonly)

Custom extension for target. NIL, if custom extension not defined.



482
483
484
# File 'lib/mxx_ru/cpp/target.rb', line 482

def mxx_target_ext
  @mxx_target_ext
end

#mxx_target_nameObject (readonly)

The name to get target result. Should not contain file extension.



508
509
510
# File 'lib/mxx_ru/cpp/target.rb', line 508

def mxx_target_name
  @mxx_target_name
end

#mxx_target_prefixObject (readonly)

Custom prefix for target. NIL, if custom prefix not defined.

Since v.1.4.2



479
480
481
# File 'lib/mxx_ru/cpp/target.rb', line 479

def mxx_target_prefix
  @mxx_target_prefix
end

#mxx_target_rootObject (readonly)

Path, the name of result of a target is related to. If contains an empty value, target should be defined using a full path. Otherwise the value of mxx_target_root is concatenated with a given target name.



474
475
476
# File 'lib/mxx_ru/cpp/target.rb', line 474

def mxx_target_root
  @mxx_target_root
end

#vc8_actual_manifestObject

Returns the value of attribute vc8_actual_manifest.



55
56
57
# File 'lib/mxx_ru/cpp/toolsets/vc8_family.rb', line 55

def vc8_actual_manifest
  @vc8_actual_manifest
end

Class Method Details

.define_spreadable_option_methods(option) ⇒ Object

Generator for methods to manipulation of options those can be ‘global’, ‘local’ and ‘upspread’.

For each option generates following stuff:

# Global values container.
@@mxx_global_<option> = []
# Local and opspread values container.
@mxx_<option> = SpreadableOption.new(...)
# Setter for global values.
def global_<option>( value ); ...; end
# Setter for local values.
def <option>( value, mode ); ...; end
# Getter for all values (including global, local and upspread).
def mxx_all_<option>s; ...; end
# Getter for upspread values only.
def mxx_all_upspread_<option>s; ...; end


559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
# File 'lib/mxx_ru/cpp/target.rb', line 559

def self.define_spreadable_option_methods( option )

  global_container_name = "@@mxx_globals_#{option}"
  local_container_name = "@mxx_#{option}"
  global_setter_name = "global_#{option}"
  local_setter_name = "#{option}"
  all_getter_name = "mxx_all_#{option}s"
  upspread_getter_name = "mxx_all_upspread_#{option}s"

  metaprogram = %Q{
    #{global_container_name} = []

    def #{global_setter_name}( value )
      #{global_container_name} << value
      SpreadableOption::refresh_option_change_time( :'#{option}' )
    end

    def #{local_setter_name}(
        value,
        mode = Target::OPT_LOCAL )
      #{local_container_name}.add( value, mode )
    end

    def #{all_getter_name}()
      return #{local_container_name}.all(
          #{global_container_name},
          mxx_required_prjs,
          :'#{upspread_getter_name}' )
    end

    def #{upspread_getter_name}()
      return #{local_container_name}.all_upspreads(
          mxx_required_prjs,
          :'#{upspread_getter_name}' )
    end
  }

  class_eval metaprogram
end

.global_option_methods(option, getter = :withgetter) ⇒ Object

Generator for methods to manipulation with ‘runtime_mode’, ‘rtti_mode’, ‘rtl_mode’, ‘threading_mode’ and so on.

By default generates 3 methods:

# Setter
def <option>( value ); ...; end
# Setter for default value.
def default_<option>( value ); ...; end
# Getter
def mxx_<option>; ...; end

If no_getter == :nogetter then getter method not generated.



526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
# File 'lib/mxx_ru/cpp/target.rb', line 526

def self.global_option_methods( option, getter = :withgetter )
  class_eval %Q{
    def #{option}( value )
      @@mxx_#{option}.change( value, prj_alias )
    end
    def default_#{option}( value )
      @@mxx_#{option}.change_default( value, prj_alias )
    end
  }
  class_eval %Q{
    def mxx_#{option}
      @@mxx_#{option}.value
    end
  } unless getter == :nogetter
end

.initialize_spreadable_option_instance_variables(target) ⇒ Object

Initializator for all instance variables created by self.define_spreadable_option_methods().

Must be called in constructor.



604
605
606
607
608
609
610
# File 'lib/mxx_ru/cpp/target.rb', line 604

def self.initialize_spreadable_option_instance_variables( target )
  class_variables.grep( /^@@mxx_globals_/ ) do |g|
    option = /^@@mxx_globals_(.+)$/.match(g)[ 1 ]
    name = "@mxx_#{option}"
    target.instance_variable_set( name, SpreadableOption.new( option ) )
  end
end

Instance Method Details

#buildObject

Perform build of the target.



906
907
908
909
910
911
912
913
914
915
916
917
918
919
# File 'lib/mxx_ru/cpp/target.rb', line 906

def build
  if nil == @mxx_last_build_result

    check_all_options_definition

    builder = self.method( :normal_mode_builder )
    builder = self.method( :option_extraction_mode_builder ) \
        if MxxRu::Cpp::Mode.instance.is_option_extraction
      
    @mxx_last_build_result = builder.call
  end

  return @mxx_last_build_result
end

#c_source(a_file_name, a_options = nil) ⇒ Object

Add one C-file to the target.

Note: if a_file_name contains prefix equal to current sources_root than mxx_ru does not add sources_root to name of file. For example:

MxxRu::Cpp::exe_target( 'some/module/prj.rb' ) {
  ...
  c_source 'f1.c' # become 'some/module/f1.c'
  c_source 'some/module/impl/f2.c' # remains 'some/module/impl/f2.c

This approach will be useful with Dir.glob:

MxxRu::Cpp::exe_target( 'some/module/prj.rb' ) {
  ...
  c_sources Dir.glob( 'some/module/**/*.c' )
}
a_file_name

The name of a file added.

a_options

Optional list of a compiler options for that file. When command line would be created, this options would be concatenated with others.



829
830
831
832
# File 'lib/mxx_ru/cpp/target.rb', line 829

def c_source( a_file_name, a_options = nil )
  @mxx_c_files.push( CppSourceFile.new(
    create_full_src_file_name( a_file_name ), a_options ) )
end

#cleanObject

Perform target’s cleanup.



922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
# File 'lib/mxx_ru/cpp/target.rb', line 922

def clean
  if nil == @mxx_last_build_result

    check_all_options_definition

    cleaner = self.method( :normal_mode_cleaner )
    cleaner = self.method( :option_extraction_mode_cleaner ) \
        if MxxRu::Cpp::Mode.instance.is_option_extraction

    cleaner.call

    @mxx_last_build_result = MxxRu::TargetState.new(
      MxxRu::TargetState::ABSENT )
  end
end

#cpp_source(a_file_name, a_options = nil) ⇒ Object

Add one C++-file to the target.

Note: if a_file_name contains prefix equal to current sources_root than mxx_ru does not add sources_root to name of file. For example:

MxxRu::Cpp::exe_target( 'some/module/prj.rb' ) {
  ...
  cpp_source 'f1.cpp' # become 'some/module/f1.cpp'
  cpp_source 'some/module/impl/f2.cpp' # remains 'some/module/impl/f2.cpp

This approach will be useful with Dir.glob:

MxxRu::Cpp::exe_target( 'some/module/prj.rb' ) {
  ...
  cpp_sources Dir.glob( 'some/module/**/*.cpp' )
}
a_file_name

The name of a file added.

a_options

Optional list of a compiler options for that file. When command line would be created, this options would be concatenated with others.



852
853
854
855
# File 'lib/mxx_ru/cpp/target.rb', line 852

def cpp_source( a_file_name, a_options = nil )
  @mxx_cpp_files.push( CppSourceFile.new(
    create_full_src_file_name( a_file_name ), a_options ) )
end

#create_full_result_target_file_nameObject

Creation of complete result target file name.

Result target file name depends on ObjPlacement and Toolset.



984
985
986
987
988
989
990
# File 'lib/mxx_ru/cpp/target.rb', line 984

def create_full_result_target_file_name
  do_target_type_depending_actions(
      :lib => lambda { |toolset| toolset.full_lib_name( self ) },
      :dll => lambda { |toolset| toolset.full_dll_name( self ) },
      :macos_bundle => lambda { |toolset| toolset.full_dll_name( self ) },
      :exe => lambda { |toolset| toolset.full_exe_name( self ) } )
end

#create_full_src_file_name(a_file_name) ⇒ Object

Creation of a complete name of a source file taking the value of mxx_sources_root into account

If a_file_name starts with current value of mxx_sources_root than a_file_name remains unchanged.



968
969
970
971
972
973
974
975
976
977
978
# File 'lib/mxx_ru/cpp/target.rb', line 968

def create_full_src_file_name( a_file_name )
  if "" == mxx_sources_root
    return a_file_name
  else
    if a_file_name[ 0..mxx_sources_root.size ] == mxx_sources_root + '/'
      return a_file_name
    else
      return File.join( [ mxx_sources_root, a_file_name ] )
    end
  end
end

#create_full_target_file_name(a_file_name) ⇒ Object

Creation of a complete name of a resulting file taking the value of mxx_target_root into account



955
956
957
958
959
960
961
# File 'lib/mxx_ru/cpp/target.rb', line 955

def create_full_target_file_name( a_file_name )
  if "" == mxx_target_root
    return a_file_name
  else
    return File.join( [ mxx_target_root, a_file_name ] )
  end
end

#global_obj_placement(a_placement) ⇒ Object

Set global obj_placement. If gloval obj_placement was already set before, exception is thrown.



712
713
714
# File 'lib/mxx_ru/cpp/target.rb', line 712

def global_obj_placement( a_placement )
  @@mxx_global_obj_placement.change( a_placement, prj_alias )
end

#implib_path(name) ⇒ Object

Set import library location.



886
887
888
# File 'lib/mxx_ru/cpp/target.rb', line 886

def implib_path( name )
  @mxx_implib_path = name.clone
end

#mswin_rc_file(a_rc_file, a_depends = nil) ⇒ Object

Set mswin resource file name.

a_rc_file

The name of rc-file.

a_depends

Optional dependencies list. Should be Array of String.



866
867
868
869
870
871
872
873
# File 'lib/mxx_ru/cpp/target.rb', line 866

def mswin_rc_file(
  a_rc_file,
  a_depends =nil )

  @mxx_mswin_rc_file = MswinRcFile.new(
      create_full_src_file_name( a_rc_file ),
      a_depends )
end

#mswin_res_file(a_res_file) ⇒ Object

Set compiled mswin resource file name.



876
877
878
# File 'lib/mxx_ru/cpp/target.rb', line 876

def mswin_res_file( a_res_file )
  @mxx_mswin_res_file = String.new( a_res_file )
end

#mxx_obj_placementObject

Get obj_placement object, which should be used.

If both global and local obj_placement are set, exception is thrown.

If global or local obj_placement is defined, it is returned.

If nor global nor local obj_placement is set, local obj_placement is created with a help of MxxRu::Cpp::default_obj_placement function and it’s returned.



731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
# File 'lib/mxx_ru/cpp/target.rb', line 731

def mxx_obj_placement
  if nil != @mxx_obj_placement &&
    nil != @@mxx_global_obj_placement.placement
    raise MxxRu::InvalidValueEx.new(
      "Global and local obj_placement object exists! " +
      "Global created by: #{@@mxx_global_obj_placement.who}. " +
      "Local created by: #{prj_alias}" )
  end

  if nil != @@mxx_global_obj_placement.placement
    return @@mxx_global_obj_placement.placement
  end

  if nil == @mxx_obj_placement
    @mxx_obj_placement = MxxRu::Cpp::default_obj_placement
  end

  return @mxx_obj_placement
end

#mxx_runtime_modeObject

runtime_mode accessor (custom implementation).



683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
# File 'lib/mxx_ru/cpp/target.rb', line 683

def mxx_runtime_mode
  # If runtime_mode is set to RUNTIME_DEFAULT (i.e.
  # wasn't changed in a projects), then check of command line options
  # is required (--mxx-cpp-release, --mxx-cpp-debug).
  result = @@mxx_runtime_mode.value
  if @@mxx_runtime_mode.default_value == result
    if MxxRu::Cpp::Mode.instance.is_release &&
      MxxRu::Cpp::Mode.instance.is_debug
      # This is an invalid combination of flags.
      raise MxxRu::InvalidValueEx.new(
        "#{MxxRu::Cpp::MXXCPPARG_RELEASE} and " +
        "#{MxxRu::Cpp::MXXCPPARG_DEBUG} cannot be used " +
        "together" )
    elsif MxxRu::Cpp::Mode.instance.is_release
      result = RUNTIME_RELEASE
    elsif MxxRu::Cpp::Mode.instance.is_debug
      result = RUNTIME_DEBUG
    end
  end

  return result
end

#obj_file(file_name) ⇒ Object

Add object file to the target.



881
882
883
# File 'lib/mxx_ru/cpp/target.rb', line 881

def obj_file( file_name )
  @mxx_obj_files.push( String.new( file_name ) )
end

#obj_placement(a_placement) ⇒ Object

Set local obj_placement. It’s impossible to simultaneously set global and local obj_placement.



718
719
720
# File 'lib/mxx_ru/cpp/target.rb', line 718

def obj_placement( a_placement )
  @mxx_obj_placement = a_placement
end

#optimization(a_mode) ⇒ Object

Set optimization mode required.



891
892
893
894
895
896
897
898
# File 'lib/mxx_ru/cpp/target.rb', line 891

def optimization( a_mode )
  if OPTIM_SIZE != a_mode && OPTIM_SPEED != a_mode
    raise MxxRu::InvalidValueEx.new(
      "Unknown optimization mode: '#{a_mode}'" )
  else
    @mxx_optimization = a_mode.clone
  end
end

#resetObject

Reset build status to enable rebuild.



939
940
941
942
943
944
# File 'lib/mxx_ru/cpp/target.rb', line 939

def reset
  if @mxx_last_build_result 
    reset_required_projects
    @mxx_last_build_result = nil
  end
end

#screen_mode(a_mode) ⇒ Object

Set screen mode.



802
803
804
805
806
807
808
809
# File 'lib/mxx_ru/cpp/target.rb', line 802

def screen_mode( a_mode )
  if SCREEN_CONSOLE == a_mode || SCREEN_WINDOW == a_mode
    @mxx_screen_mode = a_mode
  else
    raise MxxRu::UnsupportedModeEx.new(
      "Unsupported screen mode: #{a_mode}" )
  end
end

#source_encoding(a_encoding) ⇒ Object

Set encoding source files.



901
902
903
# File 'lib/mxx_ru/cpp/target.rb', line 901

def source_encoding( a_encoding )
  @mxx_encoding = Encoding.find("#{a_encoding}")
end

#sources_root(a_root) ⇒ Object

Change source files path. If empty string is set, then full file names are required. If block is defined, then path is changed only during a block execution, then old path value is restored.

Returns previous mxx_sources_root value. Is actual for a case, when method is called without block parameter.



788
789
790
791
792
793
794
795
796
797
798
799
# File 'lib/mxx_ru/cpp/target.rb', line 788

def sources_root( a_root )
  old_root = @mxx_sources_root.clone
  if block_given?
    @mxx_sources_root = File.join( [ @mxx_sources_root, a_root ] )
    yield
    @mxx_sources_root = old_root
  else
    @mxx_sources_root = a_root
  end

  return old_root
end

#target(a_target) ⇒ Object

Set a name from which target name would be created.



766
767
768
# File 'lib/mxx_ru/cpp/target.rb', line 766

def target( a_target )
  @mxx_target_name = create_full_target_file_name( a_target )
end

#target_ext(ext) ⇒ Object Also known as: target_suffix

Set a custom extension for target.



776
777
778
# File 'lib/mxx_ru/cpp/target.rb', line 776

def target_ext( ext )
  @mxx_target_ext = ext
end

#target_prefix(ext) ⇒ Object

Set a custom prefix for target.



771
772
773
# File 'lib/mxx_ru/cpp/target.rb', line 771

def target_prefix( ext )
  @mxx_target_prefix = ext
end

#target_root(a_root) ⇒ Object

Change path, the names of target results are related to.

NOTE: This method should be called BEFORE target method!

If target_root is called after target method, then a_root given is added to the name already was set.



757
758
759
760
761
762
763
# File 'lib/mxx_ru/cpp/target.rb', line 757

def target_root( a_root )
  @mxx_target_root = a_root
  if @mxx_target_name
    @mxx_target_name = File.join(
      [ @mxx_target_root, @mxx_target_name ] )
  end
end

#target_typeObject

Get the target type. Should be overloaded in child classes. Object, inherited from MxxRu::Cpp::TargetType is returned.

Raises:



949
950
951
# File 'lib/mxx_ru/cpp/target.rb', line 949

def target_type
  raise AbstractMethodEx.new( "MxxRu::Cpp::Target::target_type" )
end

#toolsetObject

A simple way to get access to the toolset. In a class, inherited from MxxRu::Cpp::Target is more convinient to call toolset method, instead of MxxRu::Cpp::toolset function. Just calling MxxRu::Cpp::toolset function.



676
677
678
# File 'lib/mxx_ru/cpp/target.rb', line 676

def toolset()
  return MxxRu::Cpp::toolset()
end

#vc8_source_manifestObject

Get source manifest description. If target has no manifest then default manifest will be returned.



42
43
44
45
46
47
48
# File 'lib/mxx_ru/cpp/toolsets/vc8_family.rb', line 42

def vc8_source_manifest
  if nil != @vc8_source_manifest
    @vc8_source_manifest
  else
    MxxRu::Cpp::Toolsets::Vc8Family::default_manifest
  end
end

#vc8_source_manifest=(manifest) ⇒ Object

Setter for source manifest description.



51
52
53
# File 'lib/mxx_ru/cpp/toolsets/vc8_family.rb', line 51

def vc8_source_manifest=( manifest )
  @vc8_source_manifest = manifest
end