--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ApplicationBuilder.st Tue Mar 31 20:22:48 1998 +0200
@@ -0,0 +1,1273 @@
+ToolApplicationModel subclass:#ApplicationBuilder
+ instanceVariableNames:'task shellView'
+ classVariableNames:'Aspects'
+ poolDictionaries:''
+ category:'Interface-Smalltalk'
+!
+
+!ApplicationBuilder class methodsFor:'documentation'!
+
+documentation
+"
+ The Application Builder of ST/X allows you to build ST/X-applications by following steps:
+
+ 0. Clobber the target directory of the application
+ 1. Generation of the h-file with symbols
+ 2. Generation of the c-file with modules
+ 3. Compilation of the modules init file
+ 4. Compilation of the startup C-file
+ 5. Defining of the symbolic links to the libraries
+ 6. Linking of the libraries to the application
+ 7. Defining of the symbolic links to the resources
+
+ [instance variables:]
+ task <Process> task of the running build
+ shellView <ShellView> shell view for outputing the build results
+
+ [class variables:]
+ Aspects <IdentityDictionary> aspects of the settings
+
+ [start with:]
+ ApplicationBuilder open
+
+ [see also:]
+ LibraryBuilder
+
+ [author:]
+ Thomas Zwick, eXept Software AG
+"
+! !
+
+!ApplicationBuilder class methodsFor:'help specs'!
+
+helpSpec
+ "This resource specification was automatically generated
+ by the UIHelpTool of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIHelpTool may not be able to read the specification."
+
+ "
+ UIHelpTool openOnClass:ApplicationBuilder
+ "
+
+ <resource: #help>
+
+ ^super helpSpec addPairsFrom:#(
+
+#applicationLinkDefines
+'Opens a dialog to define the link defines for the application.'
+
+#applicationName
+'Name of the application.'
+
+#build
+'Starts the process of building the application.'
+
+#buildDate
+'Build date of the application.'
+
+#configuration
+'Configuration information of the application.'
+
+#libraryDirectory
+'Directory of the ST/X libraries.'
+
+#start
+'Start the build application.'
+
+#startupCFile
+'Startup C-file of ST/X for the application.'
+
+#startupFile
+'Startup C-file of ST/X for the application.'
+
+#startupMessage
+'Startup message consisting of the class name and the selector name.'
+
+#startupModule
+'Startup module of ST/X for the application.'
+
+#stop
+'Stops the process of application building.'
+
+#stxLibraries
+'List of the ST/X library names.'
+
+#symlinkBitmaps
+'Create symbolic links to the bitmaps of ST/X.'
+
+#symlinkRCFiles
+'Create symbolic links to the RC-files of ST/X.'
+
+#symlinkResources
+'Create symbolic links to the resources of ST/X.'
+
+#symlinkSources
+'Create symbolic links to the sources of ST/X.'
+
+#systemLibaries
+'Libraries of the operating system needed by the application.'
+
+#targetDirectory
+'Target directory of the application.'
+
+#topDirectory
+'Top directory of ST/X.'
+
+#userLibraries
+'Libraries of the user wanted to add to the application.'
+
+)
+! !
+
+!ApplicationBuilder class methodsFor:'interface specs'!
+
+windowSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:ApplicationBuilder andSelector:#windowSpec
+ ApplicationBuilder new openInterface:#windowSpec
+ ApplicationBuilder open
+ "
+
+ <resource: #canvas>
+
+ ^
+
+ #(#FullSpec
+ #window:
+ #(#WindowSpec
+ #name: 'Application Builder'
+ #layout: #(#LayoutFrame 37 0 199 0 536 0 658 0)
+ #label: 'Application Builder'
+ #min: #(#Point 420 220)
+ #max: #(#Point 1152 900)
+ #bounds: #(#Rectangle 37 199 537 659)
+ #menu: #menu
+ #usePreferredExtent: false
+ )
+ #component:
+ #(#SpecCollection
+ #collection:
+ #(
+ #(#ViewSpec
+ #name: 'Box1'
+ #layout: #(#LayoutFrame 0 0.0 0 0 0 1.0 288 0)
+ #component:
+ #(#SpecCollection
+ #collection:
+ #(
+ #(#ViewSpec
+ #name: 'Box2'
+ #layout: #(#LayoutFrame 0 0.0 0 0.0 -148 1.0 2 1.0)
+ #component:
+ #(#SpecCollection
+ #collection:
+ #(
+ #(#LabelSpec
+ #name: 'applicationNameLabel'
+ #layout: #(#AlignmentOrigin 147 0 15 0 1 0.5)
+ #label: 'Application Name:'
+ #adjust: #right
+ )
+ #(#InputFieldSpec
+ #name: 'applicationNameField'
+ #layout: #(#LayoutFrame 150 0 4 0 0 1 26 0)
+ #activeHelpKey: #applicationName
+ #model: #applicationName
+ )
+ #(#LabelSpec
+ #name: 'startupMessageLabel'
+ #layout: #(#AlignmentOrigin 147 0 39 0 1 0.5)
+ #label: 'Startup Message:'
+ #adjust: #right
+ )
+ #(#InputFieldSpec
+ #name: 'startupMessageField'
+ #layout: #(#LayoutFrame 150 0 28 0 0 1.0 50 0)
+ #activeHelpKey: #startupMessage
+ #model: #startupMessage
+ )
+ #(#LabelSpec
+ #name: 'buildDateLabel'
+ #layout: #(#AlignmentOrigin 147 0 63 0 1 0.5)
+ #label: 'Build Date:'
+ #adjust: #right
+ )
+ #(#InputFieldSpec
+ #name: 'buildDateField'
+ #layout: #(#LayoutFrame 150 0 52 0 0 1.0 74 0)
+ #activeHelpKey: #buildDate
+ #model: #buildDate
+ )
+ #(#LabelSpec
+ #name: 'configurationLabel'
+ #layout: #(#AlignmentOrigin 147 0 87 0 1 0.5)
+ #label: 'Configuration:'
+ #adjust: #right
+ )
+ #(#InputFieldSpec
+ #name: 'configurationField'
+ #layout: #(#LayoutFrame 150 0 76 0 0 1.0 98 0)
+ #activeHelpKey: #configuration
+ #model: #configuration
+ )
+ #(#DividerSpec
+ #name: 'divider1'
+ #layout: #(#LayoutFrame 0 0 102 0 0 1 105 0)
+ )
+ #(#ActionButtonSpec
+ #name: 'targetDirectoryButton'
+ #layout: #(#LayoutFrame 4 0 109 0 147 0 133 0)
+ #label: 'Target Directory:'
+ #model: #doSelectDirectory:
+ #actionValue: 'Target'
+ )
+ #(#InputFieldSpec
+ #name: 'targetDirectoryField'
+ #layout: #(#LayoutFrame 150 0 109 0 0 1.0 131 0)
+ #activeHelpKey: #targetDirectory
+ #model: #targetDirectory
+ )
+ #(#ActionButtonSpec
+ #name: 'topDirectoryButton'
+ #layout: #(#LayoutFrame 4 0 133 0 147 0 157 0)
+ #label: 'Top Directory:'
+ #model: #doSelectDirectory:
+ #actionValue: 'Top'
+ )
+ #(#InputFieldSpec
+ #name: 'topDirectoryField'
+ #layout: #(#LayoutFrame 150 0 133 0 0 1.0 155 0)
+ #activeHelpKey: #topDirectory
+ #model: #topDirectory
+ )
+ #(#ActionButtonSpec
+ #name: 'libraryDirectoryButton'
+ #layout: #(#LayoutFrame 4 0 157 0 147 0 181 0)
+ #label: 'Library Directory:'
+ #model: #doSelectDirectory:
+ #actionValue: 'Library'
+ )
+ #(#InputFieldSpec
+ #name: 'libraryDirectoryField'
+ #layout: #(#LayoutFrame 150 0 157 0 0 1.0 179 0)
+ #activeHelpKey: #libraryDirectory
+ #model: #libraryDirectory
+ )
+ #(#ActionButtonSpec
+ #name: 'startupCFileButton'
+ #layout: #(#LayoutFrame 4 0 181 0 147 0 205 0)
+ #label: 'Startup C-File:'
+ #model: #doSelectCFile:
+ #actionValue: 'StartupCFile'
+ )
+ #(#InputFieldSpec
+ #name: 'startupCFileField'
+ #layout: #(#LayoutFrame 150 0 181 0 0 1.0 203 0)
+ #activeHelpKey: #startupModule
+ #model: #startupCFile
+ )
+ #(#DividerSpec
+ #name: 'divider2'
+ #layout: #(#LayoutFrame 0 0.0 208 0 0 1.0 211 0)
+ )
+ #(#LabelSpec
+ #name: 'stxLibraryButton'
+ #layout: #(#LayoutFrame 4 0 215 0 147 0 239 0)
+ #label: 'ST/X Libraries:'
+ )
+ #(#ComboBoxSpec
+ #name: 'stxLibrariesComboBox'
+ #layout: #(#LayoutFrame 150 0 216 0 0 1 238 0)
+ #activeHelpKey: #stxLibraries
+ #model: #stxLibrary
+ #immediateAccept: false
+ #acceptOnTab: false
+ #comboList: #stxLibraries
+ )
+ #(#ActionButtonSpec
+ #name: 'systemLibrariesButton'
+ #layout: #(#LayoutFrame 4 0 239 0 147 0 263 0)
+ #label: 'System Libraries:'
+ #model: #doSelectLibrary:
+ #actionValue: 'SystemLibrary'
+ )
+ #(#ComboBoxSpec
+ #name: 'systemLibrariesComboBox'
+ #layout: #(#LayoutFrame 150 0 240 0 0 1 262 0)
+ #activeHelpKey: #systemLibaries
+ #model: #systemLibrary
+ #immediateAccept: false
+ #acceptOnTab: false
+ #comboList: #systemLibraries
+ )
+ #(#ActionButtonSpec
+ #name: 'userLibrariesButton'
+ #layout: #(#LayoutFrame 4 0 263 0 147 0 287 0)
+ #label: 'User Libraries:'
+ #model: #doSelectLibrary:
+ #actionValue: 'UserLibrary'
+ )
+ #(#ComboBoxSpec
+ #name: 'userLibrariesComboBox'
+ #layout: #(#LayoutFrame 150 0 264 0 0 1 286 0)
+ #activeHelpKey: #userLibraries
+ #model: #userLibrary
+ #immediateAccept: false
+ #acceptOnTab: false
+ #comboList: #userLibraries
+ )
+ )
+ )
+ )
+ #(#ViewSpec
+ #name: 'Box3'
+ #layout: #(#LayoutFrame -134 1 0 0.0 0 1.0 0 1.0)
+ #component:
+ #(#SpecCollection
+ #collection:
+ #(
+ #(#FramedBoxSpec
+ #name: 'FramedBox'
+ #layout: #(#LayoutFrame -4 0.0 0 0.0 0 1.0 -98 1.0)
+ #component:
+ #(#SpecCollection
+ #collection:
+ #(
+ #(#CheckBoxSpec
+ #name: 'linkRCFilesCheckBox'
+ #layout: #(#LayoutFrame 12 0 24 0 12 1 46 0)
+ #activeHelpKey: #symlinkRCFiles
+ #model: #linkRCFiles
+ #label: 'RC-Files'
+ )
+ #(#CheckBoxSpec
+ #name: 'linkResourcesCheckBox'
+ #layout: #(#LayoutFrame 12 0 48 0 12 1 70 0)
+ #activeHelpKey: #symlinkResources
+ #model: #linkResources
+ #label: 'Resources'
+ )
+ #(#CheckBoxSpec
+ #name: 'linkSourcesCheckBox'
+ #layout: #(#LayoutFrame 12 0 72 0 12 1 94 0)
+ #activeHelpKey: #symlinkSources
+ #model: #linkSources
+ #label: 'Sources'
+ )
+ #(#CheckBoxSpec
+ #name: 'linkBitmapsCheckBox'
+ #layout: #(#LayoutFrame 12 0 96 0 12 1 118 0)
+ #activeHelpKey: #symlinkBitmaps
+ #model: #linkBitmaps
+ #label: 'Bitmaps'
+ )
+ )
+ )
+ #label: 'Symbolic Links'
+ #labelPosition: #topLeft
+ )
+ #(#VerticalPanelViewSpec
+ #name: 'VerticalPanel'
+ #layout: #(#LayoutFrame 0 0.0 -90 1 -6 1.0 0 1.0)
+ #component:
+ #(#SpecCollection
+ #collection:
+ #(
+ #(#ActionButtonSpec
+ #name: 'buildButton'
+ #activeHelpKey: #build
+ #label: 'Build'
+ #model: #doBuild
+ #extent: #(#Point 128 28)
+ )
+ #(#ActionButtonSpec
+ #name: 'stopButton'
+ #activeHelpKey: #stop
+ #label: 'Stop'
+ #model: #doStop
+ #extent: #(#Point 128 28)
+ )
+ #(#ActionButtonSpec
+ #name: 'Button1'
+ #activeHelpKey: #start
+ #label: 'Start'
+ #model: #doStart
+ #extent: #(#Point 128 28)
+ )
+ )
+ )
+ #horizontalLayout: #fit
+ #verticalLayout: #fit
+ #horizontalSpace: 3
+ #verticalSpace: 3
+ )
+ )
+ )
+ )
+ #(#DividerSpec
+ #name: 'Separator1'
+ #layout: #(#LayoutFrame -144 1 0 0.0 -138 1 0 1.0)
+ #orientation: #vertical
+ )
+ )
+ )
+ )
+ #(#DividerSpec
+ #name: 'Separator2'
+ #layout: #(#LayoutFrame 0 0.0 290 0 0 1.0 293 0)
+ )
+ #(#SubCanvasSpec
+ #name: 'SubCanvas'
+ #layout: #(#LayoutFrame 0 0.0 296 0 0 1.0 -26 1)
+ #hasHorizontalScrollBar: false
+ #hasVerticalScrollBar: false
+ #clientHolder: #shellView
+ )
+ #(#UISubSpecification
+ #name: 'windowSpecForInfoBar'
+ #layout: #(#LayoutFrame 0 0.0 -24 1 0 1.0 0 1.0)
+ #majorKey: #ToolApplicationModel
+ #minorKey: #windowSpecForInfoBar
+ )
+ )
+ )
+ )
+! !
+
+!ApplicationBuilder class methodsFor:'menu specs'!
+
+menu
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+ "
+ MenuEditor new openOnClass:ApplicationBuilder andSelector:#menu
+ (Menu new fromLiteralArrayEncoding:(ApplicationBuilder menu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+
+ #(#Menu
+
+ #(
+ #(#MenuItem
+ #label: 'File'
+ #submenu:
+ #(#Menu
+
+ #(
+ #(#MenuItem
+ #label: 'Build'
+ #value: #doBuild
+ #activeHelpKey: #build
+ )
+ #(#MenuItem
+ #label: 'Stop'
+ #value: #doStop
+ #activeHelpKey: #stop
+ )
+ #(#MenuItem
+ #label: 'Start'
+ #value: #doStart
+ #activeHelpKey: #start
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #label: 'Exit'
+ #value: #closeRequest
+ #activeHelpKey: #fileExit
+ )
+ ) nil
+ nil
+ )
+ )
+ #(#MenuItem
+ #label: 'Settings'
+ #submenu:
+ #(#Menu
+
+ #(
+ #(#MenuItem
+ #label: 'Target Directory...'
+ #value: #doSelectDirectory:
+ #activeHelpKey: #targetDirectory
+ #argument: 'Target'
+ )
+ #(#MenuItem
+ #label: 'Top Directory...'
+ #value: #doSelectDirectory:
+ #activeHelpKey: #topDirectory
+ #argument: 'Top'
+ )
+ #(#MenuItem
+ #label: 'Library Directory...'
+ #value: #doSelectDirectory:
+ #activeHelpKey: #libraryDirectory
+ #argument: 'Library'
+ )
+ #(#MenuItem
+ #label: 'Startup C-File...'
+ #value: #doSelectCFile:
+ #activeHelpKey: #startupCFile
+ #argument: 'StartupCFile'
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #label: 'System Libraries...'
+ #value: #doSelectLibrary:
+ #activeHelpKey: #systemLibaries
+ #argument: 'SystemLibrary'
+ )
+ #(#MenuItem
+ #label: 'User Libraries...'
+ #value: #doSelectLibrary:
+ #activeHelpKey: #userLibraries
+ #argument: 'UserLibrary'
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #label: 'Application Link Defines...'
+ #value: #doDefineApplicationLinkDefines
+ #activeHelpKey: #applicationLinkDefines
+ )
+ #(#MenuItem
+ #label: '-'
+ )
+ #(#MenuItem
+ #label: 'Fonts'
+ #submenuChannel: #menuFont
+ )
+ ) nil
+ nil
+ )
+ )
+ #(#MenuItem
+ #label: 'Help'
+ #startGroup: #right
+ #submenuChannel: #menuHelp
+ )
+ ) nil
+ nil
+ )
+! !
+
+!ApplicationBuilder methodsFor:'actions'!
+
+doBuild
+ "builds the application by doing following tasks:
+ 0. Clobber the target directory of the application
+ 1. Generation of the h-file with symbols
+ 2. Generation of the c-file with modules
+ 3. Compilation of the modules init file
+ 4. Compilation of the startup C-file
+ 5. Creating of the symbolic links to the libraries
+ 6. Linking of the libraries to the application
+ 7. Creating of the symbolic links to the resources
+ "
+ |dir compilerPath compilerFlags block0 block1 block2 block3 block4 block5 block6 block7 priority|
+
+ task notNil ifTrue: [self warn: 'There is already a build running!!'].
+
+ self inform: 'Starting building of application...' asBoldText.
+
+ (dir := self getApplicationDirectory) isNil
+ ifTrue: [^self warn: 'Could not create application directory!!'].
+
+ shellView directory: dir.
+
+ (compilerPath := ByteCodeCompiler ccPath, ' ') isNil
+ ifTrue: [^self warn:'Define first a system compiler!!'].
+ compilerFlags := self getCompilerFlags.
+
+ block0 :=
+ [
+ self inform: 'Clobbering the target directory...'.
+ self clobberTargetDirectory: dir.
+ task := nil
+ ].
+ block1 :=
+ [
+ self inform: 'Starting generation of the h-file with symbols...'.
+ self generateHFileWithSymbolsIn: dir.
+ (dir asFilename construct: 'symbols.h') exists
+ ifTrue: [task := nil]
+ ifFalse: [self warn:'Could not generate the h-file with symbols!!']
+ ].
+ block2 :=
+ [
+ self inform: 'Starting generation of the C-file with modules...'.
+ self generateCFileWithModulesIn: dir.
+ (dir asFilename construct: 'modulList.c') exists
+ ifTrue: [task := nil]
+ ifFalse: [self warn:'Could not generate the C-file with libraries!!']
+ ].
+ block3 :=
+ [
+ self inform: 'Starting compilation of the modules init file...'.
+ self compileModulListFileWith: compilerPath, compilerFlags inDirectory: dir.
+ (dir asFilename construct: 'modulList.o') exists
+ ifTrue: [task := nil]
+ ifFalse: [self warn:'Could not compile the modules file!!']
+ ].
+ block4 :=
+ [
+ ((Aspects at: #startupCFile) value asFilename) exists
+ ifFalse: [task := nil. self warn: 'Defined startup C-file not found!!'].
+ self inform: 'Starting compilation of the startup C-file...'.
+ self compileStartupCFileWith: compilerPath, compilerFlags inDirectory: dir.
+ (dir asFilename construct: 'main.o') exists
+ ifTrue: [task := nil]
+ ifFalse: [self warn:'Could not compile the startup C-file!!']
+ ].
+ block5 :=
+ [
+ self inform: 'Starting defining of the symbolic links to the libraries...'.
+ self createSymbolicLinksToTheLibrariesIn: dir.
+ task := nil.
+ ].
+ block6 :=
+ [
+ self inform: 'Starting linking of the libraries to the application...'.
+ self linkLibrariesToTheApplicationIn: dir.
+ (dir asFilename construct: (Aspects at: #applicationName) value) exists
+ ifTrue: [task := nil]
+ ifFalse: [self warn:'Could not build the application!!']
+ ].
+ block7 :=
+ [
+ self inform: 'Starting linking of the resources...'.
+ self createSymbolicLinksToTheResourcesIn: dir.
+ task := nil.
+ ].
+
+ priority := Processor userBackgroundPriority.
+ task := block0 forkAt: priority.
+ task addExitAction:
+ [
+ task isNil ifTrue:
+ [
+ task := block1 forkAt: priority.
+ task addExitAction:
+ [
+ task isNil ifTrue:
+ [
+ task := block2 forkAt: priority.
+ task addExitAction:
+ [
+ task isNil ifTrue:
+ [
+ task := block3 forkAt: priority.
+ task addExitAction:
+ [
+ task isNil ifTrue:
+ [
+ task := block4 forkAt: priority.
+ task addExitAction:
+ [
+ task isNil ifTrue:
+ [
+ task := block5 forkAt: priority.
+ task addExitAction:
+ [
+ task isNil ifTrue:
+ [
+ task := block6 forkAt: priority.
+ task addExitAction:
+ [
+ task isNil ifTrue:
+ [
+ task := block7 forkAt: priority.
+ task addExitAction:
+ [
+ task := nil.
+ self inform: 'Application build.' asBoldText.
+ Display beep.
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+ ]
+
+
+
+
+
+
+!
+
+doDefineApplicationLinkDefines
+ "opens a dialog for defining the application defines"
+
+ |box|
+ box := EnterBox new.
+ box label: 'Application Link Defines'.
+ box initialText: (Aspects at: #applicationLinkDefines) value.
+ box showAtPointer.
+ box accepted
+ ifTrue:
+ [
+ (Aspects at: #applicationLinkDefines) value: box contents
+ ].
+ box destroy
+!
+
+doSelectCFile: whichFile
+ "opens a FileSelectionBrowser in order to select C-file"
+
+ |currentFile selectedFile|
+
+ currentFile := Aspects at: whichFile asLowercaseFirst asSymbol.
+
+ ((selectedFile := FileSelectionBrowser
+ request: 'Select Your ', whichFile, ' File'
+ fileName: currentFile value
+ inDirectory: currentFile value
+ withFileFilters: #('*.c')) notNil and:
+ [selectedFile asFilename exists and: [selectedFile asFilename isDirectory not]])
+ ifTrue: [currentFile value: selectedFile]
+
+
+!
+
+doSelectDirectory: whichDir
+ "opens a FileSelectionBrowser in order to select directory"
+
+ |currentDir selectedDir|
+
+ currentDir := Aspects at: (whichDir asLowercaseFirst, 'Directory') asSymbol.
+
+ ((selectedDir := FileSelectionBrowser
+ request: 'Select Your ', whichDir, ' Directory'
+ fileName: nil
+ inDirectory: currentDir value
+ withFileFilters: #('*.*o')) notNil and:
+ [selectedDir asFilename exists and: [selectedDir asFilename isDirectory]])
+ ifTrue: [currentDir value: selectedDir. shellView executeCommand: 'cd ', selectedDir]
+
+
+!
+
+doSelectLibrary: whichFile
+ "opens a FileSelectionBrowser in order to select library"
+
+ |currentFile selectedFile|
+
+ currentFile := Aspects at: whichFile asLowercaseFirst asSymbol.
+
+ ((selectedFile := FileSelectionBrowser
+ request: 'Select Your ', whichFile, ' File'
+ fileName: currentFile value
+ inDirectory: currentFile value
+ withFileFilters: #('*.*o' '*.a')) notNil and:
+ [selectedFile asFilename exists and: [selectedFile asFilename isDirectory not]])
+ ifTrue: [currentFile value: selectedFile]
+
+
+!
+
+doStart
+ "starts the build application"
+
+ |dir|
+ self doStop.
+ (dir := self getApplicationDirectory) isNil
+ ifTrue: [^self warn: 'Application directory does not exists!!'].
+
+ shellView directory: dir.
+ shellView executeCommand: (Aspects at: #applicationName) value.
+
+!
+
+doStop
+ "terminates the task of the current build"
+
+ task notNil ifTrue: [task removeAllExitActions. task terminate].
+ task := nil.
+ shellView executeCommand: 'clear'.
+ self inform: ''
+
+! !
+
+!ApplicationBuilder methodsFor:'aspects'!
+
+aspectFor:aKey
+ "returns an aspect at aKey"
+
+ ^Aspects at: aKey ifAbsent: [super aspectFor:aKey]
+
+!
+
+aspectsAt: aKey putFirst: anObject
+ "puts firstly anObject as ValueHolder at aKey and returns it"
+
+ ^Aspects at: aKey ifAbsent: [Aspects at: aKey put: anObject asValue]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+!
+
+shellView
+ "returns a shell view"
+
+ shellView isNil ifTrue: [shellView := ShellView new. shellView directory: (Aspects at: #topDirectory) value].
+ ^shellView
+
+
+
+! !
+
+!ApplicationBuilder methodsFor:'building'!
+
+clobberTargetDirectory: dir
+ "clobbers the target directory of the application"
+
+ self executeCommand: 'rm -r *' inDirectory: dir
+
+
+
+
+
+!
+
+compileModulListFileWith: ccPathAndFlags inDirectory: dir
+ "compiles the C-file with the list of the module names"
+
+ |command|
+
+ command := ccPathAndFlags , ' -c -fPIC -O6 -fomit-frame-pointer -m486 -DDEBUG -Di386 modulList.c'.
+
+ self executeCommand: command inDirectory: dir
+
+!
+
+compileStartupCFileWith: ccPathAndFlags inDirectory: dir
+ "compiles the startup file with passing startup class, startup selector, configuration string, and build date"
+
+ |startUpClass cls startUpSelector startupFile command|
+
+ startUpClass := ((Aspects at: #startupMessage) value upTo: $ ) asSymbol.
+ (cls := Smalltalk at: startUpClass) isNil ifTrue: [^self warn: 'Defined class not found in system!!'].
+ startUpSelector := ((Aspects at: #startupMessage) value copy reverse upTo: $ ) reverse asSymbol.
+ (cls respondsTo: startUpSelector) ifFalse: [^self warn: 'Defined class does not respond to the defined selector!!'].
+ startupFile := (Aspects at: #startupCFile) value asFilename.
+ startupFile copyTo: (startupFile := dir asFilename construct: (Aspects at: #startupCFile) value asFilename baseName).
+ command := ccPathAndFlags , ' -o main.o -c -O -O6 -fomit-frame-pointer -m486 -DDEBUG -Di386 ',
+ '-DSTARTUP_CLASS="\"', startUpClass, '\"" ',
+ '-DSTARTUP_SELECTOR="\"', startUpSelector, '\"" ',
+ '-DCONFIGURATION_STRING="\"', (Aspects at: #configuration) value, '\"" ',
+ '-DBUILD_DATE="\"', (Aspects at: #buildDate) value, '\"" ',
+ startupFile name.
+
+ self executeCommand: command inDirectory: dir
+!
+
+compileStartupFileWith: ccPathAndFlags inDirectory: dir
+ "compiles the startup file with passing startup class, startup selector, configuration string, and build date"
+
+ |startUpClass cls startUpSelector startupFile command|
+
+ startUpClass := ((Aspects at: #startupMessage) value upTo: $ ) asSymbol.
+ (cls := Smalltalk at: startUpClass) isNil ifTrue: [^self warn: 'Defined class not found in system!!'].
+ startUpSelector := ((Aspects at: #startupMessage) value copy reverse upTo: $ ) reverse asSymbol.
+ (cls respondsTo: startUpSelector) ifFalse: [^self warn: 'Defined class does not respond to the defined selector!!'].
+ startupFile := (Aspects at: #startupModule) value asFilename.
+ startupFile copyTo: (startupFile := dir asFilename construct: (Aspects at: #startupModule) value asFilename baseName).
+ command := ccPathAndFlags , ' -o main.o -c -O -O6 -fomit-frame-pointer -m486 -DDEBUG -Di386 ',
+ '-DSTARTUP_CLASS="\"', startUpClass, '\"" ',
+ '-DSTARTUP_SELECTOR="\"', startUpSelector, '\"" ',
+ '-DCONFIGURATION_STRING="\"', (Aspects at: #configuration) value, '\"" ',
+ '-DBUILD_DATE="\"', (Aspects at: #buildDate) value, '\"" ',
+ startupFile name.
+
+ self executeCommand: command inDirectory: dir
+!
+
+createSymbolicLinksToTheLibrariesIn: dir
+ "creates the symbolic links to the libraries"
+
+ self getLibraryFileNames value do:
+ [:libPath|
+ self executeCommand: 'ln -s ', libPath , ' ', libPath asFilename head inDirectory: dir
+ ]
+
+
+
+
+!
+
+createSymbolicLinksToTheResourcesIn: dir
+ "creates the symbolic links to the resources"
+
+ (Aspects at: #linkRCFiles) value
+ ifTrue:
+ [
+ self executeCommand:
+ 'ln -s ',
+ ((Aspects at: #libraryDirectory) value asFilename construct: '*.rc') name, ' ',
+ (Aspects at: #targetDirectory) value inDirectory: dir.
+ ].
+ (Aspects at: #linkResources) value
+ ifTrue:
+ [
+ self executeCommand:
+ 'cp -r -d ',
+ ((Aspects at: #libraryDirectory) value asFilename construct: 'resources') name, ' ',
+ (Aspects at: #targetDirectory) value inDirectory: dir.
+ ].
+ (Aspects at: #linkSources) value
+ ifTrue:
+ [
+ self executeCommand:
+ 'cp -r -d ',
+ ((Aspects at: #libraryDirectory) value asFilename construct: 'source') name, ' ',
+ (Aspects at: #targetDirectory) value inDirectory: dir.
+ ].
+ (Aspects at: #linkBitmaps) value
+ ifTrue:
+ [
+ self executeCommand:
+ 'cp -r -d ',
+ ((Aspects at: #libraryDirectory) value asFilename construct: 'bitmaps') name, ' ',
+ (Aspects at: #targetDirectory) value inDirectory: dir.
+ ].
+
+
+!
+
+executeCommand: aCommand inDirectory: dir
+ "executes aCommand in directory dir; put aCommand and the result into the shell view"
+
+ |outStream|
+
+ shellView directory: dir.
+ shellView append: shellView getDirectoryTextString, ' ', aCommand.
+
+ outStream:= PipeStream readingFrom: aCommand errorDisposition:#inline inDirectory: dir.
+ [
+ outStream canReadWithoutBlocking
+ ifTrue:
+ [
+ outStream readWait.
+ shellView append: shellView getDirectoryTextString, ' ',
+ (Text string: (outStream upTo: Character cr) color: Color red).
+ ].
+ ] doWhile:[outStream atEnd not].
+
+ outStream close
+
+!
+
+generateCFileWithModulesIn: dir
+ "generates a C-file with the modules in directory dir"
+
+ |selectionOfLibraries|
+
+ selectionOfLibraries := self getModuleNames.
+ self executeCommand: 'echo "#include <stcIntern.h>" > modulList.c' inDirectory: dir.
+ self executeCommand: 'echo "typedef void (*vf)();" >> modulList.c' inDirectory: dir.
+ selectionOfLibraries do:
+ [:lib|
+ self executeCommand: 'echo "extern void _', lib, '_Init();" >> modulList.c' inDirectory: dir.
+ ].
+ self executeCommand: 'echo "static vf modules[] = {" >> modulList.c' inDirectory: dir.
+ selectionOfLibraries do:
+ [:lib|
+ self executeCommand: 'echo "_', lib, '_Init," >> modulList.c' inDirectory: dir.
+ ].
+ self executeCommand: 'echo "(vf)0};" >> modulList.c' inDirectory: dir.
+ self executeCommand: 'echo "vf *__modules__ = modules;" >> modulList.c' inDirectory: dir
+
+
+!
+
+generateHFileWithSymbolsIn: dir
+ "generates a H-file with the symbols in directory dir"
+
+ |symbolsFile realInc|
+ ByteCodeCompiler stcCompilationIncludes asArrayOfSubstrings do:
+ [:inc|
+ realInc := inc readStream.
+ realInc upTo: $/.
+ realInc := '/', realInc upToEnd.
+ (symbolsFile := realInc asFilename construct: 'symbols.stc') exists
+ ifTrue:
+ [
+ self executeCommand: 'echo "char *__symbols[] = {" > symbols.h' inDirectory: dir.
+ self executeCommand: 'sed ''s/^/"/'' < ', symbolsFile name,' | sed ''s/$/",/'' | sed ''s/\\/\\\\/g'' >> symbols.h' inDirectory: dir.
+ self executeCommand: 'echo "0 };" >> symbols.h' inDirectory: dir.
+ ]
+ ].
+ ^nil
+
+
+
+!
+
+inform: aString
+ "outputs aString via shell view as information"
+
+ shellView commandInputField contents: aString
+
+
+
+
+!
+
+linkLibrariesToTheApplicationIn: dir
+ "links the libraries to the application"
+
+ |appName command|
+
+ appName := (Aspects at: #applicationName) value.
+
+ command := ByteCodeCompiler ccPath,
+ ' ', (Aspects at: #applicationLinkDefines) value, ' ',
+ ' -o ' , appName,
+ ' modulList.o main.o ',
+ ((Aspects at: #libraryDirectory) value asFilename construct: 'librun', ObjectFileLoader sharedLibraryExtension) name, ' ',
+ ((self getLibraryFileNames, (Aspects at: #systemLibraries) value) asStringCollection asStringWith: $ ).
+
+ self executeCommand: command inDirectory: dir
+
+
+
+
+! !
+
+!ApplicationBuilder methodsFor:'change & update'!
+
+update:something with:aParameter from:changedObject
+ "updates the combo boxes with the library names and the module names"
+
+ |library libraries|
+
+ (changedObject == (Aspects at: #stxLibrary))
+ ifTrue:
+ [
+ libraries := (Aspects at: #stxLibraries) value.
+ (Aspects at: #stxLibrary) value size = 0 ifTrue: [libraries remove: (Aspects at: #oldSTXLibrary) value ifAbsent: nil].
+ (Aspects at: #oldSTXLibrary) value: (library := (Aspects at: #stxLibrary) value).
+ (libraries includes: library) not &
+ library notEmpty
+ ifTrue:
+ [
+ libraries addFirst: library
+ ]
+ ].
+ (changedObject == (Aspects at: #systemLibrary))
+ ifTrue:
+ [
+ libraries := (Aspects at: #systemLibraries) value.
+ (Aspects at: #systemLibrary) value size = 0 ifTrue: [libraries remove: (Aspects at: #oldSystemLibrary) value ifAbsent: nil].
+ (Aspects at: #oldSystemLibrary) value: (library := (Aspects at: #systemLibrary) value).
+ (libraries includes: library) not &
+ library notEmpty
+ ifTrue:
+ [
+ libraries addFirst: library
+ ]
+ ].
+ (changedObject == (Aspects at: #userLibrary))
+ ifTrue:
+ [
+ libraries := (Aspects at: #userLibraries) value.
+ (Aspects at: #userLibrary) value size = 0 ifTrue: [libraries remove: (Aspects at: #oldUserLibrary) value ifAbsent: nil].
+ (Aspects at: #oldUserLibrary) value: (library := (Aspects at: #userLibrary) value).
+ (libraries includes: library) not &
+ library notEmpty
+ ifTrue:
+ [
+ libraries addFirst: library
+ ]
+ ].
+
+
+
+
+
+
+! !
+
+!ApplicationBuilder methodsFor:'initialization'!
+
+initialize
+ "initialize all aspects"
+
+ |homeDir|
+
+ super initialize.
+
+ Aspects := Aspects ? IdentityDictionary new.
+
+ homeDir := Filename homeDirectory asFilename.
+
+ self aspectsAt: #applicationName putFirst: 'application'.
+ self aspectsAt: #startupMessage putFirst: 'Smalltalk start'.
+ self aspectsAt: #startupCFile putFirst: (homeDir construct: 'stx/librun/main.c') name.
+ self aspectsAt: #topDirectory putFirst: (homeDir construct: 'stx') name.
+ self aspectsAt: #targetDirectory putFirst: (homeDir construct: 'stx/projects/application') name.
+ self aspectsAt: #libraryDirectory putFirst: (homeDir construct: 'stx/projects/smalltalk') name.
+
+ self aspectsAt: #stxLibraries putFirst:
+ (ObjectMemory binaryModuleInfo collect: [:binMoInfo| (binMoInfo name copy reverse upTo: $ ) reverse]) asSortedCollection.
+ self aspectsAt: #systemLibraries putFirst: ObjectFileLoader searchedLibraries.
+ self aspectsAt: #userLibraries putFirst: OrderedCollection new.
+
+ Aspects at: #buildDate put: Date today printString, ' ', Time now printString.
+ self aspectsAt: #configuration putFirst: Smalltalk configuration.
+
+ self aspectsAt: #linkRCFiles putFirst: true.
+ self aspectsAt: #linkResources putFirst: true.
+ self aspectsAt: #linkSources putFirst: true.
+ self aspectsAt: #linkBitmaps putFirst: true.
+
+ (Aspects at: #stxLibrary put: ((Aspects at: #stxLibraries) value at: 1 ifAbsent: '') asValue) addDependent: self.
+ (Aspects at: #systemLibrary put: ((Aspects at: #systemLibraries) value at: 1 ifAbsent: '') asValue) addDependent: self.
+ (Aspects at: #userLibrary put: ((Aspects at: #userLibraries) value at: 1 ifAbsent: '') asValue) addDependent: self.
+
+ self aspectsAt: #oldSTXLibrary putFirst: (Aspects at: #stxLibrary) value.
+ self aspectsAt: #oldSystemLibrary putFirst: (Aspects at: #systemLibrary) value.
+ self aspectsAt: #oldUserLibrary putFirst: (Aspects at: #userLibrary) value.
+
+ self aspectsAt: #applicationLinkDefines putFirst: '-L/usr/X11/lib -Llib -Lbinary -L. -L/usr/local/lib -L/usr/lib -L/lib -lm -ldl -lXext -lX11'.
+! !
+
+!ApplicationBuilder methodsFor:'queries'!
+
+getApplicationDirectory
+ "returns the directory of the application; if not present, create it"
+
+ |appDir|
+
+ (appDir := (Aspects at: #targetDirectory) value asFilename) exists ifFalse:[appDir makeDirectory].
+ (appDir isReadable and:[appDir isWritable]) ifFalse: [^nil].
+
+ ^appDir name
+
+!
+
+getCompilerFlags
+ "returns the defines of the OS and the compiler flags of the ByteCodeCompiler"
+
+ |compilerFlags|
+
+ compilerFlags := OperatingSystem getOSDefine ? ''.
+
+ ByteCodeCompiler stcCompilationDefines notNil
+ ifTrue:[compilerFlags := compilerFlags , ' ' , ByteCodeCompiler stcCompilationDefines].
+ ByteCodeCompiler stcCompilationIncludes notNil
+ ifTrue:[compilerFlags := compilerFlags , ' ' , ByteCodeCompiler stcCompilationIncludes].
+ ByteCodeCompiler ccCompilationOptions notNil
+ ifTrue:[compilerFlags := compilerFlags , ' ' , ByteCodeCompiler ccCompilationOptions].
+
+ ^compilerFlags
+
+!
+
+getLibraryFileNames
+ "returns the complete file names of the system and the user libraries"
+
+ |libraryFileNames|
+
+ libraryFileNames := OrderedCollection new.
+
+ (Aspects at: #stxLibraries) value do:
+ [:lib|
+ |abbrevLib libPath|
+ abbrevLib := lib.
+ lib = 'GLXWorkstation' ifTrue: [abbrevLib := 'GLXWorkstat'].
+ lib = 'XWorkstation' ifTrue: [abbrevLib := 'XWorkstat' ].
+ lib = 'ObjectFileLoader' ifTrue: [abbrevLib := 'ObjFLoader' ].
+ (libPath := (Aspects at: #libraryDirectory) value asFilename construct: abbrevLib, ObjectFileLoader sharedLibraryExtension) exists
+ ifTrue: [libraryFileNames add: libPath name]
+ ].
+
+ ^libraryFileNames, (Aspects at: #userLibraries) value
+
+!
+
+getModuleNames
+ "returns the module names of the system and the user libraries"
+
+ |moduleNames|
+
+ moduleNames := OrderedCollection new.
+ (Aspects at: #userLibraries) value do:
+ [:lib|
+ lib asFilename exists ifTrue: [moduleNames add: (lib asFilename baseName upTo: $.)]
+ ].
+
+ ^(Aspects at: #stxLibraries) value, moduleNames
+! !
+
+!ApplicationBuilder methodsFor:'startup / release'!
+
+closeRequest
+ "close request; before closing stop the running build, then release the dependents of all aspects"
+
+ self doStop.
+ Aspects do: [:aspect| aspect release].
+
+ super closeRequest
+
+! !
+
+!ApplicationBuilder class methodsFor:'documentation'!
+
+version
+ ^ '$Header: /cvs/stx/stx/libtool/ApplicationBuilder.st,v 1.1 1998-03-31 18:22:48 tz Exp $'
+! !