ProjectBuilder.st
author Patrik Svestka <patrik.svestka@gmail.com>
Wed, 14 Nov 2018 12:07:51 +0100
branchjv
changeset 3630 5e718e0a754e
parent 3343 ad0041b8f3d2
child 3481 f7cdc2137f58
permissions -rw-r--r--
Issue #239: Fix all Smalltak/X source files to be in unicode (UTF8 without BOM) and prefixed by "{ Encoding: utf8 }" when any unicode character is present

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