class MxxRu::Cpp::Qt4

A special modification for the case when configuration of Qt4 is detected via 'pkg-config' command. For example on Debian Linux. (This case is detected and used by Mikhail Lyossin).

Method use_module is redefined to make two calls to pkg-config:

Files generator for Qt4 class.

Main features:

Generated source files automatically added into cpp_source list of target.

Local list defines is supported.

If only pointer to the target passed into contructor, default list of defines is used. If it's required to change default list, new list should be passed through a second argument:

generator( MxxRu::Cpp::Qt4.new( self, [ "QT_DEPRECATED_WARNINGS" ] ) )

Constants

DEFAULT_DEFINES

Default list of defines. QT_DLL

Attributes

cpp_ext[RW]

File extension for source files generated. Used in both moc and uic tools. Default: .cpp

hpp_ext[RW]

File extension for header files generated. Used in uic tool. Default: .h

lupdate_name[RW]

Name of lupdate tool.

Default value: lupdate.

lupdate_options[RW]

List of options for lupdate utility.

Default value: [ '-noobsolete', '-silent' ]

moc_ext[RW]

File extension for moc files generated. Used in moc tool. Default: .moc

moc_name[RW]

moc tool executable Default: moc

moc_result_subdir[RW]

Subfolder name where moc generated files would be located. If nil, generated files would be in the same folder where source files were. Default: nil

qrc_result_subdir[RW]

Subfolder name where results of rcc invokation must be placed. If nil, generated files would be in the same folder where source qrc files were. Used only for qrc2cpp translation.

qt_cpp2moc_files[R]

Files list for generating moc files from source files.

More exact: a.cpp -> a.moc.

qt_h2moc_files[R]

Files list for generating moc files from header files.

More exact: a.hpp -> moc_a.cpp. moc_a.cpp file is added to cpp_source list of a target.

qt_qrc2cpp_files[R]

Files list for generating source files from qrc files.

More exact: a.qrc -> qrc_a.cpp

qt_qrc2rcc_files[R]

Files list for generating binary resource files from qrc files.

More exact: a.qrc -> a.rcc

qt_ts_files[R]

File list for translations.

qt_ui_files[R]

Files list for generating header files from ui files.

More exact: a.ui -> ui_a.hpp

rcc_name[RW]

rcc tool executable Default: rcc.

target[R]

Target, generator is created for.

uic_name[RW]

uic tool executable Default: uic.

uic_result_subdir[RW]

Subfolder name where results of uic invokation must be placed. If nil, generated files would be in the same folder where source ui files were.

Public Class Methods

new( a_target, a_defines = DEFAULT_DEFINES ) click to toggle source

Constructor.

# File lib/mxx_ru/cpp/qt4details.rb, line 229
def initialize( a_target, a_defines = DEFAULT_DEFINES )
  @moc_name = "moc"
  @uic_name = "uic"
  @rcc_name = "rcc"
  @cpp_ext = ".cpp"
  @hpp_ext = ".h"
  @moc_ext = ".moc"
  @moc_result_subdir = nil
  @uic_result_subdir = nil
  @qrc_result_subdir = nil
  @lupdate_name = 'lupdate'
  @lupdate_options = [ '-noobsolete', '-silent' ]

  # If uic_result_subdir not nil than we must add
  # uic_result_subdir into
  # target include_path. But must do this only one time.
  @uic_result_subdir_include_paths = Set.new

  @qt_h2moc_files = []
  @qt_cpp2moc_files = []
  @qt_ui_files = []
  @qt_qrc2cpp_files = []
  @qt_qrc2rcc_files = []
  @qt_ts_files = []

  defines_to_set = a_defines.flatten
  defines_to_set.each { |d| a_target.define( d ) }

  @target = a_target

  # QtCore must be used.
  use_module Qt4Modules::QT_CORE
end

Protected Class Methods

detect_qrc_file_dependencies( a_qrc_file ) click to toggle source

Detect list of dependencies for .qrc file.

# File lib/mxx_ru/cpp/qt4details.rb, line 621
def Qt4.detect_qrc_file_dependencies( a_qrc_file )
  qrc_file_path = File.dirname( a_qrc_file )
  result = []
  File.open( a_qrc_file, 'r' ) do |file|
    doc = REXML::Document.new( file )
    result = doc.elements[ '/RCC/qresource/file' ].inject( [] ) do
      |list, item|
      s = item.value
      p = Pathname.new( s )
      if !p.absolute?
        list << File.join( qrc_file_path, s )
      else
        list << s
      end
      list
    end
  end

  result
end

Public Instance Methods

build( a_target ) click to toggle source

Perform files generation.

# File lib/mxx_ru/cpp/qt4details.rb, line 324
def build( a_target )
  build_from_ui( a_target )
  build_from_qrc2cpp( a_target )
  build_from_qrc2rcc( a_target )
  build_from_h( a_target )
  build_from_cpp( a_target )
  build_translations( a_target )
end
clean( a_target ) click to toggle source

Perform generated files cleanup.

# File lib/mxx_ru/cpp/qt4details.rb, line 334
def clean( a_target )
  clean_from_ui( a_target )
  clean_from_qrc2cpp( a_target )
  clean_from_qrc2rcc( a_target )
  clean_from_h( a_target )
  clean_from_cpp( a_target )
end
cpp2moc( a_file ) click to toggle source

Add a file for cpp to moc generation.

# File lib/mxx_ru/cpp/qt4details.rb, line 269
def cpp2moc( a_file )
  @qt_cpp2moc_files << @target.create_full_src_file_name( a_file )
end
h2moc( a_file ) click to toggle source

Add a file for hpp to moc generation.

# File lib/mxx_ru/cpp/qt4details.rb, line 264
def h2moc( a_file )
  @qt_h2moc_files << @target.create_full_src_file_name( a_file )
end
lib_qtmain() click to toggle source

Add qtmain component for target.

# File lib/mxx_ru/cpp/qt4details.rb, line 343
def lib_qtmain
  @target.lib 'qtmain'
  self
end
qrc2cpp( a_file ) click to toggle source

Add a file for qrc to cpp generation.

# File lib/mxx_ru/cpp/qt4details.rb, line 288
def qrc2cpp( a_file )
  full_file_name = @target.create_full_src_file_name( a_file )
  @qt_qrc2cpp_files << full_file_name
end
qrc2rcc( a_file ) click to toggle source

Add a file for qrc to rcc generation.

# File lib/mxx_ru/cpp/qt4details.rb, line 294
def qrc2rcc( a_file )
  full_file_name = @target.create_full_src_file_name( a_file )
  @qt_qrc2rcc_files << full_file_name
end
ts( a_name ) click to toggle source

Add translation file.

a_file – name of .ts-file.

# File lib/mxx_ru/cpp/qt4details.rb, line 319
def ts( a_name )
  @qt_ts_files << a_name
end
ui( a_file ) click to toggle source

Add a file for ui to hpp generation.

# File lib/mxx_ru/cpp/qt4details.rb, line 274
def ui( a_file )
  full_file_name = @target.create_full_src_file_name( a_file )
  @qt_ui_files << full_file_name
  if @uic_result_subdir
    uic_result_path = make_uic_result_path_for( full_file_name )

    if !@uic_result_subdir_include_paths.member?( uic_result_path )
      @target.include_path( uic_result_path )
      @uic_result_subdir_include_paths.add( uic_result_path )
    end
  end
end
use_module( a_module ) click to toggle source
# File lib/mxx_ru/cpp/qt4_via_pkg_config.rb, line 51
def use_module( a_module )
  @target.define a_module.define
  
  IO.popen( "pkg-config #{a_module.library} --cflags" ) { |file|
    @target.compiler_option( file.gets.chop )
  }
  IO.popen( "pkg-config #{a_module.library} --libs" ) { |file|
    @target.linker_option( file.gets.chop )
  }
end
use_modules( *a_modules ) click to toggle source

Add some Qt4 modules to target.

a_modules – an enumeration of Qt4Modules::ModuleDescription instances.

# File lib/mxx_ru/cpp/qt4details.rb, line 311
def use_modules( *a_modules )
  a_modules.each { |m| use_module( m ) }
end

Protected Instance Methods

add_cpp_source( a_target, a_file ) click to toggle source

Setting C++ file name, ignoring current sources_root value.

# File lib/mxx_ru/cpp/qt4details.rb, line 596
def add_cpp_source( a_target, a_file )
  old_root = a_target.sources_root( "" )
  a_target.cpp_source( a_file )
  a_target.sources_root( old_root )
end
build_from_cpp( a_target ) click to toggle source

Perform generation from cpp file using moc tool.

# File lib/mxx_ru/cpp/qt4details.rb, line 541
def build_from_cpp( a_target )
  @qt_cpp2moc_files.each { |cpp_full|
    moc_full = moc_from_cpp( cpp_full, a_target )

    if TargetState::EXISTS != TargetState.detect(
      moc_full, [ cpp_full ] ).state
      MxxRu::AbstractTarget::run(
        [ "#{moc_name} -o #{moc_full} " + 
          "#{cpp_full}" ],
        [ moc_full ],
        "building moc file #{moc_full}" )
    end
  }
end
build_from_h( a_target ) click to toggle source

Perform generation from hpp file using moc tool.

# File lib/mxx_ru/cpp/qt4details.rb, line 498
def build_from_h( a_target )
  @qt_h2moc_files.each { |header_full|
    moc_full = moc_from_h( header_full, a_target )

    if TargetState::EXISTS != TargetState.detect(
      moc_full, [ header_full ] ).state
      MxxRu::AbstractTarget::run(
        [ "#{moc_name} -o #{moc_full} " + 
          "#{header_full}" ],
        [ moc_full ],
        "building moc file #{moc_full}" )
    end

    add_cpp_source( a_target, moc_full )
  }
end
build_from_qrc2cpp( a_target ) click to toggle source

Perform generation from qrc-files.

# File lib/mxx_ru/cpp/qt4details.rb, line 410
def build_from_qrc2cpp( a_target )
  @qt_qrc2cpp_files.each { |qrc_file|
    name = File.basename( MxxRu::Util::remove_file_ext( qrc_file ) )
    qrc_cpp = source_from_qrc( qrc_file, a_target )
    MxxRu::Util::ensure_path_exists( File.dirname( qrc_cpp ) )

    # Checking what files are changed and running generation
    # from them if necessary.
    if TargetState::EXISTS != TargetState.detect(
        qrc_cpp,
        [ qrc_file ] + Qt4.detect_qrc_file_dependencies( qrc_file ) ).state
      MxxRu::AbstractTarget::run(
        [ "#{@rcc_name} -name #{name} -o #{qrc_cpp} #{qrc_file}" ],
        [ qrc_cpp ],
        "building source file #{qrc_cpp}" )
    end

    add_cpp_source( a_target, qrc_cpp )
  }
end
build_from_qrc2rcc( a_target ) click to toggle source

Perform generation from qrc-files.

# File lib/mxx_ru/cpp/qt4details.rb, line 462
def build_from_qrc2rcc( a_target )
  @qt_qrc2rcc_files.each { |qrc_file|
    name = File.basename( MxxRu::Util::remove_file_ext( qrc_file ) )
    target_path =
        File.dirname( a_target.create_full_result_target_file_name )
    MxxRu::Util::ensure_path_exists( target_path )

    rcc_file = File.join( target_path, name + '.rcc' )

    # Checking what files are changed and running generation
    # from them if necessary.
    if TargetState::EXISTS != TargetState.detect(
        rcc_file,
        [ qrc_file ] + Qt4.detect_qrc_file_dependencies( qrc_file ) ).state
      MxxRu::AbstractTarget::run(
        [ "#{@rcc_name} -binary -name #{name} -o #{rcc_file} #{qrc_file}" ],
        [ rcc_file ],
        "building Qt4 resource file #{rcc_file}" )
    end
  }
end
build_from_ui( a_target ) click to toggle source

Perform generation from ui-files.

# File lib/mxx_ru/cpp/qt4details.rb, line 366
def build_from_ui( a_target )
  @qt_ui_files.each { |ui|
    ui_header = header_from_ui( ui, a_target )
    MxxRu::Util::ensure_path_exists( File.dirname( ui_header ) )

    # Checking what files are changed and running generation
    # from them if necessary.
    if TargetState::EXISTS != TargetState.detect(
        ui_header, [ ui ] ).state
      MxxRu::AbstractTarget::run(
        [ "#{@uic_name} -o #{ui_header} #{ui}" ],
        [ ui_header ],
        "building header file #{ui_header}" )
    end
  }
end
build_translations( a_target ) click to toggle source

Perform .ts-files building.

# File lib/mxx_ru/cpp/qt4details.rb, line 567
def build_translations( a_target )
  return if 0 == @qt_ts_files.size

  project_path = File.dirname( a_target.prj_alias )
  @qt_ts_files.each do |ts_file|
    full_ts_file_name = File.join( project_path, ts_file )
    MxxRu::Util::ensure_path_exists( File.dirname( full_ts_file_name ) )

    MxxRu::AbstractTarget::run(
        [ "#{lupdate_name} #{lupdate_options.join(' ')} " +
            "#{project_path} -ts #{full_ts_file_name}" ],
        [ full_ts_file_name ],
        "building translation file #{full_ts_file_name}" )
  end
end
clean_from_cpp( a_target ) click to toggle source

Perform cleanup of files produced by generation from cpp file.

# File lib/mxx_ru/cpp/qt4details.rb, line 557
def clean_from_cpp( a_target )
  @qt_cpp2moc_files.each { |cpp|
    moc = moc_from_cpp( cpp, a_target )

    MxxRu::Util::delete_file( moc )
  }
end
clean_from_h( a_target ) click to toggle source

Perform cleanup of files produced by generation from hpp file.

# File lib/mxx_ru/cpp/qt4details.rb, line 516
def clean_from_h( a_target )
  @qt_h2moc_files.each { |h|
    moc = moc_from_h( h, a_target )

    MxxRu::Util::delete_file( moc )

    add_cpp_source( a_target, moc )
  }
end
clean_from_qrc2cpp( a_target ) click to toggle source

Perform cleanup of files, generated from qrc files.

# File lib/mxx_ru/cpp/qt4details.rb, line 433
def clean_from_qrc2cpp( a_target )
  @qt_qrc2cpp_files.each { |qrc_file|
    qrc_cpp = source_from_qrc( qrc_file, a_target )

    # It is necessary to delete obj-file.
    add_cpp_source( a_target, qrc_cpp )

    MxxRu::Util::delete_file( qrc_cpp )
  }
end
clean_from_qrc2rcc( a_target ) click to toggle source

Perform cleanup of files, generated from qrc files.

# File lib/mxx_ru/cpp/qt4details.rb, line 486
def clean_from_qrc2rcc( a_target )
  @qt_qrc2rcc_files.each { |qrc_file|
    name = File.basename( MxxRu::Util::remove_file_ext( qrc_file ) )
    target_path =
        File.dirname( a_target.create_full_result_target_file_name )
    rcc_file = File.join( target_path, name + '.rcc' )

    MxxRu::Util::delete_file( rcc_file )
  }
end
clean_from_ui( a_target ) click to toggle source

Perform cleanup of files, generated from ui files.

# File lib/mxx_ru/cpp/qt4details.rb, line 384
def clean_from_ui( a_target )
  @qt_ui_files.each { |ui|
    ui_header = header_from_ui( ui, a_target )

    MxxRu::Util::delete_file( ui_header )
  }
end
header_from_ui( a_ui_file, a_target ) click to toggle source

Getting file name, generated by uic tool.

# File lib/mxx_ru/cpp/qt4details.rb, line 394
def header_from_ui( a_ui_file, a_target )
  path, file_name = File.split( a_ui_file )
  updated_file_name = 'ui_' +
      MxxRu::Util::remove_file_ext( file_name ) +
      @hpp_ext

  if @uic_result_subdir then
    result = File.join( path, @uic_result_subdir, updated_file_name )
  else
    result = File.join( path, updated_file_name )
  end

  result
end
make_library_name( base_library_name ) click to toggle source

Create actual Qt library name with respect to debug/release mode on Windows.

Since v.1.5.2

# File lib/mxx_ru/cpp/qt4details.rb, line 353
def make_library_name( base_library_name )
  name =
    if MxxRu::Util::IS_WINDOWS_PLATFORM &&
        RUNTIME_DEBUG == @target.mxx_runtime_mode
      base_library_name + 'd'
    else
      base_library_name
    end

  name + '4'
end
make_moc_result_path_for( path ) click to toggle source

Calculating path for moc results.

# File lib/mxx_ru/cpp/qt4details.rb, line 603
def make_moc_result_path_for( path )
  if @moc_result_subdir
    if path.length > 0
      File.join( path, @moc_result_subdir )
    else
      @moc_result_subdir
    end
  else
    path
  end
end
make_uic_result_path_for( file ) click to toggle source

Calculating path for uic results.

# File lib/mxx_ru/cpp/qt4details.rb, line 616
def make_uic_result_path_for( file )
  File.join( File.dirname( file ), @uic_result_subdir )
end
moc_from_cpp( a_cpp_file, a_target ) click to toggle source

Formatting file name, which is generated from cpp file by moc tool

# File lib/mxx_ru/cpp/qt4details.rb, line 584
def moc_from_cpp( a_cpp_file, a_target )
  path = make_moc_result_path_for( File.dirname( a_cpp_file ) )

  MxxRu::Util::ensure_path_exists( path )

  r = File.join( path, File.basename(
    MxxRu::Util::remove_file_ext( a_cpp_file ) ) + @moc_ext )

  return r
end
moc_from_h( a_h_file, a_target ) click to toggle source

Formatting file name, which is generated from hpp file by moc tool

# File lib/mxx_ru/cpp/qt4details.rb, line 527
def moc_from_h( a_h_file, a_target )
  path = File.dirname( a_h_file )

  # If path == ".", then Qt will generate wrong include directive
  path = "" if path == "./"
  path = make_moc_result_path_for( path )

  MxxRu::Util::ensure_path_exists( path )

  r = File.join( path, "moc_" + File.basename(
    MxxRu::Util::remove_file_ext( a_h_file ) ) + @cpp_ext )
end
source_from_qrc( a_qrc_file, a_target ) click to toggle source

Getting file name, generated by rcc tool.

# File lib/mxx_ru/cpp/qt4details.rb, line 446
def source_from_qrc( a_qrc_file, a_target )
  path, file_name = File.split( a_qrc_file )
  updated_file_name = 'qrc_' +
      MxxRu::Util::remove_file_ext( file_name ) +
      @cpp_ext

  if @qrc_result_subdir then
    result = File.join( path, @qrc_result_subdir, updated_file_name )
  else
    result = File.join( path, updated_file_name )
  end

  result
end