ProjectBuilder.st
author Claus Gittinger <cg@exept.de>
Thu, 21 Mar 2013 18:30:30 +0100
changeset 2981 e61e4a6fb317
parent 2979 06dcbe5668a4
child 2984 bfb6db857ea8
permissions -rw-r--r--
class: Tools::ProjectBuilder
changed:
#copyResourcesForPackage:
#generateSourceFilesByFilingOut

care for extensions
     1 "
     2  COPYRIGHT (c) 2009 by eXept Software AG
     3               All Rights Reserved
     4 
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    11 "
    12 "{ Package: 'stx:libtool2' }"
    13 
    14 "{ NameSpace: Tools }"
    15 
    16 Object subclass:#ProjectBuilder
    17 	instanceVariableNames:'package projectDefinitionClass sourceCodeManager buildDirectory
    18 		myWorkingDirectory mySTXTopDirectory myTopDirectory outputStream
    19 		makeExeOnly makeQuick usedCompiler stdOut stdErr isQuickBuild
    20 		isLocalBuild'
    21 	classVariableNames:'PreviousBuildDirectory'
    22 	poolDictionaries:''
    23 	category:'System-Support-Projects'
    24 !
    25 
    26 !ProjectBuilder class methodsFor:'documentation'!
    27 
    28 copyright
    29 "
    30  COPYRIGHT (c) 2009 by eXept Software AG
    31               All Rights Reserved
    32 
    33  This software is furnished under a license and may be used
    34  only in accordance with the terms of that license and with the
    35  inclusion of the above copyright notice.   This software may not
    36  be provided or otherwise made available to, or used by, any
    37  other person.  No title to or ownership of the software is
    38  hereby transferred.
    39 "
    40 ! !
    41 
    42 !ProjectBuilder class methodsFor:'accessing'!
    43 
    44 previousBuildDirectory
    45     ^ PreviousBuildDirectory
    46 !
    47 
    48 previousBuildDirectory:something
    49     PreviousBuildDirectory := something.
    50 ! !
    51 
    52 !ProjectBuilder class methodsFor:'examples'!
    53 
    54 example1
    55     Smalltalk loadPackage:'stx:projects/helloWorldApp' asAutoloaded:true.
    56 
    57     self new
    58         package:'stx:projects/helloWorldApp';
    59         build
    60 !
    61 
    62 example2
    63     |builder|
    64 
    65     Smalltalk loadPackage:'stx:clients/Demos/foxCalcApplication' asAutoloaded:true.
    66 
    67     builder := self new.
    68     builder 
    69         package:'stx:clients/Demos/foxCalcApplication';
    70         build.
    71 
    72     UserPreferences fileBrowserClass openOnDirectory:builder packageBuildDirectory.
    73 
    74     "Modified: / 03-09-2012 / 19:23:53 / cg"
    75 ! !
    76 
    77 !ProjectBuilder class methodsFor:'queries'!
    78 
    79 defaultUsedCompiler
    80     |compiler|
    81 
    82     (compiler := UserPreferences current usedCompilerForBuild) notNil ifTrue:[
    83         ^ compiler
    84     ].
    85 
    86     ^ OperatingSystem isMSWINDOWSlike 
    87         ifTrue:[ 'bcc' ]
    88         ifFalse:[ 'gcc' ]
    89 
    90     "Created: / 21-01-2012 / 14:06:51 / cg"
    91 !
    92 
    93 listOfPossibleCompilers
    94     OperatingSystem isMSWINDOWSlike ifTrue:[
    95         OperatingSystem getLoginName = 'cg' ifTrue:[
    96             ^ #(
    97                 'bcc'   "/ OK
    98                 'vc'    "/ almost OK
    99                 'lcc'   "/ experimental, but only free for non-commercial work
   100                 'tcc'   "/ experimental; limited but free
   101                 'mingw' "/ experimental; free
   102              )
   103         ].
   104         ^ #('bcc' 'vc' 'mingw' )
   105     ].
   106     ^ #('gcc')
   107 
   108     "Created: / 21-01-2012 / 14:04:15 / cg"
   109 !
   110 
   111 suiteNameOfCompiler:usedCompiler
   112     usedCompiler = 'bcc' ifTrue:[
   113         ^ 'Borland C-Compiler'.
   114     ].
   115     usedCompiler = 'vc' ifTrue:[
   116         ^ 'Microsoft Visual C Compiler'.
   117     ].
   118     usedCompiler = 'lcc' ifTrue:[
   119         ^ 'LCC C-Compiler'.
   120     ].
   121     usedCompiler = 'tcc' ifTrue:[
   122         ^ 'Tiny C-Compiler'.
   123     ].
   124     usedCompiler = 'gcc' ifTrue:[
   125         ^ 'GNU C-Compiler'.
   126     ].
   127     usedCompiler = 'mingw' ifTrue:[
   128         ^ 'MINGW GNU C-Compiler'.
   129     ].
   130     self halt:'unknown compiler'.
   131 
   132     ^ 'C-Compiler'.
   133 
   134     "Created: / 06-09-2012 / 15:58:33 / cg"
   135 ! !
   136 
   137 !ProjectBuilder methodsFor:'accessing'!
   138 
   139 buildDirectory
   140     ^ buildDirectory
   141 !
   142 
   143 buildDirectory:something
   144     buildDirectory := something.
   145 !
   146 
   147 isLocalBuild
   148     ^ isLocalBuild ? false
   149 !
   150 
   151 isLocalBuild:aBoolean
   152     "create a files without going through the source code manager"
   153 
   154     isLocalBuild := aBoolean.
   155 !
   156 
   157 isQuickBuild
   158     ^ isQuickBuild ? false
   159 !
   160 
   161 isQuickBuild:aBoolean
   162     "skips creation of header files, and copying of support files, if possible
   163      to speedup a build. Use with care."
   164 
   165     isQuickBuild := aBoolean.
   166 !
   167 
   168 makeExeOnly
   169     ^ (makeExeOnly ? false)
   170 !
   171 
   172 makeExeOnly:aBoolean
   173     makeExeOnly := aBoolean.
   174 !
   175 
   176 makeQuick
   177     ^ (makeQuick ? false)
   178 !
   179 
   180 makeQuick:aBoolean
   181     makeQuick := aBoolean.
   182 !
   183 
   184 package:aPackageIDOrSymbol
   185     package := aPackageIDOrSymbol asPackageId.
   186 !
   187 
   188 packageBuildDirectory
   189     "the directoray, where the deployable binary is created (xxxSetup.exe)"
   190 
   191     ^ buildDirectory / (package asPackageId module) / (package asPackageId directory)
   192 !
   193 
   194 projectDefinitionClass:something
   195     projectDefinitionClass := something.
   196 !
   197 
   198 suffixForHeaderFiles
   199     ^ OperatingSystem isUNIXlike ifTrue:['.H'] ifFalse:['.STH']
   200 !
   201 
   202 usedCompilerForBuild:something
   203     usedCompiler := something.
   204 
   205     "Created: / 22-01-2012 / 10:50:48 / cg"
   206 ! !
   207 
   208 !ProjectBuilder methodsFor:'building'!
   209 
   210 build
   211     "/ intermediate - this will move into a commonly used utility class
   212     "/ (where all the project code support will be collected).
   213 
   214     |makeOutput|
   215 
   216     makeOutput := TextStream on:(Text new:10000).
   217     self buildWithColorizedOutputTo:makeOutput.
   218 
   219     TextView openWith:makeOutput contents.
   220 !
   221 
   222 buildWithColorizedOutputTo:makeOutput
   223     "/ intermediate - this will move into a commonly used utility class
   224     "/ (where all the project code support will be collected).
   225 
   226     |lock|
   227 
   228     lock := Semaphore forMutualExclusion.
   229 
   230     stdErr := ActorStream new
   231                     nextPutBlock:[:char |
   232                         lock critical:[
   233                             makeOutput 
   234                                 withEmphasis:{#backgroundColor->Color red. #color->Color white.}
   235                                 do:[makeOutput nextPut:char].
   236                         ]
   237                     ];
   238                     nextPutAllBlock:[:string |
   239                         lock critical:[          
   240                             "/ (string includesString:'das Ziel' )ifTrue:[self halt].
   241                             makeOutput
   242                                 withEmphasis:{#backgroundColor->Color red. #color->Color white.}
   243                                 do:[makeOutput nextPutAll:string].
   244                         ]
   245                     ].
   246     stdOut := ActorStream new
   247                     nextPutBlock:[:char |
   248                         lock critical:[
   249                             makeOutput nextPut:char.
   250                         ]
   251                     ];
   252                     nextPutAllBlock:[:string |
   253                         lock critical:[         
   254                             "/ (string includesString:'das Ziel' )ifTrue:[self halt].
   255                             makeOutput nextPutAll:string.
   256                         ]
   257                     ].
   258 
   259     self buildWithOutputTo:stdOut errorTo:stdErr.
   260 
   261     "Modified: / 06-09-2012 / 16:15:50 / cg"
   262 !
   263 
   264 buildWithOutputTo:stdOutArg errorTo:stdErrArg
   265     "/ intermediate - this will move into a commonly used utility class
   266     "/ (where all the project code support will be collected).
   267 
   268     |module directory|
   269 
   270     projectDefinitionClass := ProjectDefinition definitionClassForPackage:package.
   271     projectDefinitionClass isNil ifTrue:[
   272         self error:('Missing ProjectDefinition class for "',package asString,'"')
   273     ].
   274 
   275     "/ ensure that everything is loaded...
   276     projectDefinitionClass loadAsAutoloaded:false.
   277     projectDefinitionClass loadExtensions.
   278     projectDefinitionClass loadAllClassesAsAutoloaded:false.
   279 
   280     module := package module.
   281     directory := package directory.
   282 
   283     buildDirectory isNil ifTrue:[
   284         buildDirectory := PreviousBuildDirectory ifNil:[ UserPreferences current buildDirectory ].
   285         buildDirectory isNil ifTrue:[
   286             buildDirectory := Filename tempDirectory construct:'stx_build'.
   287         ].
   288     ].
   289     buildDirectory := buildDirectory asFilename.
   290 
   291     "/ self validateBuildDirectoryIsPresent.
   292 
   293     PreviousBuildDirectory := buildDirectory.
   294 
   295     "/ UserPreferences current localBuild:true
   296     (self isLocalBuild or:[UserPreferences current localBuild]) ifFalse:[
   297         SourceCodeManager notNil ifTrue:[
   298             sourceCodeManager := SourceCodeManagerUtilities default sourceCodeManagerFor:projectDefinitionClass.
   299         ]
   300     ].
   301     sourceCodeManager := nil.
   302 
   303     myTopDirectory := 
   304         Smalltalk packagePath 
   305             detect:[:aPath |
   306                 (aPath asFilename / 'stx' / 'include') exists
   307                 and: [ (aPath asFilename / 'stx' / 'rules') exists ]]
   308             ifNone:nil.       
   309     myTopDirectory isNil ifTrue:[
   310         self error:('Cannot figure out my top directory (where stx/include and stx/rules are)')
   311     ].
   312     myTopDirectory := myTopDirectory asFilename.
   313     mySTXTopDirectory := myTopDirectory / 'stx'.
   314 
   315     self makeQuick ifFalse:[
   316         self setupBuildDirectory.
   317         self activityNotification:'Generating stc directory...'.
   318         self copySTCDirectoryForBuild.
   319     ].
   320     self activityNotification:'Generating source files...'.
   321     self generateSourceFiles.
   322     self makeQuick ifFalse:[
   323         self activityNotification:'Copying dlls for linkage...'.
   324         self copyDLLsForLinkage.
   325         self activityNotification:'Copying support files for compilation and linkage...'.
   326         self copySupportFilesForCompilation.
   327         self copySupportFilesForLinkage.
   328         self copyStartupFilesFromSmalltalk.
   329     ].
   330     self activityNotification:'Executing make...'.
   331     self makeWithOutputTo:stdOut errorTo:stdErr.
   332 
   333     "Modified: / 04-09-2012 / 00:49:52 / cg"
   334 ! !
   335 
   336 !ProjectBuilder methodsFor:'building/private'!
   337 
   338 copyDLLsForLinkage
   339     |targetBuildDir preRequisites dllRelativeSourcePathes dllRelativeDestPathes|
   340 
   341     targetBuildDir := buildDirectory / package module / package directory.
   342 
   343     preRequisites := projectDefinitionClass allPreRequisites.
   344     OperatingSystem isUNIXlike ifTrue:[
   345         "For now: unix Makefiles require some libs implicitely..."
   346         preRequisites := preRequisites union:#(
   347                                #'stx:goodies/refactoryBrowser/parser'
   348                                #'stx:libtool'
   349                             ).
   350     ].
   351 
   352     preRequisites do:[:eachPackageToFileout |
   353         |packageId packageDef packageModule packageDirectory packageTargetDir
   354          dllSource dllSourceDir libraryName dllRelativePathSource 
   355          dllRelativePathDest objDirSource objDirDest alternativeObjDirSource|
   356 
   357         packageId := eachPackageToFileout asPackageId.
   358         packageModule := packageId module.
   359         packageDirectory := packageId directory.
   360         packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
   361 
   362         packageDef := packageId projectDefinitionClass.
   363         libraryName := packageDef libraryName.
   364 
   365         "/ mhmh - take them from my tree or from the projects/smalltalk execution directory ??
   366         dllSourceDir := myTopDirectory / packageModule / packageDirectory.
   367 
   368         OperatingSystem isMSWINDOWSlike ifTrue:[
   369             objDirDest := self objDirForUsedCompiler:usedCompiler.
   370             objDirSource := objDirDest.
   371 "/            "/ use visual-c files for tcc linkage
   372 "/            usedCompiler = 'tcc' ifTrue:[
   373 "/                objDirSource := self objDirForUsedCompiler:'vc'.
   374 "/            ] ifFalse:[
   375 "/                objDirSource := objDirDest
   376 "/            ].
   377             (dllSourceDir / objDirSource / (libraryName, '.dll')) exists ifFalse:[
   378                 alternativeObjDirSource := self objDirForUsedCompiler:'vc'.
   379                 (dllSourceDir / alternativeObjDirSource / (libraryName, '.dll')) exists ifTrue:[
   380                     objDirSource := alternativeObjDirSource.
   381                     stdErr nextPutLine:(('Warning: using alternative %1 from %2 (%3 version)...' 
   382                                                 bindWith:libraryName 
   383                                                 with:alternativeObjDirSource 
   384                                                 with:(self class suiteNameOfCompiler:'vc'))
   385                                             emphasizeAllWith:(#color -> Color red darkened)).
   386                 ] ifFalse:[
   387                     alternativeObjDirSource := self objDirForUsedCompiler:'bcc'.
   388                     (dllSourceDir / alternativeObjDirSource / (libraryName, '.dll')) exists ifTrue:[
   389                         objDirSource := alternativeObjDirSource.
   390                         stdErr nextPutLine:('Warning: using alternative %1 from %2 (%3 version)...' 
   391                                     bindWith:libraryName 
   392                                     with:alternativeObjDirSource 
   393                                     with:(self class suiteNameOfCompiler:'bcc')).
   394                     ]
   395                 ].
   396             ].
   397 
   398 "/            dllRelativePath := objDir,'/',(libraryName,'.dll').
   399 "/            (dllSourceDir / dllRelativePath) exists 
   400             dllRelativeSourcePathes := Array with:(objDirSource,'\', libraryName, '.dll').
   401             dllRelativeDestPathes := Array with:(objDirDest,'\', libraryName, '.dll').
   402         ] ifFalse:[
   403             dllRelativeSourcePathes := Array with:(libraryName,'.so').
   404             dllRelativeDestPathes := Array with:(libraryName, '.so').
   405             (packageModule = 'stx' and:[packageDirectory = 'libview']) ifTrue:[
   406                 dllRelativeSourcePathes := dllRelativeSourcePathes copyWith:('XWorkstation.so').
   407                 dllRelativeDestPathes := dllRelativeDestPathes copyWith:'XWorkstation.so'.
   408                 dllRelativeSourcePathes := dllRelativeSourcePathes copyWith:('GLXWorkstation.so').
   409                 dllRelativeDestPathes := dllRelativeDestPathes copyWith:'GLXWorkstation.so'.
   410             ].
   411         ].
   412         dllRelativeSourcePathes with:dllRelativeDestPathes do:[:dllRelativeSourcePath :dllRelativeDestPath|
   413             |source dest|
   414 
   415             source := dllSourceDir / dllRelativeSourcePath.
   416             source exists ifFalse:[
   417                 self activityNotification:'   skip missing file: ',source pathName.
   418             ] ifTrue:[
   419                 dest := packageTargetDir / dllRelativeDestPath.
   420                 (dest exists not
   421                  or:[source fileSize ~= dest fileSize
   422                  or:[source modificationTime >= dest modificationTime
   423                  "/ or:[ ((dllSourceDir / dllRelativePath) sameContentsAs:(packageTargetDir / dllRelativePath)) not ]
   424                 ]]) ifTrue:[
   425                     Transcript showCR:'updating ',dllRelativeDestPath.
   426                     dest directory recursiveMakeDirectory.
   427                     source copyTo:dest.    
   428                 ].
   429             ]
   430         ].
   431     ].
   432 
   433     "Modified: / 06-09-2012 / 16:19:29 / cg"
   434 !
   435 
   436 copyDirectory:relativepath
   437     "/ need rules in stx
   438     ((Smalltalk projectDirectoryForPackage:'stx') asFilename construct:relativepath)
   439         recursiveCopyTo:(buildDirectory construct:'stx').
   440 !
   441 
   442 copyDirectoryForBuild:subdir
   443     |targetDir targetFile|
   444 
   445     targetDir := buildDirectory / 'stx' / subdir.
   446     targetDir exists ifFalse:[
   447         targetDir makeDirectory.
   448     ] ifTrue:[
   449         self isQuickBuild ifTrue:[^ self]
   450     ].
   451     (mySTXTopDirectory / subdir) directoryContentsAsFilenamesDo:[:eachFile |
   452         eachFile isDirectory ifFalse:[
   453             targetFile := targetDir / eachFile baseName.
   454             (targetFile exists not
   455             or:[ targetFile modificationTime < eachFile modificationTime ]) ifTrue:[
   456                 self activityNotification:'copying ',eachFile pathName,'...'.
   457                 eachFile copyTo:(targetDir construct:eachFile baseName)
   458             ]
   459         ].
   460     ].
   461     self activityNotification:nil
   462 !
   463 
   464 copyResourcesForPackage:aPackage
   465     |module directory myPackageDirectory rsrcDir stylesDir|
   466 
   467     module := aPackage asPackageId module.
   468     directory := aPackage asPackageId directory.
   469 
   470     myPackageDirectory := myTopDirectory / module / directory.
   471 
   472     (rsrcDir := myPackageDirectory / 'resources' ) exists ifTrue:[
   473         rsrcDir recursiveCopyTo:(buildDirectory / module / directory)
   474     ].
   475     (stylesDir := myPackageDirectory / 'styles' ) exists ifTrue:[
   476         stylesDir recursiveCopyTo:(buildDirectory / module / directory)
   477     ].
   478 !
   479 
   480 copySTCDirectoryForBuild
   481     "copy stc files to the build directory"
   482 
   483     |targetDir stc files|
   484 
   485     targetDir := buildDirectory / 'stx' / 'stc'.
   486     targetDir exists ifFalse:[ targetDir makeDirectory ].
   487 
   488     stc := OperatingSystem isMSWINDOWSlike 
   489                 ifTrue:[ 'stc.exe' ]
   490                 ifFalse:[ 'stc' ].
   491 
   492     files := #( ) copyWith:stc.
   493 
   494     files do:[:eachFile |
   495         |sourceFile targetFile|
   496 
   497         sourceFile := mySTXTopDirectory / 'stc' / eachFile.
   498         targetFile := targetDir / eachFile.
   499         (targetFile exists not
   500         or:[ targetFile modificationTime < sourceFile modificationTime ]) ifTrue:[
   501             self activityNotification:'copying ',sourceFile pathName,'...'.
   502             sourceFile copyTo:targetFile
   503         ].
   504     ].
   505 
   506     OperatingSystem isUNIXlike ifTrue:[
   507         (targetDir / 'stc') makeExecutableForAll    
   508     ].
   509 
   510     self activityNotification:nil
   511 
   512     "Modified (comment): / 04-09-2012 / 00:49:19 / cg"
   513 !
   514 
   515 copyStartupFilesFromSmalltalk
   516     "copy additional smalltalk startup files to the build directory"
   517 
   518     (buildDirectory / 'stx' / 'projects/smalltalk' ) exists ifFalse:[
   519         (buildDirectory / 'stx' / 'projects/smalltalk' ) recursiveMakeDirectory.
   520     ].
   521 
   522     #( 
   523         'keyboard.rc' 
   524         'keyboardMacros.rc' 
   525         'display.rc' 
   526         'd_win32.rc'
   527         'host.rc' 
   528         'h_win32.rc'  
   529         'smalltalk.rc'  
   530         'private.rc'  
   531     ) do:[:fn |
   532         (myTopDirectory / 'stx' / 'projects/smalltalk' / fn)
   533             copyTo: (buildDirectory / 'stx' / 'projects/smalltalk' / fn)
   534     ].
   535 
   536     (myTopDirectory / 'stx' / 'doc/online/english/LICENCE_STX.html')
   537             copyTo: (buildDirectory / 'stx' / 'projects/smalltalk' / 'LICENCE_STX.html').
   538 
   539     "Modified (comment): / 04-09-2012 / 00:48:47 / cg"
   540 !
   541 
   542 copySupportFilesForCompilation
   543     "copy the tcc compiler to the build directory"
   544 
   545     |files|
   546 
   547     files := #().
   548 
   549     OperatingSystem isMSWINDOWSlike ifTrue:[
   550         files := files , #( 'librun/genDate.com' ).
   551         usedCompiler = 'tcc' ifTrue:[
   552             files := files , #( 
   553                         'support/tcc'
   554                     ).
   555         ].
   556     ] ifFalse:[
   557         files := files , #( 'librun/genDate' ).
   558     ].
   559 
   560     files do:[:relativePath |
   561         (mySTXTopDirectory / relativePath) exists ifTrue:[
   562             ((buildDirectory / 'stx' / relativePath) exists
   563             and:[ (mySTXTopDirectory / relativePath) fileSize = (buildDirectory / 'stx' / relativePath) fileSize
   564             and:[ (mySTXTopDirectory / relativePath) modificationTime < (buildDirectory / 'stx' / relativePath) modificationTime
   565             "/ and:[ (mySTXTopDirectory / dllRelativePath) sameContentsAs:(targetBuildDir / dllRelativePath) ]
   566             ]]) ifFalse:[
   567                 (mySTXTopDirectory / relativePath) recursiveCopyTo:(buildDirectory / 'stx' / relativePath).    
   568             ]
   569         ] ifFalse:[
   570             self error:'Missing directory: ',relativePath printString mayProceed:true.
   571         ].
   572     ].
   573 
   574     "Created: / 04-09-2012 / 00:47:49 / cg"
   575 !
   576 
   577 copySupportFilesForLinkage
   578     "copy additional files which are req'd for linkage to the build directory"
   579 
   580     |files|
   581 
   582     OperatingSystem isMSWINDOWSlike ifTrue:[
   583         files := #( 
   584                     'librun/genDate.com'
   585                     'librun/main.c'
   586                     'projects/smalltalk/stx_16x16.ico'
   587                     'projects/smalltalk/stx_32x32.ico'
   588                     'projects/smalltalk/stx_splash.bmp'
   589                  ).
   590 
   591         usedCompiler = 'bcc' ifTrue:[
   592             files := files , #( 
   593                         'librun/objbc/librun.dll'
   594                         'support/win32/borland/cs3245.dll' 
   595                         'support/win32/X11.dll'
   596                         'support/win32/Xext.dll'
   597                         'lib/bc/librun.lib'
   598                         'lib/bc/cs32i.lib'
   599                     ).
   600         ].
   601         usedCompiler = 'vc' ifTrue:[
   602             files := files , #( 
   603                         'librun/objvc/librun.dll'
   604                         'lib/vc/librun.lib'
   605                     ).
   606         ].
   607         usedCompiler = 'tcc' ifTrue:[
   608             files := files , #( 
   609                         'librun/objvc/librun.dll'   "/ linkage is against vc version!!
   610                         'lib/vc/librun.lib'
   611                     ).
   612         ].
   613         usedCompiler = 'lcc' ifTrue:[
   614             files := files , #( 
   615                         'librun/objvc/librun.dll'   "/ linkage is against vc version!!
   616                         'lib/vc/librun.lib'
   617                     ).
   618         ].
   619         usedCompiler = 'mingw' ifTrue:[
   620             files := files , #( 
   621                         'librun/objmingw/librun.dll'   "/ linkage is against vc version!!
   622                         'lib/mingw/librun.lib'
   623                     ).
   624         ].
   625     ] ifFalse:[
   626         files := #(
   627                     'librun/main.c'
   628                     'librun/librun.so'
   629                 )
   630     ].
   631     files := files asOrderedCollection.
   632 
   633     OperatingSystem isMSWINDOWSlike ifTrue:[
   634         projectDefinitionClass applicationIconFileName notNil ifTrue:[
   635             files add:('projects/smalltalk/',projectDefinitionClass applicationIconFileName,'.ico')
   636         ].
   637         projectDefinitionClass splashFileName notNil ifTrue:[
   638             files add:('projects/smalltalk/',projectDefinitionClass splashFileName,'.bmp')
   639         ].
   640     ].
   641 
   642     files do:[:relativePath |
   643         (mySTXTopDirectory / relativePath) exists ifTrue:[
   644             ((buildDirectory / 'stx' / relativePath) exists
   645             and:[ (mySTXTopDirectory / relativePath) fileSize = (buildDirectory / 'stx' / relativePath) fileSize
   646             and:[ (mySTXTopDirectory / relativePath) modificationTime < (buildDirectory / 'stx' / relativePath) modificationTime
   647             "/ and:[ (mySTXTopDirectory / dllRelativePath) sameContentsAs:(targetBuildDir / dllRelativePath) ]
   648             ]]) ifFalse:[
   649                 (buildDirectory / 'stx' / relativePath) directory recursiveMakeDirectory.
   650                 (mySTXTopDirectory / relativePath) copyTo:(buildDirectory / 'stx' / relativePath).    
   651             ]
   652         ] ifFalse:[
   653 "/ does not really help: objbc/librun.lib does not work with MSVC and vice versa...
   654 "/            ((relativePath = 'librun/objvc/librun.dll')
   655 "/            and:[ (mySTXTopDirectory / 'librun/objbc/librun.dll') exists ])ifTrue:[
   656 "/                stdErr nextPutLine:('Warning: using alternative librun from objbc (Borland version)...'). 
   657 "/                (buildDirectory / 'stx' / relativePath) directory recursiveMakeDirectory.
   658 "/                (mySTXTopDirectory / 'librun/objbc/librun.dll') copyTo:(buildDirectory / 'stx' / relativePath).    
   659 "/            ] ifFalse:[
   660 "/                ((relativePath = 'librun/objbc/librun.dll')
   661 "/                and:[ (mySTXTopDirectory / 'librun/objvc/librun.dll') exists ])ifTrue:[
   662 "/                    stdErr nextPutLine:('Warning: using alternative librun from objvc (MSVC version)...'). 
   663 "/                    (buildDirectory / 'stx' / relativePath) directory recursiveMakeDirectory.
   664 "/                    (mySTXTopDirectory / 'librun/objvc/librun.dll') copyTo:(buildDirectory / 'stx' / relativePath).    
   665 "/                ] ifFalse:[
   666                     self error:'Missing file: ',relativePath printString mayProceed:true.
   667 "/                ]
   668 "/            ]
   669         ].
   670     ].
   671 
   672     "Modified: / 05-09-2012 / 16:26:25 / cg"
   673 !
   674 
   675 createHeaderFileFor:aClass in:packageTargetDir
   676     |instVarList classInstVarList classVarList bindings superclassFilename
   677      template file newContents oldContents|
   678 
   679     instVarList := StringCollection new.
   680     aClass instVarNames do:[:v |
   681         instVarList add:('OBJ %1;' bindWith:v)
   682     ].
   683     classInstVarList := StringCollection new.
   684     aClass class instVarNames do:[:v |
   685     "/ (v includes:$_) ifTrue:[self halt].
   686         classInstVarList add:('OBJ %1;' bindWith:v)
   687     ].
   688     classVarList := StringCollection new.
   689     aClass classVarNames do:[:v |
   690         classVarList add:('extern OBJ %1_%2;' bindWith:aClass name with:v)
   691     ].
   692 
   693     bindings := Dictionary new.
   694     bindings at:'ClassName' put:aClass name. 
   695     aClass superclass isNil ifTrue:[
   696         bindings at:'SuperclassName' put:'-'. 
   697         bindings at:'SuperclassFileInclude' put:''.
   698     ] ifFalse:[
   699         bindings at:'SuperclassName' put:aClass superclass name. 
   700         bindings at:'SuperclassFileName' put:(superclassFilename := Smalltalk fileNameForClass:aClass superclass).
   701         bindings at:'SuperclassFileInclude' put:('#include "%1.STH"' bindWith:superclassFilename).
   702     ].
   703     bindings at:'InstVarList' put:instVarList asString. 
   704     bindings at:'ClassVarList' put:classVarList asString. 
   705     bindings at:'ClassInstVarList' put:classInstVarList asString. 
   706 
   707     template := 
   708 '/* This file was generated by ProjectBuilder. */
   709 /* !!!!!!!! Do not change by hand !!!!!!!! */
   710 
   711 /* Class: %(ClassName) */
   712 /* Superclass: %(SuperclassName) */
   713 
   714 %(SuperclassFileInclude)
   715 
   716 /* INDIRECTGLOBALS */
   717 #ifdef _HEADER_INST_
   718 %(InstVarList)
   719 #endif /* _HEADER_INST_ */
   720 
   721 #ifdef _HEADER_CLASS_
   722 %(ClassVarList)
   723 #endif /* _HEADER_CLASS_ */
   724 
   725 #ifdef _HEADER_CLASSINST_
   726 %(ClassInstVarList)
   727 #endif /* _HEADER_CLASSINST_ */
   728 '.
   729     newContents := template bindWithArguments:bindings.
   730     file := packageTargetDir asFilename / ((Smalltalk fileNameForClass:aClass),(self suffixForHeaderFiles)).
   731     (file exists not
   732     or:[ (oldContents := file contents) ~= newContents ]) ifTrue:[
   733         file contents: newContents.
   734     ].
   735 
   736     "Modified: / 15-08-2011 / 14:58:46 / cg"
   737 !
   738 
   739 generateSourceFiles
   740     (self isLocalBuild not and:[ sourceCodeManager notNil ])  ifTrue:[
   741         "/ check out / generate files there
   742         self generateSourceFilesByCheckingOutUsing:sourceCodeManager
   743     ] ifFalse:[
   744         "/ local build
   745         "/ fileout the project
   746         self generateSourceFilesByFilingOut
   747     ]
   748 !
   749 
   750 generateSourceFilesByCheckingOutUsing:aSourceCodeManager
   751     "/ will no longer be needed/supported
   752 
   753     |repository stxRepository module directory|
   754 
   755     self breakPoint:#cg.
   756 
   757     "/ check out / generate files there
   758     repository := (aSourceCodeManager repositoryNameForModule:module) ifNil:[aSourceCodeManager repositoryName].
   759     stxRepository := aSourceCodeManager repositoryName.
   760 
   761     (buildDirectory construct:'stx') exists ifFalse:[
   762         (module ~= 'stx') ifTrue:[
   763             OperatingSystem
   764                 executeCommand:('cvs -d ',stxRepository,' co stx')
   765                 inputFrom:nil
   766                 outputTo:Transcript
   767                 errorTo:Transcript
   768                 inDirectory:buildDirectory
   769                 onError:[:status| self error:'cvs update stx failed'].
   770         ].
   771     ].
   772 
   773     ((buildDirectory construct:module) construct:'CVS') exists ifFalse:[
   774         OperatingSystem
   775             executeCommand:('cvs -d ',repository,' co -l ',directory)
   776             inputFrom:nil
   777             outputTo:Transcript
   778             errorTo:Transcript
   779             inDirectory:buildDirectory
   780             onError:[:status| self error:'cvs update failed'].
   781     ].
   782     OperatingSystem
   783         executeCommand:'cvs upd -d'
   784         inputFrom:nil
   785         outputTo:Transcript
   786         errorTo:Transcript
   787         inDirectory:(buildDirectory construct:module)
   788         onError:[:status| self error:'cvs update failed'].
   789 self halt.
   790 
   791     "Modified: / 29-12-2011 / 14:02:56 / cg"
   792 !
   793 
   794 generateSourceFilesByFilingOut
   795     "/ local build
   796     "/ fileout the project
   797 
   798     |fullPathName|
   799 
   800     (package module ~= 'stx') ifTrue:[
   801         (buildDirectory / package module) makeDirectory.
   802     ].
   803 
   804     "/ file out the package(s) which are to be built
   805     ((Array with:package))
   806     do:[:eachPackageToFileout |
   807         |packageId packageModule packageDirectory packageTargetDir packageDef extSource|
   808 
   809         packageId := eachPackageToFileout asPackageId.
   810         packageModule := packageId module.
   811         packageDirectory := packageId directory.
   812         packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
   813 
   814         packageDef := packageId projectDefinitionClass.
   815         (packageDef compiled_classNames_common ,
   816         packageDef compiled_classNamesForPlatform) do:[:eachClassName |
   817             |cls fileName newSource|
   818 
   819             cls := Smalltalk classNamed:eachClassName.
   820             self assert:cls isLoaded.
   821             fileName := (Smalltalk fileNameForClass:cls),'.st'.
   822             fileName := packageTargetDir asFilename construct:fileName.
   823             fileName exists ifTrue:[
   824                 newSource := String streamContents:[:s | cls fileOutOn:s withTimeStamp:false].
   825                 newSource = fileName contentsAsString ifFalse:[
   826                     fileName contents:newSource
   827                 ].
   828             ] ifFalse:[
   829                 cls fileOutIn:packageTargetDir withTimeStamp:false
   830             ].
   831         ].
   832 
   833         packageDef hasExtensionMethods ifTrue:[
   834             extSource := 
   835                 String streamContents:[:s |
   836                     packageDef extensionMethods do:[:eachMethod |
   837                         eachMethod mclass fileOutMethod:eachMethod on:s
   838                     ].
   839                 ].
   840                 (packageTargetDir asFilename construct:'extensions.st') contents:extSource
   841         ].
   842 
   843 "/        (Smalltalk allClassesInPackage:eachPackageToFileout) do:[:cls |
   844 "/            cls isPrivate ifFalse:[
   845 "/                cls isLoaded ifFalse:[
   846 "/                    self halt.
   847 "/                    cls autoload.
   848 "/                ].
   849 "/                cls fileOutIn:packageTargetDir
   850 "/            ]
   851 "/        ].
   852 
   853         projectDefinitionClass forEachFileNameAndGeneratedContentsDo:[:fileName :fileContents |
   854             fullPathName := packageTargetDir construct:fileName.
   855             fullPathName directory exists ifFalse:[
   856                 "take care for files like 'autopackage/default.apspec'"
   857                 fullPathName directory makeDirectory.
   858             ].
   859             (fullPathName exists
   860              and:[ fullPathName contents = fileContents ]) ifFalse:[
   861                 fullPathName contents:fileContents.
   862             ].
   863         ].    
   864     ].
   865     self makeQuick ifFalse:[
   866         "/ generate header files in prerequisite packages...
   867         (projectDefinitionClass allPreRequisites)
   868         do:[:eachPackageToFileout |
   869             |packageId packageDef packageModule packageDirectory packageTargetDir|
   870 
   871             packageId := eachPackageToFileout asPackageId.
   872             packageModule := packageId module.
   873             packageDirectory := packageId directory.
   874             packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
   875 
   876             packageDef := packageId projectDefinitionClass.
   877             (packageDef compiled_classNames_common ,
   878             packageDef compiled_classNamesForPlatform) do:[:eachClassName |
   879                 |cls|
   880 
   881                 cls := Smalltalk classNamed:eachClassName.
   882                 "/ self assert:cls isLoaded.
   883                 cls isNil ifTrue:[
   884                     stdErr nextPutLine:('Missing class: ',eachClassName, ' (not present in system. Warning only:subclasses of it will not be compiled)').
   885                 ] ifFalse:[
   886                     cls isLoaded ifTrue:[    
   887                         self createHeaderFileFor:cls in:packageTargetDir
   888                     ]
   889                 ].
   890             ].
   891             self copyResourcesForPackage:eachPackageToFileout.
   892         ].
   893     ].
   894 
   895 "/    stx_libbasic2 preRequisitesForBuilding#(#'stx:libbasic')
   896 !
   897 
   898 makeCommandOfCompiler:usedCompiler
   899     usedCompiler = 'bcc' ifTrue:[ 
   900         ^ 'bmake'.
   901     ].
   902     usedCompiler = 'vc' ifTrue:[ 
   903         ^ 'vcmake'. "/ compilerFlag := '-DUSEVC' 
   904     ].
   905     usedCompiler = 'lcc' ifTrue:[ 
   906         ^ 'lccmake'. "/ compilerFlag := '-DUSELCC' 
   907     ].
   908     usedCompiler = 'tcc' ifTrue:[ 
   909         ^ 'tccmake'. "/ compilerFlag := '-DUSELCC' 
   910     ].
   911     usedCompiler = 'gcc' ifTrue:[ 
   912         ^ 'make'.       "/ compilerFlag := '-DUSEGCC' 
   913     ].
   914     usedCompiler = 'mingw' ifTrue:[ 
   915         ^ 'mingwmake'.  "/ compilerFlag := '-DUSEMINGW' 
   916     ].
   917     self error:'unknown compiler specified'.
   918 
   919     "Created: / 03-09-2012 / 19:46:07 / cg"
   920 !
   921 
   922 makeWithOutputTo:stdOut errorTo:stdErr
   923     |module directory makeCommand|
   924 
   925     module := package module.
   926     directory := package directory.
   927 
   928     makeCommand := ParserFlags makeCommand.
   929     usedCompiler isNil ifTrue:[
   930         usedCompiler := ParserFlags usedCompiler.
   931     ].
   932     makeCommand := self makeCommandOfCompiler:usedCompiler.
   933 
   934     "/ makeCommand := makeCommand, ' TOP=', mySTXTopDirectory pathName.
   935 
   936     OperatingSystem isUNIXlike ifTrue:[
   937         "/ generate the makefile first
   938         self activityNotification:('sh %1/rules/stmkmf' bindWith:mySTXTopDirectory pathName).
   939         OperatingSystem
   940             executeCommand:('sh %1/rules/stmkmf' bindWith:mySTXTopDirectory pathName)
   941             inputFrom:nil
   942             outputTo:stdOut
   943             errorTo:stdErr
   944             inDirectory:(buildDirectory / module / directory)
   945             onError:[:status | self error:'make failed'].
   946     ].
   947 
   948     projectDefinitionClass isLibraryDefinition ifTrue:[
   949         "/ generate the library
   950         self activityNotification:(makeCommand,' classLibRule').
   951         OperatingSystem
   952             executeCommand:(makeCommand,' classLibRule')
   953             inputFrom:nil
   954             outputTo:stdOut
   955             errorTo:stdErr
   956             inDirectory:(buildDirectory / module / directory)
   957             onError:[:status | self error:'make failed'].
   958     ] ifFalse:[
   959         (self makeExeOnly) ifTrue:[
   960             self activityNotification:(makeCommand,' exe').
   961             OperatingSystem
   962                 "/ generate the executable
   963                 executeCommand:(makeCommand,' exe')
   964                 inputFrom:nil
   965                 outputTo:stdOut
   966                 errorTo:stdErr
   967                 inDirectory:(buildDirectory / module / directory)
   968                 onError:[:status | self error:'make failed'].
   969 
   970         ] ifFalse:[
   971             "/ generate the self-installable package
   972             self activityNotification:(makeCommand,' ALL_NP').
   973             OperatingSystem
   974                 executeCommand:(makeCommand,' ALL_NP')
   975                 inputFrom:nil
   976                 outputTo:stdOut
   977                 errorTo:stdErr
   978                 inDirectory:(buildDirectory / module / directory)
   979                 onError:[:status | self error:'make failed'].
   980         ]
   981     ]
   982 
   983     "Modified: / 03-09-2012 / 19:47:15 / cg"
   984     "Modified (comment): / 06-09-2012 / 16:22:38 / cg"
   985 !
   986 
   987 objDirForUsedCompiler
   988     ^ self objDirForUsedCompiler:usedCompiler
   989 
   990     "Created: / 20-08-2012 / 17:01:13 / cg"
   991 !
   992 
   993 objDirForUsedCompiler:usedCompiler
   994     usedCompiler = 'gcc' ifTrue:[^ 'obj'].      "/ unix case
   995 
   996     usedCompiler = 'bcc' ifTrue:[^ 'objbc'].
   997     usedCompiler = 'vc' ifTrue:[^ 'objvc'].
   998     usedCompiler = 'tcc' ifTrue:[^ 'objtcc'].
   999     usedCompiler = 'lcc' ifTrue:[^ 'objlcc'].
  1000     usedCompiler = 'mingw' ifTrue:[^ 'objmingw'].
  1001     self halt:'please add compiler here'.
  1002     ^ 'objbc'
  1003 
  1004     "Created: / 03-09-2012 / 19:55:34 / cg"
  1005 !
  1006 
  1007 recursiveCopyDirectoryForBuild:subdir
  1008     |targetDir|
  1009 
  1010     targetDir := buildDirectory / 'stx' / subdir.
  1011     targetDir exists ifFalse:[
  1012         targetDir makeDirectory.
  1013     ].
  1014     (mySTXTopDirectory / subdir) directoryContentsAsFilenamesDo:[:eachFile |
  1015         eachFile recursiveCopyTo:(targetDir construct:eachFile baseName)
  1016     ].
  1017     self activityNotification:nil
  1018 !
  1019 
  1020 setupBuildDirectory
  1021     buildDirectory exists ifFalse:[
  1022         buildDirectory recursiveMakeDirectory.
  1023     ].
  1024     (buildDirectory / 'stx') exists ifFalse:[
  1025         (buildDirectory / 'stx') makeDirectory.
  1026     ].
  1027 
  1028     self copyDirectoryForBuild:'include'.
  1029     self copyDirectoryForBuild:'rules'.
  1030     OperatingSystem isUNIXlike ifTrue:[
  1031         self recursiveCopyDirectoryForBuild:'configurations'.
  1032     ]
  1033 !
  1034 
  1035 validateBuildDirectoryIsPresent
  1036 
  1037     ^ self.
  1038 
  1039 "/    [
  1040 "/        |default directoryIsOKForMe stc |
  1041 "/
  1042 "/        default := (buildDirectory ?
  1043 "/                          PreviousBuildDirectory)
  1044 "/                          ifNil:[ UserPreferences current buildDirectory].
  1045 "/
  1046 "/        buildDirectory := Dialog requestDirectoryName:'Temporary Work-ROOT for build:'
  1047 "/                                 default:default.
  1048 "/
  1049 "/        buildDirectory isEmptyOrNil ifTrue:[^ self].
  1050 "/        buildDirectory := buildDirectory asFilename.
  1051 "/        directoryIsOKForMe := true.
  1052 "/
  1053 "/        buildDirectory exists ifFalse:[
  1054 "/            Dialog warn:(self classResources string:'Work directory %1 does not exist.' with:buildDirectory).
  1055 "/            directoryIsOKForMe := false.
  1056 "/        ] ifTrue:[
  1057 "/            (buildDirectory construct:'stx') exists ifFalse:[
  1058 "/                Dialog warn:(self classResources stringWithCRs:'Work directory must contain an stx subDirectory,\which contains (at least) the stc and include subdirectories.').
  1059 "/                directoryIsOKForMe := false.
  1060 "/            ] ifTrue:[
  1061 "/                stc := (OperatingSystem isMSDOSlike) ifTrue:['stc.exe'] ifFalse:['stc'].
  1062 "/                (((buildDirectory construct:'stx')construct:'stc')construct:stc) exists ifFalse:[
  1063 "/                    Dialog warn:(self classResources stringWithCRs:'Work directory must contain an stc compiler in the stx/stc subDirectory.').
  1064 "/                    directoryIsOKForMe := false.
  1065 "/                ].
  1066 "/                ((buildDirectory construct:'stx')construct:'include') exists ifFalse:[
  1067 "/                    Dialog warn:(self classResources stringWithCRs:'Work directory must have had a make run before (for include files to exists).').
  1068 "/                    directoryIsOKForMe := false.
  1069 "/                ].
  1070 "/            ]
  1071 "/        ].
  1072 "/        directoryIsOKForMe
  1073 "/    ] whileFalse
  1074 ! !
  1075 
  1076 !ProjectBuilder class methodsFor:'documentation'!
  1077 
  1078 version
  1079     ^ '$Header$'
  1080 !
  1081 
  1082 version_CVS
  1083     ^ '$Header$'
  1084 ! !
  1085