diff options
Diffstat (limited to 'lib/compiler/external_compiler.tcl')
-rw-r--r--[-rwxr-xr-x] | lib/compiler/external_compiler.tcl | 220 |
1 files changed, 150 insertions, 70 deletions
diff --git a/lib/compiler/external_compiler.tcl b/lib/compiler/external_compiler.tcl index 3cf581b..5d8c6b2 100755..100644 --- a/lib/compiler/external_compiler.tcl +++ b/lib/compiler/external_compiler.tcl @@ -2,7 +2,7 @@ # Part of MCU 8051 IDE ( http://mcu8051ide.sf.net ) ############################################################################ -# Copyright (C) 2007-2009 by Martin Ošmera # +# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera # # martin.osmera@gmail.com # # # # This program is free software; you can redistribute it and#or modify # @@ -21,6 +21,11 @@ # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # ############################################################################ +# >>> File inclusion guard +if { ! [ info exists _EXTERNAL_COMPILER_TCL ] } { +set _EXTERNAL_COMPILER_TCL _ +# <<< File inclusion guard + # -------------------------------------------------------------------------- # DESCRIPTION # Implements interface to external compilers @@ -163,7 +168,7 @@ namespace eval ExternalCompiler { variable sdcc_string_options_def { model --model-small standard --std-sdcc89 - stack --pack-iram + stack {} custom {} } # Current SDCC string options @@ -192,6 +197,16 @@ namespace eval ExternalCompiler { # Current semicolon separated optional string options variable sdcc_scs_string_options + ## Make utility + # General options, this is an array! + variable makeutil_config + # Default values for the eneral options + variable makeutil_config_def { + c_ena 0 + c_file {} + co_file {} + ct_file {} + } ## Make backup copies for files with the given extensions and remove original files # (input_filename.extension -> input_filename.extension~)* @@ -217,50 +232,76 @@ namespace eval ExternalCompiler { proc compile_C {work_dir input_file iram xram code} { variable input_filename ;# String: Name of file to compile (without extension) variable compiler_used ;# Int: Compiler ID (1 == ASEM-51; 2 == ASL; 3 == AS31, other values have no meaning) + variable makeutil_config;# Make utility - general options set compiler_used 0 set input_filename [file rootname $input_file] backup_and_remove {asm cdb ihx} set sdcc_opts [determinate_sdcc_options] - if {${::PROGRAM_AVALIABLE(sdcc-sdcc)}} { + if {${::PROGRAM_AVAILABLE(sdcc-sdcc)}} { set sdcc_cmd {sdcc-sdcc} - } { + } else { set sdcc_cmd {sdcc} } - ::X::messages_text_append [::Compiler::msgc {S}][mc "\n\nStarting compiler ..."] + + # Normal way (POSIX) if {!$::MICROSOFT_WINDOWS} { - ::X::messages_text_append "\ncd \"$work_dir\"\n$sdcc_cmd -mmcs51 --iram-size $iram --xram-size $xram --code-size $code $sdcc_opts \"$input_file\"" - } { - ::X::messages_text_append "\ncd \"$work_dir\"\n$sdcc_cmd -mmcs51 --iram-size $iram --xram-size $xram --code-size $code --nooverlay --noinduction --verbose --debug -V --std-sdcc89 --model-small --pack-iram \"$input_file\"" + # Start GNU make + if {$makeutil_config(c_ena) && ${::PROGRAM_AVAILABLE(make)}} { + ::X::messages_text_append [::Compiler::msgc {S}][mc "\n\nStarting make ..."] + ::X::messages_text_append "\ncd \"${work_dir}\"\nmake -f \"${makeutil_config(c_file)}\" ${makeutil_config(co_file)} ${makeutil_config(ct_file)}" + + # Start SDCC + } else { + ::X::messages_text_append [::Compiler::msgc {S}][mc "\n\nStarting compiler ..."] + ::X::messages_text_append "\ncd \"${work_dir}\"\n${sdcc_cmd} -mmcs51 --iram-size ${iram} --xram-size ${xram} --code-size ${code} ${sdcc_opts} \"${input_file}\"" + } + # Microsoft Windows way + } else { + regsub -all {/} $work_dir "\\\\\\\\" work_dir + regsub -all {/} $input_file "\\\\\\\\" input_file + + ::X::messages_text_append [::Compiler::msgc {S}][mc "\n\nStarting compiler ..."] + ::X::messages_text_append "\ncd \"${work_dir}\"\n${sdcc_cmd} -mmcs51 --iram-size ${iram} --xram-size ${xram} --code-size ${code} ${sdcc_opts} \"${input_file}\"" } if {[catch { cd $work_dir - }]} { + }]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "\nError: Unable to change working directory to '%s'" $work_dir] } if {!$::MICROSOFT_WINDOWS} { ;# Normal way (POSIX) - return [exec -- /bin/sh -c "$sdcc_cmd -mmcs51 \ - --iram-size $iram \ - --xram-size $xram \ - --code-size $code \ - $sdcc_opts \"$input_file\"" |& \ - tclsh "${::LIB_DIRNAME}/external_command.tcl" \ - [tk appname] \ - {::ExternalCompiler::ext_compilation_complete 1}\ - ::X::compilation_message & \ - ] - } { ;# Microsoft Windows way + # Start GNU make + if {$makeutil_config(c_ena) && ${::PROGRAM_AVAILABLE(make)}} { + return [exec -- /bin/sh -c "make -f \"${makeutil_config(c_file)}\" ${makeutil_config(co_file)} ${makeutil_config(ct_file)}" |& \ + tclsh "${::LIB_DIRNAME}/external_command.tcl" \ + [tk appname] \ + {::ExternalCompiler::ext_compilation_complete 1} \ + ::X::compilation_message & \ + ] + + # Start SDCC + } else { + return [exec -- /bin/sh -c "$sdcc_cmd -mmcs51 \ + --iram-size $iram \ + --xram-size $xram \ + --code-size $code \ + $sdcc_opts \"$input_file\"" |& \ + tclsh "${::LIB_DIRNAME}/external_command.tcl" \ + [tk appname] \ + {::ExternalCompiler::ext_compilation_complete 1}\ + ::X::compilation_message & \ + ] + } + } else { ;# Microsoft Windows way eval [subst -nocommands { - return [exec -- "${::LIB_DIRNAME}/sdcc.bat" \ - "${::LIB_DIRNAME}" \ - $iram \ - $xram \ - $code \ - "$input_file" \ + return [exec -- "${::INSTALLATION_DIR}/startsdcc.bat" \ + "${work_dir}" \ + $sdcc_opts \ + "${input_file}" \ |& \ - "${::LIB_DIRNAME}/external_command.bat" \ - "${::LIB_DIRNAME}/external_command.tcl" \ - [tk appname] \ + "${::INSTALLATION_DIR}/external_command.bat" \ + "${::INSTALLATION_DIR}/external_command.exe" \ + "[tk appname]" \ {::ExternalCompiler::ext_compilation_complete 1} \ ::X::compilation_message & \ ] @@ -292,7 +333,7 @@ namespace eval ExternalCompiler { ::X::messages_text_append "\ncd \"$work_dir\"\nas31 $as31_options \"$input_file\"" if {[catch { cd $work_dir - }]} { + }]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "\nError: Unable to change working directory to '%s'" $work_dir] } backup_and_remove {adf hex lst} @@ -322,20 +363,47 @@ namespace eval ExternalCompiler { set input_filename [file rootname $input_file_base] set working_dir $work_dir - set asem51_options [determinate_asem51_options] ::X::messages_text_append [::Compiler::msgc {S}][mc "\n\nStarting compiler ..."] - ::X::messages_text_append "\ncd \"$work_dir\"\nasem $asem51_options \"$input_file\"" + + set asem51_options [determinate_asem51_options] + if {$::MICROSOFT_WINDOWS} { + regsub -all -- {--verbose} $asem51_options {} asem51_options + regsub -all -- {--} $asem51_options {/} asem51_options + regsub -all -- {=} $asem51_options {:} asem51_options + regsub -all -- {;} $asem51_options { /includes:} asem51_options + regsub -all {/} $work_dir "\\\\\\\\" work_dir + regsub -all {/} $input_file "\\\\\\\\" input_file + ::X::messages_text_append "\ncd \"$work_dir\"\nasem \"$input_file\" $asem51_options" + } else { + ::X::messages_text_append "\ncd \"$work_dir\"\nasem $asem51_options \"$input_file\"" + } if {[catch { cd $work_dir - }]} { + }]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "\nError: Unable to change working directory to '%s'" $work_dir] } backup_and_remove {adf hex lst omf} - return [exec -- /bin/sh -c "asem $asem51_options \"$input_file\"" |& \ - tclsh "${::LIB_DIRNAME}/external_command.tcl" "[tk appname]" \ - ::ExternalCompiler::ext_compilation_complete ::X::compilation_message & \ - ] + if {!$::MICROSOFT_WINDOWS} { ;# Normal way (POSIX) + return [exec -- /bin/sh -c "asem $asem51_options \"$input_file\"" |& \ + tclsh "${::LIB_DIRNAME}/external_command.tcl" "[tk appname]" \ + ::ExternalCompiler::ext_compilation_complete ::X::compilation_message & \ + ] + } else { ;# Microsoft Windows way + eval [subst -nocommands { + return [exec -- "${::INSTALLATION_DIR}/startasem.bat" \ + "${work_dir}" \ + "${input_file}" \ + $asem51_options \ + |& \ + "${::INSTALLATION_DIR}/external_command.bat" \ + "${::INSTALLATION_DIR}/external_command.exe" \ + "[tk appname]" \ + {::ExternalCompiler::ext_compilation_complete 1} \ + ::X::compilation_message & \ + ] + }] + } } ## Start ASL (Assembler) @@ -364,7 +432,7 @@ namespace eval ExternalCompiler { ::X::messages_text_append "\ncd \"$work_dir\"\nasl $asl_opts \"$input_file\"" if {[catch { cd $work_dir - }]} { + }]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "\nError: Unable to change working directory to '%s'" $work_dir] } return [exec -- /bin/sh -c "asl $asl_opts \"$input_file\" $additional_commands" |& \ @@ -383,18 +451,20 @@ namespace eval ExternalCompiler { # List of files included files in the main file set included_files [list] + set cbd_file {} ;# We will set this variable later ... + # Open C DeBug file generated by SDCC compiler if {[catch { set cdb_file [open $input_filename.cdb r] - }]} { + }]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "\nUnable to find \"%s\"" [file rootname $input_filename].cdb] return } # Open the hashes file for writing (possibly create the file) if {[catch { - set hs_file [open $input_filename.hashes w 420] - }]} { + set hs_file [open $input_filename.hashes w 0640] + }]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "\nUnable to create \"%s\"" [file rootname $input_filename].hashes] catch {close $cbd_file} return @@ -429,11 +499,11 @@ namespace eval ExternalCompiler { } ## This function must be called after exteral compiler finished its work - # @parm Int action = 0 - Action to perform after successfull compilation + # @parm Int action=0 - Action to perform after successfull compilation # 0 - No action # 1 - Copy <file>.ihx to <file>.hex # @return void - proc ext_compilation_complete args { + proc ext_compilation_complete {{action 0}} { variable input_filename ;# String: Name of file to compile (without extension) variable compiler_used ;# Int: Compiler ID (1 == ASEM-51; 2 == ASL; 3 == AS31, other values have no meaning) variable assembler_ASEM51_addcfg;# Current ASEM-51 assembler configuration @@ -464,10 +534,13 @@ namespace eval ExternalCompiler { create_hashes_file } } - ::X::messages_text_append [::Compiler::msgc {S}][mc "\nCompilation successful"] + + if {$::X::compilation_successfull} { + ::X::messages_text_append [::Compiler::msgc {S}][mc "\nCompilation successful"] + } # Perform specified after successfull compilation - switch -- [lindex $args 0] { + switch -- $action { 0 { ;# No action } 1 { ;# Copy <file>.ihx to <file>.hex @@ -479,9 +552,10 @@ namespace eval ExternalCompiler { } } } + } # Compilation failed - } { + if {!$::X::compilation_successfull} { ::X::messages_text_append [::Compiler::msgc {E}][mc "\nCompilation FAILED"] } ::X::ext_compilation_complete @@ -505,8 +579,8 @@ namespace eval ExternalCompiler { # Try to open code listing file and some tempotary debug file if {[catch { set lst_file [open $input_filename.lst r] - set adf_file [open $input_filename.adf w 420] - } result]} { + set adf_file [open $input_filename.adf w 0640] + } result]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "File access error:\n%s" $result] return 0 } @@ -514,7 +588,6 @@ namespace eval ExternalCompiler { # Write file header puts $adf_file "# Assembler Debug File created by ${::APPNAME}" puts $adf_file "# Used assembler: AS31" - puts $adf_file "# Date: [clock format [clock seconds] -format {%D}]" # Write MD5 of the source file puts -nonewline $adf_file [::md5::md5 -hex -file $input_file_base] @@ -550,8 +623,8 @@ namespace eval ExternalCompiler { scan $h %x h lappend adf_code $h } - }]} { - ::X::messages_text_append [::Compiler::msgc {E}][mc "Unable to understand formulation at line %s in file %s" $line_number $input_filename.lst] + }]} then { + ::X::messages_text_append [::Compiler::msgc {E}][mc "Unable to understand formulation at %s in file %s" $line_number $input_filename.lst] close $lst_file close $adf_file return 0 @@ -561,11 +634,11 @@ namespace eval ExternalCompiler { if {$address == {}} { puts -nonewline $adf_file { } puts -nonewline $adf_file $adf_code - } { + } else { if {[catch { scan $address %x address - }]} { - ::X::messages_text_append [::Compiler::msgc {E}][mc "Unable to understand formulation at line %s in file %s" $line_number $input_filename.lst] + }]} then { + ::X::messages_text_append [::Compiler::msgc {E}][mc "Unable to understand formulation at %s in file %s" $line_number $input_filename.lst] close $lst_file close $adf_file return 0 @@ -603,8 +676,8 @@ namespace eval ExternalCompiler { # Try to open code listing file and some tempotary debug file if {[catch { set lst_file [open $input_filename.lst r] - set adf_file [open $input_filename._adf w 420] - } result]} { + set adf_file [open $input_filename._adf w 0640] + } result]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "File access error:\n%s" $result] return 0 } @@ -619,7 +692,7 @@ namespace eval ExternalCompiler { # Read 1 line set line [gets $lst_file] - # Normal line coresponding to certain line in source code + # Normal line corresponding to certain line in source code if {[regexp {^ *\d+:(..)?} $line inclusion_level]} { # Extract numbers after "line_num: inc_lvl " set line [string range $line [string length $inclusion_level] end] @@ -701,22 +774,21 @@ namespace eval ExternalCompiler { # Open final debug file if {[catch { - set adf_file [open $input_filename.adf w 420] - } result]} { + set adf_file [open $input_filename.adf w 0640] + } result]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "File access error:\n%s" $result] return 0 } # Write file header puts $adf_file "# Assembler Debug File created by ${::APPNAME}" puts $adf_file "# Used assembler: ASEM-51" - puts $adf_file "# Date: [clock format [clock seconds] -format {%D}]" # Create list of included files with MD5 hashes set hashes_and_files {} set project_dir_len [string length $project_dir] foreach filename $included_files { if {[catch { lappend hashes_and_files [::md5::md5 -hex -file $filename] - } result]} { + } result]} then { lappend hashes_and_files 0 ::X::messages_text_append [::Compiler::msgc {E}][mc "File access error:\n%s" $result] } @@ -730,7 +802,7 @@ namespace eval ExternalCompiler { # Copy content of tempotary debug file to final debug file if {[catch { set adf__file [open $input_filename._adf r] - } result]} { + } result]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "File access error:\n%s" $result] return 0 } @@ -756,8 +828,8 @@ namespace eval ExternalCompiler { if {[catch { set map_file [open $input_filename.map r] ;# ASL debug file set hex_file [open $input_filename.hex r] ;# Machine code - set adf_file [open $input_filename.adf w 420] ;# MCU 8051 IDE debug file - } result]} { + set adf_file [open $input_filename.adf w 0640] ;# MCU 8051 IDE debug file + } result]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "File access error:\n%s" $result] return 0 } @@ -812,7 +884,7 @@ namespace eval ExternalCompiler { set filename [file join $project_dir [file normalize $filename]] if {[catch { lappend hashes_and_files [::md5::md5 -hex -file $filename] - } result]} { + } result]} then { ::X::messages_text_append [::Compiler::msgc {E}][mc "\nFile access error:\n%s" $result] lappend hashes_and_files {0} } @@ -829,7 +901,6 @@ namespace eval ExternalCompiler { seek $map_file 0 puts $adf_file "# Assembler Debug File created by ${::APPNAME}" puts $adf_file "# Used assembler: ASL" - puts $adf_file "# Date: [clock format [clock seconds] -format {%D}]" puts $adf_file $hashes_and_files unset hashes_and_files @@ -914,7 +985,7 @@ namespace eval ExternalCompiler { set val [::IHexTools::get_value $i] if {$val > -1} { lappend code [expr "0x$val"] - } { + } else { lappend code 0 } } @@ -956,7 +1027,7 @@ namespace eval ExternalCompiler { if {$value != {}} { if {[regexp {\s} $value]} { append result { } $key { } "\"" $value "\"" - } { + } else { append result { } $key { } $value } } @@ -969,7 +1040,7 @@ namespace eval ExternalCompiler { if {$value != {}} { if {[regexp {\s} $value]} { append result { } $key { } "\"" $value "\"" - } { + } else { append result { } $key { } $value } } @@ -986,7 +1057,7 @@ namespace eval ExternalCompiler { set result $assembler_ASEM51_config(custom) if {$assembler_ASEM51_config(-i) != {}} { - append result { -i } {"} $assembler_ASEM51_config(i) {"} + append result " --includes=$assembler_ASEM51_config(-i)" } foreach opt {--omf-51 --columns --verbose} { if {$assembler_ASEM51_config($opt)} { @@ -1069,8 +1140,17 @@ namespace eval ExternalCompiler { $::ExternalCompiler::sdcc_optional_string_options_def array set ::ExternalCompiler::sdcc_scs_string_options \ $::ExternalCompiler::sdcc_scs_string_options_def + + # Make utility + foreach {key value} ${::ExternalCompiler::makeutil_config_def} { + set ::ExternalCompiler::makeutil_config($key) $value + } } } # Initialize NS variables ExternalCompiler::initialize + +# >>> File inclusion guard +} +# <<< File inclusion guard |