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