ProjectBuilder.st
author Claus Gittinger <cg@exept.de>
Wed, 05 Oct 2016 19:02:48 +0200
changeset 3332 37a32de127ba
parent 3321 08f3a7af6975
child 3333 32dc40dc06cf
permissions -rw-r--r--
#UI_ENHANCEMENT by cg
class: Tools::ProjectBuilder
added: #determineBuildDirectory
changed:
#buildDirectory
#buildWithOutputTo:errorTo:
     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|
   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         projectDefinitionClass applicationIconFileName notNil ifTrue:[
   656             files add:('projects/smalltalk/',projectDefinitionClass applicationIconFileName,'.ico')
   657         ].
   658         projectDefinitionClass splashFileName notNil ifTrue:[
   659             files add:('projects/smalltalk/',projectDefinitionClass splashFileName,'.bmp')
   660         ].
   661     ].
   662 
   663     files do:[:relativePath |
   664         (mySTXTopDirectory / relativePath) exists ifTrue:[
   665             ((buildDirectory / 'stx' / relativePath) exists
   666             and:[ (mySTXTopDirectory / relativePath) fileSize = (buildDirectory / 'stx' / relativePath) fileSize
   667             and:[ (mySTXTopDirectory / relativePath) modificationTime < (buildDirectory / 'stx' / relativePath) modificationTime
   668             "/ and:[ (mySTXTopDirectory / dllRelativePath) sameContentsAs:(targetBuildDir / dllRelativePath) ]
   669             ]]) ifFalse:[
   670                 (buildDirectory / 'stx' / relativePath) directory recursiveMakeDirectory.
   671                 (mySTXTopDirectory / relativePath) copyTo:(buildDirectory / 'stx' / relativePath).    
   672             ]
   673         ] ifFalse:[
   674 "/ does not really help: objbc/librun.lib does not work with MSVC and vice versa...
   675 "/            ((relativePath = 'librun/objvc/librun.dll')
   676 "/            and:[ (mySTXTopDirectory / 'librun/objbc/librun.dll') exists ])ifTrue:[
   677 "/                stdErr nextPutLine:('Warning: using alternative librun from objbc (Borland version)...'). 
   678 "/                (buildDirectory / 'stx' / relativePath) directory recursiveMakeDirectory.
   679 "/                (mySTXTopDirectory / 'librun/objbc/librun.dll') copyTo:(buildDirectory / 'stx' / relativePath).    
   680 "/            ] ifFalse:[
   681 "/                ((relativePath = 'librun/objbc/librun.dll')
   682 "/                and:[ (mySTXTopDirectory / 'librun/objvc/librun.dll') exists ])ifTrue:[
   683 "/                    stdErr nextPutLine:('Warning: using alternative librun from objvc (MSVC version)...'). 
   684 "/                    (buildDirectory / 'stx' / relativePath) directory recursiveMakeDirectory.
   685 "/                    (mySTXTopDirectory / 'librun/objvc/librun.dll') copyTo:(buildDirectory / 'stx' / relativePath).    
   686 "/                ] ifFalse:[
   687                     self error:'Missing file: ',relativePath printString mayProceed:true.
   688 "/                ]
   689 "/            ]
   690         ].
   691     ].
   692 
   693     "Modified: / 05-09-2012 / 16:26:25 / cg"
   694 !
   695 
   696 createHeaderFileFor:aClass in:packageTargetDir
   697     |instVarList classInstVarList classVarList bindings superclassFilename
   698      template file newContents oldContents|
   699 
   700     instVarList := StringCollection new.
   701     aClass instVarNames do:[:v |
   702         instVarList add:('OBJ %1;' bindWith:v)
   703     ].
   704     classInstVarList := StringCollection new.
   705     aClass class instVarNames do:[:v |
   706     "/ (v includes:$_) ifTrue:[self halt].
   707         classInstVarList add:('OBJ %1;' bindWith:v)
   708     ].
   709     classVarList := StringCollection new.
   710     aClass classVarNames do:[:v |
   711         classVarList add:('extern OBJ %1_%2;' bindWith:aClass name with:v)
   712     ].
   713 
   714     bindings := Dictionary new.
   715     bindings at:'ClassName' put:aClass name. 
   716     aClass superclass isNil ifTrue:[
   717         bindings at:'SuperclassName' put:'-'. 
   718         bindings at:'SuperclassFileInclude' put:''.
   719     ] ifFalse:[
   720         bindings at:'SuperclassName' put:aClass superclass name. 
   721         bindings at:'SuperclassFileName' put:(superclassFilename := Smalltalk fileNameForClass:aClass superclass).
   722         bindings at:'SuperclassFileInclude' put:('#include "%1.STH"' bindWith:superclassFilename).
   723     ].
   724     bindings at:'InstVarList' put:instVarList asString. 
   725     bindings at:'ClassVarList' put:classVarList asString. 
   726     bindings at:'ClassInstVarList' put:classInstVarList asString. 
   727 
   728     template := 
   729 '/* This file was generated by ProjectBuilder. */
   730 /* !!!!!!!! Do not change by hand !!!!!!!! */
   731 
   732 /* Class: %(ClassName) */
   733 /* Superclass: %(SuperclassName) */
   734 
   735 %(SuperclassFileInclude)
   736 
   737 /* INDIRECTGLOBALS */
   738 #ifdef _HEADER_INST_
   739 %(InstVarList)
   740 #endif /* _HEADER_INST_ */
   741 
   742 #ifdef _HEADER_CLASS_
   743 %(ClassVarList)
   744 #endif /* _HEADER_CLASS_ */
   745 
   746 #ifdef _HEADER_CLASSINST_
   747 %(ClassInstVarList)
   748 #endif /* _HEADER_CLASSINST_ */
   749 '.
   750     newContents := template bindWithArguments:bindings.
   751     file := packageTargetDir asFilename / ((Smalltalk fileNameForClass:aClass),(self suffixForHeaderFiles)).
   752     (file exists not
   753     or:[ (oldContents := file contents) ~= newContents ]) ifTrue:[
   754         file contents: newContents.
   755     ].
   756 
   757     "Modified: / 15-08-2011 / 14:58:46 / cg"
   758 !
   759 
   760 determineBuildDirectory
   761     buildDirectory isNil ifTrue:[
   762         buildDirectory := PreviousBuildDirectory ifNil:[ UserPreferences current buildDirectory ].
   763         buildDirectory isNil ifTrue:[
   764             buildDirectory := Filename tempDirectory construct:'stx_build'.
   765         ].
   766     ].
   767     buildDirectory := buildDirectory asFilename.
   768 !
   769 
   770 generateBuildSupportFilesByFilingOutIn:packageTargetDir forDefinitionClass:projectDefinitionClass
   771     |fullPathName|
   772 
   773     projectDefinitionClass forEachFileNameAndGeneratedContentsDo:[:fileName :fileContents |
   774         fullPathName := packageTargetDir construct:fileName.
   775         fullPathName directory exists ifFalse:[
   776             "take care for files like 'autopackage/default.apspec'"
   777             fullPathName directory makeDirectory.
   778         ].
   779         (fullPathName exists
   780          and:[ fullPathName contents = fileContents ]) ifFalse:[
   781             fullPathName contents:fileContents.
   782         ].
   783     ].    
   784 !
   785 
   786 generateSourceFiles
   787     (self isLocalBuild not and:[ sourceCodeManager notNil ])  ifTrue:[
   788         "/ check out / generate files there
   789         self generateSourceFilesByCheckingOutUsing:sourceCodeManager
   790     ] ifFalse:[
   791         "/ local build
   792         "/ fileout the project
   793         self generateSourceFilesByFilingOut
   794     ]
   795 !
   796 
   797 generateSourceFilesByCheckingOutUsing:aSourceCodeManager
   798     "/ will no longer be needed/supported
   799 
   800     |repository stxRepository module directory|
   801 
   802     self breakPoint:#cg.
   803 
   804     "/ check out / generate files there
   805     repository := (aSourceCodeManager repositoryNameForModule:module) ifNil:[aSourceCodeManager repositoryName].
   806     stxRepository := aSourceCodeManager repositoryName.
   807 
   808     (buildDirectory construct:'stx') exists ifFalse:[
   809         (module ~= 'stx') ifTrue:[
   810             OperatingSystem
   811                 executeCommand:('cvs -d ',stxRepository,' co stx')
   812                 inputFrom:nil
   813                 outputTo:Transcript
   814                 errorTo:Transcript
   815                 inDirectory:buildDirectory
   816                 onError:[:status| self error:'cvs update stx failed'].
   817         ].
   818     ].
   819 
   820     ((buildDirectory construct:module) construct:'CVS') exists ifFalse:[
   821         OperatingSystem
   822             executeCommand:('cvs -d ',repository,' co -l ',directory)
   823             inputFrom:nil
   824             outputTo:Transcript
   825             errorTo:Transcript
   826             inDirectory:buildDirectory
   827             onError:[:status| self error:'cvs update failed'].
   828     ].
   829     OperatingSystem
   830         executeCommand:'cvs upd -d'
   831         inputFrom:nil
   832         outputTo:Transcript
   833         errorTo:Transcript
   834         inDirectory:(buildDirectory construct:module)
   835         onError:[:status| self error:'cvs update failed'].
   836 self halt.
   837 
   838     "Modified: / 29-12-2011 / 14:02:56 / cg"
   839 !
   840 
   841 generateSourceFilesByFilingOut
   842     "/ local build
   843     "/ fileout the project
   844 
   845     (package module ~= 'stx') ifTrue:[
   846         (buildDirectory / package module) makeDirectory.
   847     ].
   848 
   849     "/ file out the package(s) which are to be built
   850     ((Array with:package))
   851     do:[:eachPackageToFileout |
   852         |packageId packageModule packageDirectory packageTargetDir packageDef extSource|
   853 
   854         packageId := eachPackageToFileout asPackageId.
   855         packageModule := packageId module.
   856         packageDirectory := packageId directory.
   857         packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
   858 
   859         packageDef := packageId projectDefinitionClass.
   860         (packageDef compiled_classNames_common ,
   861         packageDef compiled_classNamesForPlatform) do:[:eachClassName |
   862             |cls fileName newSource|
   863 
   864             cls := Smalltalk classNamed:eachClassName.
   865             (cls notNil and:[cls isLoaded]) ifFalse:[
   866                 self error:'missing class: ',eachClassName mayProceed:true
   867             ].
   868             fileName := (Smalltalk fileNameForClass:cls),'.st'.
   869             fileName := packageTargetDir asFilename construct:fileName.
   870             fileName exists ifTrue:[
   871                 newSource := String streamContents:[:s | cls fileOutOn:s withTimeStamp:false].
   872                 newSource = fileName contentsAsString ifFalse:[
   873                     fileName contents:newSource
   874                 ].
   875             ] ifFalse:[
   876                 cls fileOutIn:packageTargetDir withTimeStamp:false
   877             ].
   878         ].
   879 
   880         packageDef hasExtensionMethods ifTrue:[
   881             extSource := 
   882                 String streamContents:[:s |
   883                     s nextPutAll:('"{ Package: ''%1'' }" !!\\' bindWith:packageDef package) withCRs.
   884 
   885                     packageDef extensionMethods do:[:eachMethod |
   886                         eachMethod mclass fileOutMethod:eachMethod on:s
   887                     ].
   888                 ].
   889             extSource isWideString ifTrue:[
   890                 extSource := ( '"{ Encoding: utf8 }"' , Character cr asString, Character cr asString, extSource).
   891                 extSource := extSource utf8Encoded.
   892             ].
   893             (packageTargetDir asFilename construct:'extensions.st') contents:extSource
   894         ].
   895 
   896 "/        (Smalltalk allClassesInPackage:eachPackageToFileout) do:[:cls |
   897 "/            cls isPrivate ifFalse:[
   898 "/                cls isLoaded ifFalse:[
   899 "/                    self halt.
   900 "/                    cls autoload.
   901 "/                ].
   902 "/                cls fileOutIn:packageTargetDir
   903 "/            ]
   904 "/        ].
   905         self generateBuildSupportFilesByFilingOutIn:packageTargetDir forDefinitionClass:projectDefinitionClass.
   906     ].
   907     self makeQuick ifFalse:[
   908         "/ generate header files and build support files
   909         "/ in prerequisite packages...
   910         (projectDefinitionClass allPreRequisites)
   911         do:[:eachPackageToFileout |
   912             |packageId packageDef packageModule packageDirectory packageTargetDir|
   913 
   914             packageId := eachPackageToFileout asPackageId.
   915             packageModule := packageId module.
   916             packageDirectory := packageId directory.
   917             packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
   918 
   919             packageDef := packageId projectDefinitionClass.
   920             (packageDef compiled_classNames_common ,
   921             packageDef compiled_classNamesForPlatform) do:[:eachClassName |
   922                 |cls|
   923 
   924                 cls := Smalltalk classNamed:eachClassName.
   925                 "/ self assert:cls isLoaded.
   926                 cls isNil ifTrue:[
   927                     stdErr nextPutLine:('Missing class: ',eachClassName, ' (not present in system. Warning only:subclasses of it will not be compiled)').
   928                 ] ifFalse:[
   929                     cls isLoaded ifTrue:[    
   930                         self createHeaderFileFor:cls in:packageTargetDir
   931                     ]
   932                 ].
   933             ].
   934             self copyResourcesForPackage:eachPackageToFileout.
   935             self generateBuildSupportFilesByFilingOutIn:packageTargetDir forDefinitionClass:packageDef.
   936             (packageTargetDir / '.NOSOURCE') contents:'existence of this file suppresses compilation of st files'.
   937         ].
   938     ].
   939 
   940 "/    stx_libbasic2 preRequisitesForBuilding#(#'stx:libbasic')
   941 !
   942 
   943 makeCommandOfCompiler:usedCompiler
   944     usedCompiler notNil ifTrue:[
   945         usedCompiler = 'bcc' ifTrue:[ 
   946             ^ 'bmake'.
   947         ].
   948         usedCompiler = 'vc' ifTrue:[ 
   949             ^ 'vcmake'. "/ compilerFlag := '-DUSEVC' 
   950         ].
   951         usedCompiler = 'lcc' ifTrue:[ 
   952             ^ 'lccmake'. "/ compilerFlag := '-DUSELCC' 
   953         ].
   954         usedCompiler = 'tcc' ifTrue:[ 
   955             ^ 'tccmake'. "/ compilerFlag := '-DUSELCC' 
   956         ].
   957         usedCompiler = 'mingw' ifTrue:[ 
   958             ^ 'mingwmake'.  "/ compilerFlag := '-DUSEMINGW' 
   959         ].
   960         true "usedCompiler = 'gcc'" ifTrue:[ 
   961             ^ 'make'.       "/ compilerFlag := '-DUSEGCC' 
   962         ].
   963     ].
   964     self error:'unknown compiler specified'.
   965 
   966     "Created: / 03-09-2012 / 19:46:07 / cg"
   967     "Modified: / 06-06-2016 / 15:11:54 / cg"
   968 !
   969 
   970 makeWithOutputTo:stdOut errorTo:stdErr
   971     |module directory makeCommand forceArg makeTarget|
   972 
   973     module := package module.
   974     directory := package directory.
   975 
   976     "/ makeCommand := ParserFlags makeCommand.
   977     usedCompiler isNil ifTrue:[
   978         usedCompiler := ParserFlags usedCompiler.
   979         usedCompiler isNil ifTrue:[ self error:'no compiler defined (settings)'. ].
   980     ].
   981     makeCommand := self makeCommandOfCompiler:usedCompiler.
   982     self activityNotification:'Executing make... (',makeCommand,')'.
   983     forceArg := ''.
   984     
   985     "/ makeCommand := makeCommand, ' TOP=', mySTXTopDirectory pathName.
   986 
   987     OperatingSystem isUNIXlike ifTrue:[
   988         forceArg := ' FORCE='.
   989 
   990         "/ generate the makefile first
   991         self activityNotification:('sh %1/rules/stmkmf (in %2)' 
   992                     bindWith:mySTXTopDirectory pathName    
   993                     with:(buildDirectory / module / directory)).
   994         OperatingSystem
   995             executeCommand:('sh %1/rules/stmkmf' bindWith:mySTXTopDirectory pathName)
   996             inputFrom:nil
   997             outputTo:stdOut
   998             errorTo:stdErr
   999             inDirectory:(buildDirectory / module / directory)
  1000             onError:[:status | self error:'make failed'].
  1001     ].
  1002 
  1003     projectDefinitionClass isLibraryDefinition ifTrue:[
  1004         "/ generate the library
  1005         self activityNotification:(makeCommand,' classLibRule').
  1006         OperatingSystem
  1007             executeCommand:(makeCommand,' classLibRule',forceArg)
  1008             inputFrom:nil
  1009             outputTo:stdOut
  1010             errorTo:stdErr
  1011             inDirectory:(buildDirectory / module / directory)
  1012             onError:[:status | self error:'make failed'].
  1013     ] ifFalse:[
  1014         (self makeExeOnly) ifTrue:[
  1015             makeTarget := 'exe'
  1016         ] ifFalse:[
  1017             (self makeAppOnly) ifTrue:[
  1018                 makeTarget := 'app'
  1019             ] ifFalse:[
  1020                 makeTarget := 'ALL_NP'
  1021             ].
  1022             self activityNotification:(makeCommand,' ',makeTarget).
  1023             OperatingSystem
  1024                 "/ generate the executable
  1025                 executeCommand:(makeCommand,' ',makeTarget,forceArg)
  1026                 inputFrom:nil
  1027                 outputTo:stdOut
  1028                 errorTo:stdErr
  1029                 inDirectory:(buildDirectory / module / directory)
  1030                 onError:[:status | self error:'make failed'].
  1031         ]
  1032     ]
  1033 
  1034     "Modified: / 06-06-2016 / 15:17:00 / cg"
  1035 !
  1036 
  1037 objDirForUsedCompiler
  1038     ^ self objDirForUsedCompiler:usedCompiler
  1039 
  1040     "Created: / 20-08-2012 / 17:01:13 / cg"
  1041 !
  1042 
  1043 objDirForUsedCompiler:usedCompiler
  1044     usedCompiler = 'gcc' ifTrue:[^ 'obj'].      "/ unix case
  1045 
  1046     usedCompiler = 'bcc' ifTrue:[^ 'objbc'].
  1047     usedCompiler = 'vc' ifTrue:[^ 'objvc'].
  1048     usedCompiler = 'tcc' ifTrue:[^ 'objtcc'].
  1049     usedCompiler = 'lcc' ifTrue:[^ 'objlcc'].
  1050     usedCompiler = 'mingw' ifTrue:[^ 'objmingw'].
  1051     self halt:'please add compiler here'.
  1052     ^ 'objbc'
  1053 
  1054     "Created: / 03-09-2012 / 19:55:34 / cg"
  1055 !
  1056 
  1057 recursiveCopyDirectoryForBuild:subdir
  1058     |targetDir|
  1059 
  1060     targetDir := buildDirectory / 'stx' / subdir.
  1061     targetDir exists ifFalse:[
  1062         targetDir makeDirectory.
  1063     ].
  1064     (mySTXTopDirectory / subdir) directoryContentsAsFilenamesDo:[:eachFile |
  1065         eachFile recursiveCopyTo:(targetDir construct:eachFile baseName)
  1066     ].
  1067     self activityNotification:nil
  1068 !
  1069 
  1070 setupBuildDirectory
  1071     self activityNotification:('Building in %1' bindWith:buildDirectory pathName).
  1072 
  1073     buildDirectory exists ifFalse:[
  1074         buildDirectory recursiveMakeDirectory.
  1075     ].
  1076     (buildDirectory / 'stx') exists ifFalse:[
  1077         (buildDirectory / 'stx') makeDirectory.
  1078     ].
  1079 
  1080     self copyDirectoryForBuild:'include'.
  1081     self copyDirectoryForBuild:'rules'.
  1082 
  1083     OperatingSystem isUNIXlike ifTrue:[
  1084         self recursiveCopyDirectoryForBuild:'configurations'.
  1085     ]
  1086 !
  1087 
  1088 validateBuildDirectoryIsPresent
  1089 
  1090     ^ self.
  1091 
  1092 "/    [
  1093 "/        |default directoryIsOKForMe stc |
  1094 "/
  1095 "/        default := (buildDirectory ?
  1096 "/                          PreviousBuildDirectory)
  1097 "/                          ifNil:[ UserPreferences current buildDirectory].
  1098 "/
  1099 "/        buildDirectory := Dialog requestDirectoryName:'Temporary Work-ROOT for build:'
  1100 "/                                 default:default.
  1101 "/
  1102 "/        buildDirectory isEmptyOrNil ifTrue:[^ self].
  1103 "/        buildDirectory := buildDirectory asFilename.
  1104 "/        directoryIsOKForMe := true.
  1105 "/
  1106 "/        buildDirectory exists ifFalse:[
  1107 "/            Dialog warn:(self classResources string:'Work directory %1 does not exist.' with:buildDirectory).
  1108 "/            directoryIsOKForMe := false.
  1109 "/        ] ifTrue:[
  1110 "/            (buildDirectory construct:'stx') exists ifFalse:[
  1111 "/                Dialog warn:(self classResources stringWithCRs:'Work directory must contain an stx subDirectory,\which contains (at least) the stc and include subdirectories.').
  1112 "/                directoryIsOKForMe := false.
  1113 "/            ] ifTrue:[
  1114 "/                stc := (OperatingSystem isMSDOSlike) ifTrue:['stc.exe'] ifFalse:['stc'].
  1115 "/                (((buildDirectory construct:'stx')construct:'stc')construct:stc) exists ifFalse:[
  1116 "/                    Dialog warn:(self classResources stringWithCRs:'Work directory must contain an stc compiler in the stx/stc subDirectory.').
  1117 "/                    directoryIsOKForMe := false.
  1118 "/                ].
  1119 "/                ((buildDirectory construct:'stx')construct:'include') exists ifFalse:[
  1120 "/                    Dialog warn:(self classResources stringWithCRs:'Work directory must have had a make run before (for include files to exists).').
  1121 "/                    directoryIsOKForMe := false.
  1122 "/                ].
  1123 "/            ]
  1124 "/        ].
  1125 "/        directoryIsOKForMe
  1126 "/    ] whileFalse
  1127 ! !
  1128 
  1129 !ProjectBuilder class methodsFor:'documentation'!
  1130 
  1131 version
  1132     ^ '$Header$'
  1133 !
  1134 
  1135 version_CVS
  1136     ^ '$Header$'
  1137 ! !
  1138