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