######################################################################## # Copyright (C) 2008 ERG Limited, All rights reserved # # Module name : qt-builder.pm # Module type : Makefile system # Compiler(s) : Perl # Environment(s): jats # # Description : Provide JATS build support for the QT SDK # This module hoosk into the internals of JATS # It tries to be generic, buts its not easy # #......................................................................# require 5.008_002; use strict; use warnings; use MakeEntry; # # Global Varibales # our %SRC_DEPEND; # Source file dependencies our %SRC_ARGS; # Source file arguments # # Local variables # my $qt_package; # Ref to package containing QT my %qt_used; # Track Used items #------------------------------------------------------------------------------- # Function : BEGIN # # Description : Setup directive hooks # Register to be told about source files that are QT specific # # Inputs : None # # Returns : None # BEGIN { # # Locate the QT package # Done by looking for the include/QtGui directory # If we don't find it then don't install the Qt hooks # Generate a warning when Qt is 'Used' # This allows for the building of packages that have Qt and Non-Qt parts # foreach my $entry ( getPackageList() ) { foreach my $path ( $entry->getIncDirs(1) ) { if ( -d "$path/QtGui" ) { $qt_package = $entry; last; } } } # # Qt not supported in this type of a build # Just exist now. Will create an error if QtUses is activated # return unless ( $qt_package ); # # Define QT specfic rules. # Will be found in the same directory as this file # Rules ( StripFileExt( __FILE__ ), 'qt.rul' ); # # Register interest in various types of source file # Currently only header files are examined for MOC processing # RegisterSrcHook ('.qrc', \&src_hook_qrc ); RegisterSrcHook ('.ui', \&src_hook_ui ); RegisterSrcHook ('.h', \&src_hook_h ); RegisterSrcHook ('.cpp', \&src_hook_cpp ); # # Files will be placed into the OBJDIR # Ensure that the compiler searches this directory # AddIncDir( '*' , "\$(OBJDIR)", '--NoWarn' ); } #------------------------------------------------------------------------------- # Function : QtUses # # Description : User directive to provide information as to which parts of # Qt are being used. # # Done this way for two reasons: # 1) Allow the Include path to be extended # Qt has a lot of subdirs in 'include' # Placing all of these in the include path # slows down the compilation # # 2) Allow JATS to provide a '--Uses' construct for # programs and shared libraries taht provide a machine # independent mechanism for adding the required libs # # Inputs : $platforms - Platform predicate # @components - Compoents to use # # Returns : # sub QtUses { my ($platforms, @components) = @_; Debug( "QtUses: ",$platforms, @components ); return if ( ! ActivePlatform($platforms) ); Error ("Cannot find the Qt Base Package, or Qt is not supported", "on this platform") unless ( $qt_package ); foreach my $component ( @components ) { # # Only do it once # next if ( exists $qt_used{$component} ); $qt_used{$component} = 1; # # Extend the header search path to include the required headers # my $dir; foreach my $path ( $qt_package->getIncDirs(2) ) { if ( -d "$path/$component" ) { $dir = "$path/$component"; last; } } Error ("Qt component not supported: $component") unless ( $dir ); AddIncDir ('*', '--NoWarn','--System', $dir ); ################################################################################ # # Following code currently not active # There is no one-one relationship between QT include dirs and libraries # # Dont know how Trolltech do it. Might be hard coded # ################################################################################ # # # # # Extend a --Users(QT) definition to provide libraries for the user # # There are problems # # Under windows, some of the libraries have a 4 suffix # # Need to determine the exact name of the library # # Normally this knowledge is buried within the compiler/linker and # # some JATS tools. # # # # Algorithm: # # Given a library name, determine if the file exists # # under both windows and linux # # If Unix - prefix with lib # # If Unix - try shared-lib, static lib suffix # # If Windows - try static lib suffix # # # my @prefix = ('', 'lib'); # my @suffix = ($::so, $::a ); # my $found; # HUNT: # foreach my $qtsuf ( '4', '' ) # { # foreach my $suffix ( @suffix ) # { # foreach my $prefix ( @prefix ) # { # my $cname = $prefix . $component . $qtsuf . '.' . $suffix; # foreach my $path ( $qt_package->getLibDirs(2) ) # { # if ( -f "$path/$cname" ) # { # $found = $component . $qtsuf; # last HUNT; # } # } # } # } # } # # Error ("QT library component not supported: $component") # unless ( $found ); # # MakeIf::Libaries ( 'QT', '*', "-L$found"); ################################################################################ } } #------------------------------------------------------------------------------- # Function : src_hook_qrc # # Description : This function will be invoked when a .QRC file # is encountered in the Src directive # # .qrc file are QT resource files # These need to be processed into .cpp file # and the .cpp file needs to be converted into an object file # # Inputs : $path - Source path # $path - Source file name # $obj - Base file name (no dir or ext) # $ext - Extension # # Returns : # sub src_hook_qrc { Debug ("src_hook_qrc: @_"); my ( $srcfile ,$path, $obj, $ext ) = @_; my @dlist = (); # # The .qrc file will be converted into a cpp file # Treat the .cpp file as a source file in its own right # $obj = 'qrc_' . $obj; my $csource = '$(OBJDIR)/' . $obj . '.cpp' ; GenerateSrcFile ( 1, $csource ); # # The user may have specified some dependencies # Create a list of these to be a part of the generated Rule # @dlist = split( /$;/, $SRC_DEPEND{$path} ) if ( exists $SRC_DEPEND{$path} ); # # Parse the source file and extract dependencies # The file is of a known XML format # Depenedencies are not nested # Implement a simple parser # # Look for lines of the form: # FileName # # The source file may not acually exist. It may be symbolic # If the file doesn't exist, then don't complain. # if ( -e $srcfile ) { if (open (SF, '<', $srcfile )) { my $srcdir = StripFileExt( $srcfile ); $srcdir .= '/' if ( $srcdir ); while ( ) { if ( m~(.*)~ ) { my $name = $1; $name =~ s~([ ,])~\\$1~g; push @dlist, "$srcdir$name"; } } close SF; } } # # Create a Rule to build this file # Will be placed in the Rules section # my $var; my $me = MakeEntry::New (\$var, $csource ); # $me->AddComment ("QT Resource Compiler: $path" ); $me->AddDependancy ( $srcfile ); $me->AddDependancy ( @dlist ); $me->AddDependancy ( '$(SCM_MAKEFILE)' ); $me->AddDependancy ( '$(GBE_OBJDIR)' ); $me->AddRecipe ( '$(XX_PRE)$(QT_RCC)' ); $me->Print(); ToolsetRule ( $var ); } #------------------------------------------------------------------------------- # Function : src_hook_ui # # Description : This function will be invoked when a .UI file # is encountered in the Src directive # # .ui file are QT User Interface files # These need to be processed into header files # by the User Interface Compiler # # Inputs : $path - Source path # $path - Source file name # $obj - Base file name (no dir or ext) # $ext - Extension # # Returns : # sub src_hook_ui { Debug ("src_hook_ui: @_"); my ( $srcfile ,$path, $obj, $ext ) = @_; # # Convert the UI file into a header file # Place the header file in the OBJ directory # my $target = "\$(OBJDIR)/ui_$obj.h"; GenerateSrcFile ( 1, $target ); # # The user may have specified some dependencies # Create a list of these to be a part of the generated Rule # my @dlist = split( /$;/, $SRC_DEPEND{$path} ) if ( exists $SRC_DEPEND{$path} ); # # Create a Rule to build this file # Will be placed in the Rules section # my $var; my $me = MakeEntry::New (\$var, $target ); # $me->AddComment ("QT User Interface File: $path" ); $me->AddDependancy ( $srcfile ); $me->AddDependancy ( @dlist ); $me->AddDependancy ( '$(SCM_MAKEFILE)' ); $me->AddDependancy ( '$(GBE_OBJDIR)' ); $me->AddRecipe ( '$(XX_PRE)$(QT_UIC)' ); $me->Print(); ToolsetRule ( $var ); } #------------------------------------------------------------------------------- # Function : src_hook_h # # Description : This function will be invoked when a .h file # is encountered in the Src directive # # If the file is flagged as --Moc then it will treated # by the MOC processor # # Inputs : $path - Source path # $path - Source file name # $obj - Base file name (no dir or ext) # $ext - Extension # # Returns : # sub src_hook_h { Debug ("src_hook_h: @_"); my ( $srcfile ,$path, $obj, $ext ) = @_; # # Only interested in files that are flagged as --Moc # return unless ( $SRC_ARGS{ $path } && grep (/^--Moc$/i, split( /$;/, $SRC_ARGS{$path} ) ) ); # # The file will be converted into a cpp file # Treat the .cpp file as a source file in its own right # $obj = 'moc_' . $obj; my $csource = '$(OBJDIR)/' . $obj . '.cpp' ; GenerateSrcFile ( 1, $csource ); # # The user may have specified some dependencies # Create a list of these to be a part of the generated Rule # my @dlist = split( /$;/, $SRC_DEPEND{$path} ) if ( exists $SRC_DEPEND{$path} ); # # Create a Rule to build this file # Will be placed in the Rules section # my $var; my $me = MakeEntry::New (\$var, $csource ); # $me->AddComment ("QT Meta Object Compiler: $path" ); $me->AddDependancy ( $srcfile ); $me->AddDependancy ( @dlist ); $me->AddDependancy ( '$(SCM_MAKEFILE)' ); $me->AddDependancy ( '$(GBE_OBJDIR)' ); $me->AddRecipe ( '$(XX_PRE)$(QT_MOC)' ); $me->Print(); ToolsetRule ( $var ); } #------------------------------------------------------------------------------- # Function : src_hook_cpp # # Description : This function will be invoked when a .cpp file # is encountered in the Src directive # # If the file is flagged as --Moc then it will treated # by the MOC processor # # Inputs : $path - Source path # $path - Source file name # $obj - Base file name (no dir or ext) # $ext - Extension # # Returns : # sub src_hook_cpp { Debug ("src_hook_cpp: @_"); my ( $srcfile ,$path, $obj, $ext ) = @_; # # Only interested in files that are flagged as --Moc # return unless ( $SRC_ARGS{ $path } && grep (/^--Moc$/i, split( /$;/, $SRC_ARGS{$path} ) ) ); # # The file will be converted into a .moc file as shown in the QT doco # Treat the .moc file as a source file in its own right # my $csource = '$(OBJDIR)/' . $obj . '.moc' ; GenerateSrcFile ( 1, $csource ); # # The user may have specified some dependencies # Create a list of these to be a part of the generated Rule # my @dlist = split( /$;/, $SRC_DEPEND{$path} ) if ( exists $SRC_DEPEND{$path} ); # # Create a Rule to build this file # Will be placed in the Rules section # my $var; my $me = MakeEntry::New (\$var, $csource ); # $me->AddComment ("QT Meta Object Compiler: $path" ); $me->AddDependancy ( $srcfile ); $me->AddDependancy ( @dlist ); $me->AddDependancy ( '$(SCM_MAKEFILE)' ); $me->AddDependancy ( '$(GBE_OBJDIR)' ); $me->AddRecipe ( '$(XX_PRE)$(QT_MOC)' ); $me->Print(); ToolsetRule ( $var ); } 1;