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