class MxxRu::Cpp::Toolsets::Vc_family

Toolset implemetation for Visual C++

Public Class Methods

new( a_name ) click to toggle source
Calls superclass method MxxRu::Cpp::Toolset::new
# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 38
def initialize( a_name )
  super( a_name )

  setup_tag( "host_os", "mswin" )
  setup_tag( "target_os", "mswin" )
end

Public Instance Methods

c_compiler_name() click to toggle source

Returns C compiler name. For Visual C++ the only one compiler is used.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 67
def c_compiler_name; compiler_name end
clean_dll_specific_files( a_dll_file, a_dll_info, a_target ) click to toggle source

See description at MxxRu::Cpp::Toolset#clean_dll_specific_files.

Removes import library if exists.

Removes *.ilk, *.pdb files.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 173
def clean_dll_specific_files(
  a_dll_file,
  a_dll_info,
  a_target )

  # Remove import library if exists.
  if nil != a_dll_info.link_name
    implib_name = File.join(
        [ a_dll_info.link_path, a_dll_info.link_name ] )
    MxxRu::Util::delete_file( implib_name )

    # *.exp files are also created by Visual C++.
    explib_name =
      MxxRu::Util::change_file_ext( implib_name, ".exp" )
    MxxRu::Util::delete_file( explib_name )
  end

  clean_vc_specific_garbage( a_dll_file )
end
clean_exe_specific_files( a_exe_file, a_exe_info, a_target ) click to toggle source

See description at MxxRu::Cpp::Toolset#clean_exe_specific_files.

Removing *.ilk, *.pdb files.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 196
def clean_exe_specific_files(
  a_exe_file,
  a_exe_info,
  a_target )

  clean_vc_specific_garbage( a_exe_file )
end
clean_lib_specific_files( a_lib_file, a_lib_info, a_target ) click to toggle source

Common description see MxxRu::Cpp::Toolset#clean_lib_specific_files.

Removes VC specific garbage files.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 160
def clean_lib_specific_files(
  a_lib_file,
  a_lib_info,
  a_target )

  clean_vc_specific_garbage( a_lib_file )
end
clean_vc_specific_garbage( full_name ) click to toggle source

Remove VC specific garbage.

In DEBUG mode: *.ilk, *.pdb files. If something exported from executable: *.exp, *.lib (only if *.exp file exists).

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 416
def clean_vc_specific_garbage( full_name )
  MxxRu::Util::delete_file(
    MxxRu::Util::change_file_ext( full_name, ".ilk" ) )
  MxxRu::Util::delete_file(
    MxxRu::Util::change_file_ext( full_name, ".pdb" ) )

  exp_file_name = MxxRu::Util::change_file_ext( full_name, ".exp" )
  if File.exists?( exp_file_name )
    MxxRu::Util::delete_file( exp_file_name )
    # Import library for this export-file must be removed too.
    MxxRu::Util::delete_file(
      MxxRu::Util::change_file_ext( full_name, ".lib" ) )
  end
end
compiler_name() click to toggle source

Returns compiler name.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 46
def compiler_name
  return tag( COMPILER_NAME_TAG, "cl" )
end
cpp_compiler_name() click to toggle source

Returns C++ compiler name. For Visual C++ the only one compiler is used.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 71
def cpp_compiler_name; compiler_name; end
dll_file_name( source_name, target ) click to toggle source

See description at MxxRu::Cpp::Toolset#dll_file_name.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 279
def dll_file_name( source_name, target )
  return construct_target_name( source_name, NO_PREFIX, ".dll", target )
end
exe_file_name( source_name, target ) click to toggle source

See description at MxxRu::Cpp::Toolset#exe_file_name.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 359
def exe_file_name( source_name, target )
  return construct_target_name( source_name, NO_PREFIX, ".exe", target )
end
lib_file_name( source_name, target ) click to toggle source

See description at MxxRu::Cpp::Toolset#lib_file_name.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 255
def lib_file_name( source_name, target )
  return construct_target_name( source_name, NO_PREFIX, '.lib', target )
end
librarian_name() click to toggle source

Returns librarian name.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 56
def librarian_name
  return tag( LIBRARIAN_NAME_TAG, "lib" )
end
linker_name() click to toggle source

Returns linker name.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 51
def linker_name
  return tag( LINKER_NAME_TAG, "link" )
end
make_c_obj_command_lines( obj_name, source_name, compiler_options, target ) click to toggle source

See description at MxxRu::Cpp::Toolset#make_c_obj_command_lines.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 210
def make_c_obj_command_lines(
  obj_name,
  source_name,
  compiler_options,
  target )

  tmpfile = MxxRu::Util::TmpFiles.instance.create(
    "-c -TC -Fo#{obj_name} " +
    "#{compiler_options.join(' ')} #{source_name}" )

  return [ "#{compiler_name} @#{tmpfile}" ]
end
make_cpp_obj_command_lines( obj_name, source_name, compiler_options, target ) click to toggle source

See description at MxxRu::Cpp::Toolset#make_c_obj_command_lines.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 224
def make_cpp_obj_command_lines(
  obj_name,
  source_name,
  compiler_options,
  target )

  tmpfile = MxxRu::Util::TmpFiles.instance.create(
    "-c -TP -Fo#{obj_name} " +
    "#{compiler_options.join(' ')} #{source_name}" )

  return [ "#{compiler_name} @#{tmpfile}" ]
end
make_dll_command_lines( a_dll_name, a_dll_info, a_linker_lists, a_target ) click to toggle source

See description at MxxRu::Cpp::Toolset#make_dll_command_lines.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 309
def make_dll_command_lines(
  a_dll_name,
  a_dll_info,
  a_linker_lists,
  a_target )

  result = "/DLL " +
    "#{a_linker_lists.linker_options.join(' ')} " +
    "/OUT:#{a_dll_name} "

  if a_linker_lists.resources.size
    result << "#{a_target.mxx_all_mswin_rlink_options.join(' ')} "
  end

  if nil != a_dll_info.link_name
    implib_name = File.join( [ a_dll_info.link_path,
      a_dll_info.link_name ] )
    result << "/IMPLIB:#{implib_name} "
  end

  a_linker_lists.lib_paths.each { |p| result << "/LIBPATH:#{p} " }

  result << "#{a_linker_lists.objs.join(' ')} "
  result << "#{make_libraries_list_for_linker(a_linker_lists.libs)} "
  result << "#{a_linker_lists.resources.join(' ')} "

  tmpfile = MxxRu::Util::TmpFiles.instance.create( result )

  return [ "#{linker_name} @#{tmpfile}" ]
end
make_dll_requirements( a_dll_name, a_dll_info, a_linker_lists, a_target ) click to toggle source

See description at MxxRu::Cpp::Toolset#make_dll_requirements.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 341
def make_dll_requirements(
  a_dll_name,
  a_dll_info,
  a_linker_lists,
  a_target )

  result = DllRequirements.new

  # Dependencies are exists only if import library is present.
  if nil != a_dll_info.link_name
    result.add_libs( [ a_dll_info.link_name ] )
    result.add_lib_paths( [ a_dll_info.link_path ] )
  end

  return result
end
make_exe_command_lines( a_exe_name, a_exe_info, a_linker_lists, a_target ) click to toggle source

See description at MxxRu::Cpp::Toolset#make_exe_command_lines.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 364
def make_exe_command_lines(
  a_exe_name,
  a_exe_info,
  a_linker_lists,
  a_target )

  result = "#{a_linker_lists.linker_options.join(' ')} " +
    "/OUT:#{a_exe_name} "

  if a_linker_lists.resources.size
    result << "#{a_target.mxx_all_mswin_rlink_options.join(' ')} "
  end

  a_linker_lists.lib_paths.each { |p| result << "/LIBPATH:#{p} " }

  result << "#{a_linker_lists.objs.join(' ')} "
  result << "#{make_libraries_list_for_linker(a_linker_lists.libs)} "
  result << "#{a_linker_lists.resources.join(' ')} "

  tmpfile = MxxRu::Util::TmpFiles.instance.create( result )

  return [ "#{linker_name} @#{tmpfile}" ]
end
make_lib_command_lines( lib_name, obj_files, librarian_options, target ) click to toggle source

See description at MxxRu::Cpp::Toolset#make_lib_command_lines.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 265
def make_lib_command_lines(
  lib_name,
  obj_files,
  librarian_options,
  target )

  tmpfile = MxxRu::Util::TmpFiles.instance.create(
    "#{librarian_options.join(' ')} " +
    "/OUT:#{lib_name} #{obj_files.join(' ')}" )

  return [ "#{librarian_name} @#{tmpfile}" ]
end
make_mswin_res_command_lines( res_name, rc_file, rc_options, target ) click to toggle source

See description at MxxRu::Cpp::Toolset#make_mswin_res_command_lines.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 243
def make_mswin_res_command_lines(
  res_name,
  rc_file,
  rc_options,
  target )

  return [ "#{rc_name} " +
    "#{rc_options.join(' ')} /r " +
    "/fo#{res_name} #{rc_file}" ]
end
mswin_res_file_name( source_name ) click to toggle source

See description at MxxRu::Cpp::Toolset#mswin_res_file_name.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 238
def mswin_res_file_name( source_name )
  return source_name + ".res"
end
obj_file_ext() click to toggle source

See description at MxxRu::Cpp::Toolset#obj_file_ext.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 205
def obj_file_ext
  return ".obj"
end
rc_name() click to toggle source

Returns resource compiler name.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 61
def rc_name
  return tag( RC_NAME_TAG, "rc" )
end
setup_mandatory_options( target ) click to toggle source

See description at MxxRu::Cpp::Toolset#setup_mandatory_options.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 74
def setup_mandatory_options( target )

  target.compiler_option( "-nologo" )
  target.linker_option( "/NOLOGO" )
  target.librarian_option( "/NOLOGO" )
  target.cpp_compiler_option( "-EHsc" )

  if RUNTIME_DEBUG == target.mxx_runtime_mode
    target.compiler_option( "-Zi" )
    target.linker_option( "/DEBUG" )
    setup_vc_specific_debug_options( target )
  elsif RUNTIME_RELEASE == target.mxx_runtime_mode
    target.define( "NDEBUG" )
    if OPTIM_SIZE == target.mxx_optimization
      target.compiler_option( "-O1" )
    else
      target.compiler_option( "-O2" )
    end
  end

  if RTTI_ENABLED == target.mxx_rtti_mode
    target.cpp_compiler_option( "-GR" )
  end

  if RTL_SHARED == target.mxx_rtl_mode
    if THREADING_SINGLE == target.mxx_threading_mode
      raise MxxRu::UnsupportedModeEx.new(
        "Visual C++ not support single-threaded shared RTL" )
    else
      if RUNTIME_DEBUG == target.mxx_runtime_mode
        target.compiler_option( "-MDd" )
      else
        target.compiler_option( "-MD" )
      end
    end
  else
    if THREADING_MULTI == target.mxx_threading_mode
      if RUNTIME_DEBUG == target.mxx_runtime_mode
        target.compiler_option( "-MTd" )
      else
        target.compiler_option( "-MT" )
      end
    else
      if RUNTIME_DEBUG == target.mxx_runtime_mode
        target.compiler_option( "-MLd" )
      else
        target.compiler_option( "-ML" )
      end
    end
  end

  if target.target_type.name == DllTargetType::TYPE
    target.compiler_option( "-LD" )
  end

  if SCREEN_WINDOW == target.mxx_screen_mode
    target.linker_option( "/SUBSYSTEM:WINDOWS" )
  else
    target.linker_option( "/SUBSYSTEM:CONSOLE" )
  end

  # All defines and all include_path should be applied
  # to resource compiler too.
  target.mxx_all_defines.each { |d|
    target.compiler_option( "-D" + d )
    target.mswin_rc_option( "/d" + d )
  }

  target.mxx_all_include_paths.each { |p|
    target.compiler_option( "-I" + p )
    target.mswin_rc_option( "/i" + p )
  }

  # Resource compiler specific options.
  target.mxx_all_mswin_rc_defines.each { |d|
    target.mswin_rc_option( "/d" + d )
  }
  target.mxx_all_mswin_rc_include_paths.each { |p|
    target.mswin_rc_option( "/i" + p )
  }

end
setup_vc_specific_debug_options( target ) click to toggle source

Setting up VC specific options for managing PDB files.

Adding '/Fd<full-target-name>.pdb' option for compiler. Adding '/PDB:<full-target-name>.pdb' option for linker (in case of EXE or DLL).

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 393
def setup_vc_specific_debug_options( target )
  full_name =
    case target.target_type.name
      when ExeTargetType::TYPE
        make_exe_name( target.mxx_target_name, target ).full_name
      when DllTargetType::TYPE
        make_dll_name( target.mxx_target_name, target ).full_name
      when LibTargetType::TYPE
        make_lib_name( target.mxx_target_name, target ).full_name
      else nil
    end
  if full_name
    pdb_file = MxxRu::Util::change_file_ext( full_name, ".pdb" )
    target.compiler_option( "/Fd#{pdb_file}" )
    target.linker_option( "/PDB:#{pdb_file}" )
  end
end

Protected Instance Methods

check_library_name( name ) click to toggle source

Checks and correct name of library. For Visual C++ library name must always contain extension '.lib'. If this extension is ommitted in project files than extension must be added.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 435
def check_library_name( name )
  return name if /\.lib$/i =~ name
  return name + '.lib'
end
make_libraries_list_for_linker( libraries ) click to toggle source

Checks, correct and concatenate names of libraries for linker.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 441
def make_libraries_list_for_linker( libraries )
  libraries.inject( '' ) { |r, l|
      r << check_library_name( l.name ) << ' '
  }
end
make_toolset_id_string() click to toggle source

Create toolset identification string.

# File lib/mxx_ru/cpp/toolsets/vc_family.rb, line 448
def make_toolset_id_string
  result = IO.popen( "#{compiler_name} /?", :err => [:child, :out] ) do |io|
    target = 'generic'
    version = 'unknown'
    io.each_line do |line|
      if /Optimizing Compiler Version (?<v>\S+) for (?<trgt>\S+)/ =~ line
        target = trgt
        version = v
        break
      end
    end
    version + '_' + target
  end
  "vc#{tag('ver_hi','x')}_#{tag('ver_lo','x')}_#{result}"
end