ProjectBuilder.st
changeset 2596 876679f78999
child 2598 2bb47a698d59
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ProjectBuilder.st	Fri Oct 09 15:09:48 2009 +0200
@@ -0,0 +1,288 @@
+"{ Package: 'stx:libtool2' }"
+
+Object subclass:#ProjectBuilder
+	instanceVariableNames:'package projectDefinitionClass sourceCodeManager buildDirectory
+		myWorkingDirectory mySTXTopDirectory'
+	classVariableNames:'PreviousBuildDirectory'
+	poolDictionaries:''
+	category:'System-Support-Projects'
+!
+
+
+!ProjectBuilder class methodsFor:'examples'!
+
+example1
+    Smalltalk loadPackage:'stx:projects/helloWorldApp' asAutoloaded:true.
+
+    self new
+        package:'stx:projects/helloWorldApp';
+        build
+! !
+
+!ProjectBuilder methodsFor:'accessing'!
+
+package:aPackageIDOrSymbol
+    package := aPackageIDOrSymbol asPackageId.
+!
+
+projectDefinitionClass:something
+    projectDefinitionClass := something.
+! !
+
+!ProjectBuilder methodsFor:'building'!
+
+build
+    "/ intermediate - this will move into a commonly used utility class
+    "/ (where all the project code support will be collected).
+
+    |module directory|
+
+    projectDefinitionClass := ProjectDefinition definitionClassForPackage:package.
+    projectDefinitionClass isNil ifTrue:[
+        self error:('Missing ProjectDefinition class for "',package asString,'"')
+    ].
+
+    "/ ensure that everything is loaded...
+    projectDefinitionClass loadAsAutoloaded:false.
+    projectDefinitionClass loadExtensions.
+    projectDefinitionClass loadAllClassesAsAutoloaded:false.
+
+self halt.
+    module := package module.
+    directory := package directory.
+
+    buildDirectory := PreviousBuildDirectory ifNil:[ UserPreferences current buildDirectory ].
+    buildDirectory isNil ifTrue:[
+        buildDirectory := Filename tempDirectory construct:'stx_build'.
+    ].
+    buildDirectory := buildDirectory asFilename.
+
+    "/ self validateBuildDirectoryIsPresent.
+
+    PreviousBuildDirectory := buildDirectory.
+
+    "/ UserPreferences current localBuild:true
+    UserPreferences current localBuild ifFalse:[
+        SourceCodeManager notNil ifTrue:[
+            sourceCodeManager := SourceCodeManagerUtilities sourceCodeManagerFor:projectDefinitionClass.
+        ]
+    ].
+    sourceCodeManager := nil.
+
+    mySTXTopDirectory := 
+        Smalltalk packagePath 
+            detect:[:aPath |
+                (aPath asFilename / 'stx' / 'include') exists
+                and: [ (aPath asFilename / 'stx' / 'rules') exists ]]
+            ifNone:nil.       
+    mySTXTopDirectory isNil ifTrue:[
+        self error:('Cannot figure out my top directory (where include and rules are)')
+    ].
+
+    self setupBuildDirectory.
+    self generateSourceFiles.
+
+    OperatingSystem
+        executeCommand:(ParserFlags makeCommand)
+        inputFrom:nil
+        outputTo:Transcript
+        errorTo:Transcript
+        inDirectory:((buildDirectory construct:module) construct:directory)
+        onError:[:status| self error:'make failed'].
+
+    "Created: / 09-08-2006 / 18:37:19 / fm"
+    "Modified: / 09-08-2006 / 19:55:50 / fm"
+    "Modified: / 22-09-2006 / 17:37:11 / cg"
+!
+
+copyDirectory:relativepath
+    "/ need rules in stx
+    ((Smalltalk projectDirectoryForPackage:'stx') asFilename construct:relativepath)
+        recursiveCopyTo:(buildDirectory construct:'stx').
+!
+
+copyDirectoryForBuild:subdir
+    |targetDir|
+
+    targetDir := buildDirectory / 'stx' / subdir.
+    targetDir exists ifFalse:[
+        targetDir makeDirectory.
+        (mySTXTopDirectory / subdir) directoryContentsAsFilenamesDo:[:eachFile |
+            eachFile isDirectory ifFalse:[
+                eachFile copyTo:(targetDir construct:eachFile baseName)
+            ]
+        ].
+    ].
+!
+
+generateSourceFiles
+    sourceCodeManager notNil ifTrue:[
+        "/ check out / generate files there
+        self generateSourceFilesByCheckingOutUsing:sourceCodeManager
+    ] ifFalse:[
+        "/ local build
+        "/ fileout the project
+        self generateSourceFilesByFilingOut
+    ]
+!
+
+generateSourceFilesByCheckingOutUsing:aSourceCodeManager
+    "/ will no longer be needed/supported
+
+    |repository stxRepository module directory|
+
+self halt.
+    "/ check out / generate files there
+    repository := (aSourceCodeManager repositoryNameForModule:module) ifNil:[aSourceCodeManager repositoryName].
+    stxRepository := aSourceCodeManager repositoryName.
+
+    (buildDirectory construct:'stx') exists ifFalse:[
+        (module ~= 'stx') ifTrue:[
+            OperatingSystem
+                executeCommand:('cvs -d ',stxRepository,' co stx')
+                inputFrom:nil
+                outputTo:Transcript
+                errorTo:Transcript
+                inDirectory:buildDirectory
+                onError:[:status| self error:'cvs update stx failed'].
+        ].
+    ].
+
+    ((buildDirectory construct:module) construct:'CVS') exists ifFalse:[
+        OperatingSystem
+            executeCommand:('cvs -d ',repository,' co -l ',directory)
+            inputFrom:nil
+            outputTo:Transcript
+            errorTo:Transcript
+            inDirectory:buildDirectory
+            onError:[:status| self error:'cvs update failed'].
+    ].
+    OperatingSystem
+        executeCommand:'cvs upd -d'
+        inputFrom:nil
+        outputTo:Transcript
+        errorTo:Transcript
+        inDirectory:(buildDirectory construct:module)
+        onError:[:status| self error:'cvs update failed'].
+self halt.
+!
+
+generateSourceFilesByFilingOut
+    |targetDir prerequisitePackages|
+
+    "/ local build
+    "/ fileout the project
+
+    (package module ~= 'stx') ifTrue:[
+        (buildDirectory / package module) makeDirectory.
+    ].
+
+    "/ file out the package(s)
+
+    ((Array with:package) , (projectDefinitionClass allPreRequisites))
+    do:[:eachPackageToFileout |
+        |packageModule packageDirectory packageTargetDir|
+
+        packageModule := eachPackageToFileout asPackageId module.
+        packageDirectory := eachPackageToFileout asPackageId directory.
+        packageTargetDir := (buildDirectory / packageModule / packageDirectory) recursiveMakeDirectory.
+
+        (Smalltalk allClassesInPackage:eachPackageToFileout) do:[:cls |
+            cls isPrivate ifFalse:[
+                cls isLoaded ifFalse:[
+                    self halt.
+                    cls autoload.
+                ].
+                cls fileOutIn:packageTargetDir
+            ]
+        ].
+    ].
+
+"/    "/ copy h-files preRequisite packages
+"/    prerequisitePackages := projectDefinitionClass preRequisitesForBuilding.
+"/    prerequisitePackages do:[:eachPackage |
+"/        |relativeDir sourceDir|
+"/
+"/        relativeDir := eachPackage asPackageId pathRelativeToTopDirectory.
+"/        sourceDir := Smalltalk packageDirectoryForPackageId:eachPackage.
+"/        targetDir := buildDirectory construct:relativeDir.
+"/        targetDir recursiveMakeDirectory.
+"/        sourceDir directoryContentsAsFilenamesDo:[:eachSourceFilename |
+"/            ((eachSourceFilename suffix asLowercase = 'h')
+"/            or:[ eachSourceFilename suffix asLowercase = 'sth' ]) ifTrue:[
+"/                eachSourceFilename copyTo:targetDir.    
+"/            ].
+"/        ].
+"/    ].
+
+"/    stx_libbasic2 preRequisitesForBuilding#(#'stx:libbasic')
+"/    "/ generate support files there
+"/    targetDir := ((buildDirectory construct:module) construct:directory) recursiveMakeDirectory.
+"/    #('bmake.bat' 'Make.spec' 'Make.proto' 'libInit.cc' 'abbrev.stc'
+"/      'bc.mak'
+"/    ) do:[:f |
+"/        |contents|                          
+"/
+"/        contents := projectDefinitionClass generateFile:f.
+"/        (targetDir construct:f) contents:contents.
+"/    ].    
+!
+
+setupBuildDirectory
+    buildDirectory exists ifFalse:[
+        buildDirectory recursiveMakeDirectory.
+    ].
+    (buildDirectory / 'stx') exists ifFalse:[
+        (buildDirectory / 'stx') makeDirectory.
+    ].
+
+    self copyDirectoryForBuild:'include'.
+    self copyDirectoryForBuild:'rules'.
+!
+
+validateBuildDirectoryIsPresent
+
+    ^ self.
+
+"/    [
+"/        |default directoryIsOKForMe stc |
+"/
+"/        default := (buildDirectory ?
+"/                          PreviousBuildDirectory)
+"/                          ifNil:[ UserPreferences current buildDirectory].
+"/
+"/        buildDirectory := Dialog requestDirectoryName:'Temporary Work-ROOT for build:'
+"/                                 default:default.
+"/
+"/        buildDirectory isEmptyOrNil ifTrue:[^ self].
+"/        buildDirectory := buildDirectory asFilename.
+"/        directoryIsOKForMe := true.
+"/
+"/        buildDirectory exists ifFalse:[
+"/            Dialog warn:(self classResources string:'Work directory %1 does not exist.' with:buildDirectory).
+"/            directoryIsOKForMe := false.
+"/        ] ifTrue:[
+"/            (buildDirectory construct:'stx') exists ifFalse:[
+"/                Dialog warn:(self classResources stringWithCRs:'Work directory must contain an stx subDirectory,\which contains (at least) the stc and include subdirectories.').
+"/                directoryIsOKForMe := false.
+"/            ] ifTrue:[
+"/                stc := (OperatingSystem isMSDOSlike) ifTrue:['stc.exe'] ifFalse:['stc'].
+"/                (((buildDirectory construct:'stx')construct:'stc')construct:stc) exists ifFalse:[
+"/                    Dialog warn:(self classResources stringWithCRs:'Work directory must contain an stc compiler in the stx/stc subDirectory.').
+"/                    directoryIsOKForMe := false.
+"/                ].
+"/                ((buildDirectory construct:'stx')construct:'include') exists ifFalse:[
+"/                    Dialog warn:(self classResources stringWithCRs:'Work directory must have had a make run before (for include files to exists).').
+"/                    directoryIsOKForMe := false.
+"/                ].
+"/            ]
+"/        ].
+"/        directoryIsOKForMe
+"/    ] whileFalse
+! !
+
+!ProjectBuilder class methodsFor:'documentation'!
+
+version_CVS
+    ^ '$Header$'
+! !