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