ProjectBuilder.st
author Claus Gittinger <cg@exept.de>
Tue, 20 Oct 2009 23:53:26 +0200
changeset 2647 aedc794b630a
parent 2644 428bb83dd360
child 2672 a1cda5d8943d
permissions -rw-r--r--
*** empty log message ***
     1 "{ Package: 'stx:libtool2' }"
     2 
     3 "{ NameSpace: Tools }"
     4 
     5 Object subclass:#ProjectBuilder
     6 	instanceVariableNames:'package projectDefinitionClass sourceCodeManager buildDirectory
     7 		myWorkingDirectory mySTXTopDirectory myTopDirectory outputStream'
     8 	classVariableNames:'PreviousBuildDirectory'
     9 	poolDictionaries:''
    10 	category:'System-Support-Projects'
    11 !
    12 
    13 
    14 !ProjectBuilder class methodsFor:'accessing'!
    15 
    16 previousBuildDirectory
    17     ^ PreviousBuildDirectory
    18 !
    19 
    20 previousBuildDirectory:something
    21     PreviousBuildDirectory := something.
    22 ! !
    23 
    24 !ProjectBuilder class methodsFor:'examples'!
    25 
    26 example1
    27     Smalltalk loadPackage:'stx:projects/helloWorldApp' asAutoloaded:true.
    28 
    29     self new
    30         package:'stx:projects/helloWorldApp';
    31         build
    32 !
    33 
    34 example2
    35     |builder|
    36 
    37     Smalltalk loadPackage:'stx:clients/Demos/foxCalcApplication' asAutoloaded:true.
    38 
    39     builder := self new.
    40     builder package:'stx:clients/Demos/foxCalcApplication'.
    41     builder build.
    42 
    43     UserPreferences fileBrowserClass openOnDirectory:builder packageBuildDirectory.
    44 ! !
    45 
    46 !ProjectBuilder methodsFor:'accessing'!
    47 
    48 buildDirectory
    49     ^ buildDirectory
    50 !
    51 
    52 buildDirectory:something
    53     buildDirectory := something.
    54 !
    55 
    56 package:aPackageIDOrSymbol
    57     package := aPackageIDOrSymbol asPackageId.
    58 !
    59 
    60 packageBuildDirectory
    61     "the directoray, where the deployable binary is created (xxxSetup.exe)"
    62 
    63     ^ buildDirectory / (package asPackageId module) / (package asPackageId directory)
    64 !
    65 
    66 projectDefinitionClass:something
    67     projectDefinitionClass := something.
    68 ! !
    69 
    70 !ProjectBuilder methodsFor:'building'!
    71 
    72 build
    73     "/ intermediate - this will move into a commonly used utility class
    74     "/ (where all the project code support will be collected).
    75 
    76     |makeOutput|
    77 
    78     makeOutput := TextStream on:(Text new:10000).
    79     self buildWithColorizedOutputTo:makeOutput.
    80 
    81     TextView openWith:makeOutput contents.
    82 !
    83 
    84 buildWithColorizedOutputTo:makeOutput
    85     "/ intermediate - this will move into a commonly used utility class
    86     "/ (where all the project code support will be collected).
    87 
    88     |stdOut stdErr lock|
    89 
    90     lock := Semaphore forMutualExclusion.
    91 
    92     stdErr := ActorStream new
    93                     nextPutBlock:[:char |
    94                         lock critical:[
    95                             makeOutput emphasis:{#backgroundColor->Color red. #color->Color white.}.
    96                             makeOutput nextPut:char.
    97                             makeOutput emphasis:nil.
    98                         ]
    99                     ];
   100                     nextPutAllBlock:[:char |
   101                         lock critical:[
   102                             makeOutput emphasis:{#backgroundColor->Color red. #color->Color white.}.
   103                             makeOutput nextPutAll:char.
   104                             makeOutput emphasis:nil.
   105                         ]
   106                     ].
   107     stdOut := ActorStream new
   108                     nextPutBlock:[:char |
   109                         lock critical:[
   110                             makeOutput nextPut:char.
   111                         ]
   112                     ];
   113                     nextPutAllBlock:[:char |
   114                         lock critical:[
   115                             makeOutput nextPutAll:char.
   116                         ]
   117                     ].
   118 
   119     self buildWithOutputTo:stdOut errorTo:stdErr.
   120 !
   121 
   122 buildWithOutputTo:stdOut errorTo:stdErr
   123     "/ intermediate - this will move into a commonly used utility class
   124     "/ (where all the project code support will be collected).
   125 
   126     |module directory|
   127 
   128     projectDefinitionClass := ProjectDefinition definitionClassForPackage:package.
   129     projectDefinitionClass isNil ifTrue:[
   130         self error:('Missing ProjectDefinition class for "',package asString,'"')
   131     ].
   132 
   133     "/ ensure that everything is loaded...
   134     projectDefinitionClass loadAsAutoloaded:false.
   135     projectDefinitionClass loadExtensions.
   136     projectDefinitionClass loadAllClassesAsAutoloaded:false.
   137 
   138     module := package module.
   139     directory := package directory.
   140 
   141     buildDirectory isNil ifTrue:[
   142         buildDirectory := PreviousBuildDirectory ifNil:[ UserPreferences current buildDirectory ].
   143         buildDirectory isNil ifTrue:[
   144             buildDirectory := Filename tempDirectory construct:'stx_build'.
   145         ].
   146     ].
   147     buildDirectory := buildDirectory asFilename.
   148 
   149     "/ self validateBuildDirectoryIsPresent.
   150 
   151     PreviousBuildDirectory := buildDirectory.
   152 
   153     "/ UserPreferences current localBuild:true
   154     UserPreferences current localBuild ifFalse:[
   155         SourceCodeManager notNil ifTrue:[
   156             sourceCodeManager := SourceCodeManagerUtilities sourceCodeManagerFor:projectDefinitionClass.
   157         ]
   158     ].
   159     sourceCodeManager := nil.
   160 
   161     myTopDirectory := 
   162         Smalltalk packagePath 
   163             detect:[:aPath |
   164                 (aPath asFilename / 'stx' / 'include') exists
   165                 and: [ (aPath asFilename / 'stx' / 'rules') exists ]]
   166             ifNone:nil.       
   167     myTopDirectory isNil ifTrue:[
   168         self error:('Cannot figure out my top directory (where stx/include and stx/rules are)')
   169     ].
   170     myTopDirectory := myTopDirectory asFilename.
   171     mySTXTopDirectory := myTopDirectory / 'stx'.
   172 
   173     self setupBuildDirectory.
   174     self activityNotification:'Generating stc directory...'.
   175     self copySTCDirectoryForBuild.
   176     self activityNotification:'Generating source files...'.
   177     self generateSourceFiles.
   178     self activityNotification:'Generating dlls for linkage...'.
   179     self copyDLLsForLinkage.
   180     self activityNotification:'Generating support files for linkage...'.
   181     self copySupportFilesForLinkage.
   182     self copyStartupFilesFromSmalltalk.
   183 
   184     self activityNotification:'Executing make...'.
   185     self makeWithOutputTo:stdOut errorTo:stdErr.
   186 !
   187 
   188 copyDLLsForLinkage
   189     |targetBuildDir|
   190 
   191     targetBuildDir := buildDirectory / package module / package directory.
   192 
   193     (projectDefinitionClass allPreRequisites)
   194     do:[:eachPackageToFileout |
   195         |packageId packageDef packageModule packageDirectory packageTargetDir
   196          dllSource dllSourceDir libraryName dllRelativePath|
   197 
   198         packageId := eachPackageToFileout asPackageId.
   199         packageModule := packageId module.
   200         packageDirectory := packageId directory.
   201         packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
   202 
   203         packageDef := packageId projectDefinitionClass.
   204         libraryName := packageDef libraryName.
   205 
   206         "/ mhmh - take them from my tree or from the projects/smalltalk execution directory ??
   207         dllSourceDir := myTopDirectory / packageModule / packageDirectory.
   208         OperatingSystem isMSWINDOWSlike ifTrue:[
   209 "/            dllRelativePath := 'objvc','/',(libraryName,'.dll').
   210 "/            (dllSourceDir / dllRelativePath) exists 
   211             false ifFalse:[
   212                 dllRelativePath := 'objbc','/',(libraryName,'.dll').
   213             ]
   214         ] ifFalse:[
   215             dllRelativePath := libraryName,'.so'.
   216         ].
   217         ((packageTargetDir / dllRelativePath) exists
   218         and:[ (dllSourceDir / dllRelativePath) fileSize = (packageTargetDir / dllRelativePath) fileSize
   219         and:[ (dllSourceDir / dllRelativePath) modificationTime < (packageTargetDir / dllRelativePath) modificationTime
   220         "/ and:[ (dllSourceDir / dllRelativePath) sameContentsAs:(packageTargetDir / dllRelativePath) ]
   221         ]]) ifFalse:[
   222             (packageTargetDir / dllRelativePath) directory recursiveMakeDirectory.
   223             (dllSourceDir / dllRelativePath) copyTo:(packageTargetDir / dllRelativePath).    
   224         ]
   225     ].
   226 !
   227 
   228 copyDirectory:relativepath
   229     "/ need rules in stx
   230     ((Smalltalk projectDirectoryForPackage:'stx') asFilename construct:relativepath)
   231         recursiveCopyTo:(buildDirectory construct:'stx').
   232 !
   233 
   234 copyDirectoryForBuild:subdir
   235     |targetDir targetFile|
   236 
   237     targetDir := buildDirectory / 'stx' / subdir.
   238     targetDir exists ifFalse:[
   239         targetDir makeDirectory.
   240     ].
   241     (mySTXTopDirectory / subdir) directoryContentsAsFilenamesDo:[:eachFile |
   242         eachFile isDirectory ifFalse:[
   243             targetFile := targetDir / eachFile baseName.
   244             (targetFile exists not
   245             or:[ targetFile modificationTime < eachFile modificationTime ]) ifTrue:[
   246                 self activityNotification:'copying ',eachFile pathName,'...'.
   247                 eachFile copyTo:(targetDir construct:eachFile baseName)
   248             ]
   249         ].
   250     ].
   251     self activityNotification:nil
   252 !
   253 
   254 copyResourcesForPackage:aPackage
   255     |module directory|
   256 
   257     module := aPackage asPackageId module.
   258     directory := aPackage asPackageId directory.
   259 
   260     (myTopDirectory / module / directory / 'resources' ) exists ifTrue:[
   261         (myTopDirectory / module / directory / 'resources' )
   262             recursiveCopyTo:(buildDirectory / module / directory)
   263     ].
   264     (myTopDirectory / module / directory / 'styles' ) exists ifTrue:[
   265         (myTopDirectory / module / directory / 'styles' )
   266             recursiveCopyTo:(buildDirectory / module / directory)
   267     ].
   268 !
   269 
   270 copySTCDirectoryForBuild
   271     |targetDir stc files|
   272 
   273     targetDir := buildDirectory / 'stx' / 'stc'.
   274     targetDir exists ifFalse:[ targetDir makeDirectory ].
   275 
   276     stc := OperatingSystem isMSWINDOWSlike 
   277                 ifTrue:[ 'stc.exe' ]
   278                 ifFalse:[ 'stc' ].
   279 
   280     files := #( ) copyWith:stc.
   281 
   282     files do:[:eachFile |
   283         |sourceFile targetFile|
   284 
   285         sourceFile := mySTXTopDirectory / 'stc' / eachFile.
   286         targetFile := targetDir / eachFile.
   287         (targetFile exists not
   288         or:[ targetFile modificationTime < sourceFile modificationTime ]) ifTrue:[
   289             self activityNotification:'copying ',sourceFile pathName,'...'.
   290             sourceFile copyTo:targetFile
   291         ].
   292     ].
   293     self activityNotification:nil
   294 !
   295 
   296 copyStartupFilesFromSmalltalk
   297     (buildDirectory / 'stx' / 'projects/smalltalk' ) exists ifFalse:[
   298         (buildDirectory / 'stx' / 'projects/smalltalk' ) recursiveMakeDirectory.
   299     ].
   300 
   301     #( 'keyboard.rc' 'keyboardMacros.rc' 'display.rc' 'd_win32.rc'
   302        'host.rc' 'h_win32.rc'  
   303     ) do:[:fn |
   304         (myTopDirectory / 'stx' / 'projects/smalltalk' / fn)
   305             copyTo: (buildDirectory / 'stx' / 'projects/smalltalk' / fn)
   306     ]
   307 !
   308 
   309 copySupportFilesForLinkage
   310     |files|
   311 
   312     OperatingSystem isMSWINDOWSlike ifTrue:[
   313         files := #( 
   314                     'support/win32/borland/cs3245.dll' 
   315                     'support/win32/X11.dll'
   316                     'support/win32/Xext.dll'
   317                     'librun/librun.dll'
   318                     'libbc/librun.lib'
   319                     'libbc/cs32i.lib'
   320                     'librun/genDate.exe'
   321                     'librun/main.c'
   322                  ).
   323     ] ifFalse:[
   324         files := #(
   325                     'librun/genDate'
   326                     'librun/main.c'
   327                     'librun/librun.so'
   328                 )
   329     ].
   330 
   331     files do:[:dllRelativePath |
   332         ((buildDirectory / 'stx' / dllRelativePath) exists
   333         and:[ (mySTXTopDirectory / dllRelativePath) fileSize = (buildDirectory / 'stx' / dllRelativePath) fileSize
   334         and:[ (mySTXTopDirectory / dllRelativePath) modificationTime < (buildDirectory / 'stx' / dllRelativePath) modificationTime
   335         "/ and:[ (mySTXTopDirectory / dllRelativePath) sameContentsAs:(targetBuildDir / dllRelativePath) ]
   336         ]]) ifFalse:[
   337             (buildDirectory / 'stx' / dllRelativePath) directory recursiveMakeDirectory.
   338             (mySTXTopDirectory / dllRelativePath) copyTo:(buildDirectory / 'stx' / dllRelativePath).    
   339         ]
   340     ].
   341 !
   342 
   343 createHeaderFileFor:aClass in:packageTargetDir
   344     |instVarList classInstVarList classVarList bindings superclassFilename
   345      template file newContents oldContents|
   346 
   347     instVarList := StringCollection new.
   348     aClass instVarNames do:[:v |
   349         instVarList add:('OBJ %1;' bindWith:v)
   350     ].
   351     classInstVarList := StringCollection new.
   352     aClass class instVarNames do:[:v |
   353 (v includes:$_) ifTrue:[self halt].
   354         classInstVarList add:('OBJ %1;' bindWith:v)
   355     ].
   356     classVarList := StringCollection new.
   357     aClass classVarNames do:[:v |
   358         classVarList add:('extern OBJ %1_%2;' bindWith:aClass name with:v)
   359     ].
   360 
   361     bindings := Dictionary new.
   362     bindings at:'ClassName' put:aClass name. 
   363     aClass superclass isNil ifTrue:[
   364         bindings at:'SuperclassName' put:'-'. 
   365         bindings at:'SuperclassFileInclude' put:nil.
   366     ] ifFalse:[
   367         bindings at:'SuperclassName' put:aClass superclass name. 
   368         bindings at:'SuperclassFileName' put:(superclassFilename := Smalltalk fileNameForClass:aClass superclass).
   369         bindings at:'SuperclassFileInclude' put:('#include "%1.STH"' bindWith:superclassFilename).
   370     ].
   371     bindings at:'InstVarList' put:instVarList asString. 
   372     bindings at:'ClassVarList' put:classVarList asString. 
   373     bindings at:'ClassInstVarList' put:classInstVarList asString. 
   374 
   375     template := 
   376 '/* This file was generated by ProjectBuilder. */
   377 /* !!!!!!!! Do not change by hand !!!!!!!! */
   378 
   379 /* Class: %(ClassName) */
   380 /* Superclass: %(SuperclassName) */
   381 
   382 %(SuperclassFileInclude)
   383 
   384 /* INDIRECTGLOBALS */
   385 #ifdef _HEADER_INST_
   386 %(InstVarList)
   387 #endif /* _HEADER_INST_ */
   388 
   389 #ifdef _HEADER_CLASS_
   390 %(ClassVarList)
   391 #endif /* _HEADER_CLASS_ */
   392 
   393 #ifdef _HEADER_CLASSINST_
   394 %(ClassInstVarList)
   395 #endif /* _HEADER_CLASSINST_ */
   396 '.
   397     newContents := template bindWithArguments:bindings.
   398     file := packageTargetDir asFilename / ((Smalltalk fileNameForClass:aClass),'.STH').
   399     (file exists not
   400     or:[ (oldContents := file contents) ~= newContents ]) ifTrue:[
   401         file contents: newContents.
   402     ].
   403 !
   404 
   405 generateSourceFiles
   406     sourceCodeManager notNil ifTrue:[
   407         "/ check out / generate files there
   408         self generateSourceFilesByCheckingOutUsing:sourceCodeManager
   409     ] ifFalse:[
   410         "/ local build
   411         "/ fileout the project
   412         self generateSourceFilesByFilingOut
   413     ]
   414 !
   415 
   416 generateSourceFilesByCheckingOutUsing:aSourceCodeManager
   417     "/ will no longer be needed/supported
   418 
   419     |repository stxRepository module directory|
   420 
   421 self halt.
   422     "/ check out / generate files there
   423     repository := (aSourceCodeManager repositoryNameForModule:module) ifNil:[aSourceCodeManager repositoryName].
   424     stxRepository := aSourceCodeManager repositoryName.
   425 
   426     (buildDirectory construct:'stx') exists ifFalse:[
   427         (module ~= 'stx') ifTrue:[
   428             OperatingSystem
   429                 executeCommand:('cvs -d ',stxRepository,' co stx')
   430                 inputFrom:nil
   431                 outputTo:Transcript
   432                 errorTo:Transcript
   433                 inDirectory:buildDirectory
   434                 onError:[:status| self error:'cvs update stx failed'].
   435         ].
   436     ].
   437 
   438     ((buildDirectory construct:module) construct:'CVS') exists ifFalse:[
   439         OperatingSystem
   440             executeCommand:('cvs -d ',repository,' co -l ',directory)
   441             inputFrom:nil
   442             outputTo:Transcript
   443             errorTo:Transcript
   444             inDirectory:buildDirectory
   445             onError:[:status| self error:'cvs update failed'].
   446     ].
   447     OperatingSystem
   448         executeCommand:'cvs upd -d'
   449         inputFrom:nil
   450         outputTo:Transcript
   451         errorTo:Transcript
   452         inDirectory:(buildDirectory construct:module)
   453         onError:[:status| self error:'cvs update failed'].
   454 self halt.
   455 !
   456 
   457 generateSourceFilesByFilingOut
   458     "/ local build
   459     "/ fileout the project
   460 
   461     (package module ~= 'stx') ifTrue:[
   462         (buildDirectory / package module) makeDirectory.
   463     ].
   464 
   465     "/ file out the package(s) which are to be built
   466     ((Array with:package))
   467     do:[:eachPackageToFileout |
   468         |packageId packageModule packageDirectory packageTargetDir packageDef|
   469 
   470         packageId := eachPackageToFileout asPackageId.
   471         packageModule := packageId module.
   472         packageDirectory := packageId directory.
   473         packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
   474 
   475         packageDef := packageId projectDefinitionClass.
   476         (packageDef compiled_classNames_common ,
   477         packageDef compiled_classNamesForPlatform) do:[:eachClassName |
   478             |cls fileName newSource|
   479 
   480             cls := Smalltalk classNamed:eachClassName.
   481             self assert:cls isLoaded.
   482             fileName := (Smalltalk fileNameForClass:cls),'.st'.
   483             fileName := packageTargetDir asFilename construct:fileName.
   484             fileName exists ifTrue:[
   485                 newSource := String streamContents:[:s | cls fileOutOn:s withTimeStamp:false].
   486                 newSource = fileName contentsAsString ifFalse:[
   487                     fileName contents:newSource
   488                 ].
   489             ] ifFalse:[
   490                 cls fileOutIn:packageTargetDir withTimeStamp:false
   491             ].
   492         ].
   493 
   494 "/        (Smalltalk allClassesInPackage:eachPackageToFileout) do:[:cls |
   495 "/            cls isPrivate ifFalse:[
   496 "/                cls isLoaded ifFalse:[
   497 "/                    self halt.
   498 "/                    cls autoload.
   499 "/                ].
   500 "/                cls fileOutIn:packageTargetDir
   501 "/            ]
   502 "/        ].
   503 
   504         projectDefinitionClass forEachFileNameAndGeneratedContentsDo:[:fileName :fileContents |
   505             ((packageTargetDir / fileName) exists
   506             and:[ (packageTargetDir / fileName) contents = fileContents ]) ifFalse:[
   507                 (packageTargetDir / fileName) contents:fileContents.
   508             ].
   509         ].    
   510     ].
   511 
   512     "/ generate header files in prerequisite packages...
   513     (projectDefinitionClass allPreRequisites)
   514     do:[:eachPackageToFileout |
   515         |packageId packageDef packageModule packageDirectory packageTargetDir|
   516 
   517         packageId := eachPackageToFileout asPackageId.
   518         packageModule := packageId module.
   519         packageDirectory := packageId directory.
   520         packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
   521 
   522         packageDef := packageId projectDefinitionClass.
   523         (packageDef compiled_classNames_common ,
   524         packageDef compiled_classNamesForPlatform) do:[:eachClassName |
   525             |cls|
   526 
   527             cls := Smalltalk classNamed:eachClassName.
   528             "/ self assert:cls isLoaded.
   529             cls isLoaded ifTrue:[    
   530                 self createHeaderFileFor:cls in:packageTargetDir
   531             ].
   532         ].
   533         self copyResourcesForPackage:eachPackageToFileout.
   534     ].
   535 
   536 "/    stx_libbasic2 preRequisitesForBuilding#(#'stx:libbasic')
   537 !
   538 
   539 makeWithOutputTo:stdOut errorTo:stdErr
   540     |module directory|
   541 
   542     module := package module.
   543     directory := package directory.
   544 
   545     projectDefinitionClass isLibraryDefinition ifTrue:[
   546         OperatingSystem
   547             executeCommand:(ParserFlags makeCommand,' classLibRule')
   548             inputFrom:nil
   549             outputTo:stdOut
   550             errorTo:stdErr
   551             inDirectory:(buildDirectory / module / directory)
   552             onError:[:status| self error:'make failed'].
   553     ] ifFalse:[
   554         OperatingSystem
   555             executeCommand:(ParserFlags makeCommand,' exe')
   556             inputFrom:nil
   557             outputTo:stdOut
   558             errorTo:stdErr
   559             inDirectory:(buildDirectory / module / directory)
   560             onError:[:status| self error:'make failed'].
   561 
   562         OperatingSystem
   563             executeCommand:(ParserFlags makeCommand,' setup')
   564             inputFrom:nil
   565             outputTo:stdOut
   566             errorTo:stdErr
   567             inDirectory:(buildDirectory / module / directory)
   568             onError:[:status| self error:'make failed'].
   569     ]
   570 !
   571 
   572 setupBuildDirectory
   573     buildDirectory exists ifFalse:[
   574         buildDirectory recursiveMakeDirectory.
   575     ].
   576     (buildDirectory / 'stx') exists ifFalse:[
   577         (buildDirectory / 'stx') makeDirectory.
   578     ].
   579 
   580     self copyDirectoryForBuild:'include'.
   581     self copyDirectoryForBuild:'rules'.
   582 !
   583 
   584 validateBuildDirectoryIsPresent
   585 
   586     ^ self.
   587 
   588 "/    [
   589 "/        |default directoryIsOKForMe stc |
   590 "/
   591 "/        default := (buildDirectory ?
   592 "/                          PreviousBuildDirectory)
   593 "/                          ifNil:[ UserPreferences current buildDirectory].
   594 "/
   595 "/        buildDirectory := Dialog requestDirectoryName:'Temporary Work-ROOT for build:'
   596 "/                                 default:default.
   597 "/
   598 "/        buildDirectory isEmptyOrNil ifTrue:[^ self].
   599 "/        buildDirectory := buildDirectory asFilename.
   600 "/        directoryIsOKForMe := true.
   601 "/
   602 "/        buildDirectory exists ifFalse:[
   603 "/            Dialog warn:(self classResources string:'Work directory %1 does not exist.' with:buildDirectory).
   604 "/            directoryIsOKForMe := false.
   605 "/        ] ifTrue:[
   606 "/            (buildDirectory construct:'stx') exists ifFalse:[
   607 "/                Dialog warn:(self classResources stringWithCRs:'Work directory must contain an stx subDirectory,\which contains (at least) the stc and include subdirectories.').
   608 "/                directoryIsOKForMe := false.
   609 "/            ] ifTrue:[
   610 "/                stc := (OperatingSystem isMSDOSlike) ifTrue:['stc.exe'] ifFalse:['stc'].
   611 "/                (((buildDirectory construct:'stx')construct:'stc')construct:stc) exists ifFalse:[
   612 "/                    Dialog warn:(self classResources stringWithCRs:'Work directory must contain an stc compiler in the stx/stc subDirectory.').
   613 "/                    directoryIsOKForMe := false.
   614 "/                ].
   615 "/                ((buildDirectory construct:'stx')construct:'include') exists ifFalse:[
   616 "/                    Dialog warn:(self classResources stringWithCRs:'Work directory must have had a make run before (for include files to exists).').
   617 "/                    directoryIsOKForMe := false.
   618 "/                ].
   619 "/            ]
   620 "/        ].
   621 "/        directoryIsOKForMe
   622 "/    ] whileFalse
   623 ! !
   624 
   625 !ProjectBuilder class methodsFor:'documentation'!
   626 
   627 version_CVS
   628     ^ '$Header$'
   629 ! !