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