File indexing completed on 2024-12-01 05:12:54
0001 /*************************************************************************** 0002 * Copyright (C) 2005 by David Saxton * 0003 * david@bluehaze.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #include "sdcc.h" 0012 #include "asminfo.h" 0013 #include "languagemanager.h" 0014 #include "logview.h" 0015 #include "microinfo.h" 0016 #include "microlibrary.h" 0017 0018 #include <KLocalizedString> 0019 #include <KMessageBox> 0020 #include <KProcess> 0021 0022 #include <ktlconfig.h> 0023 #include <ktechlab_debug.h> 0024 0025 SDCC::SDCC(ProcessChain *processChain) 0026 : ExternalLanguage(processChain, "SDCC") 0027 { 0028 m_successfulMessage = i18n("*** Compilation successful ***"); 0029 m_failedMessage = i18n("*** Compilation failed ***"); 0030 } 0031 0032 SDCC::~SDCC() 0033 { 0034 } 0035 0036 void SDCC::processInput(ProcessOptions options) 0037 { 0038 resetLanguageProcess(); 0039 0040 MicroInfo *info = MicroLibrary::self()->microInfoWithID(options.m_picID); 0041 if (!info) { 0042 outputError(i18n("Could not find PIC with ID \"%1\".", options.m_picID)); 0043 return; 0044 } 0045 0046 m_processOptions = options; 0047 0048 if (KTLConfig::sDCC_install_prefix().isEmpty()) { 0049 qCDebug(KTL_LOG) << "using system sdcc"; 0050 *m_languageProcess << ("sdcc"); 0051 } else { 0052 qCDebug(KTL_LOG) << "using sdcc at " << KTLConfig::sDCC_install_prefix(); 0053 *m_languageProcess << (KTLConfig::sDCC_install_prefix().append("/bin/sdcc")); 0054 } 0055 0056 // BEGIN Pass custom sdcc options 0057 #define ARG(text, option) \ 0058 if (KTLConfig::text()) \ 0059 *m_languageProcess << (QString("--%1").arg(option)); 0060 // General 0061 ARG(sDCC_nostdlib, "nostdlib") 0062 ARG(sDCC_nostdinc, "nostdinc") 0063 ARG(sDCC_less_pedantic, "less-pedantic") 0064 ARG(sDCC_std_c89, "std-c89") 0065 ARG(sDCC_std_c99, "std-c99") 0066 ARG(sDCC_use_non_free, "use-non-free"); 0067 0068 // Code generation 0069 ARG(sDCC_stack_auto, "stack-auto") 0070 ARG(sDCC_int_long_reent, "int-long-reent") 0071 ARG(sDCC_float_reent, "float-reent") 0072 ARG(sDCC_fommit_frame_pointer, "fommit-frame-pointer") 0073 ARG(sDCC_no_xinit_opt, "no-xinit-opt") 0074 ARG(sDCC_all_callee_saves, "all-callee-saves") 0075 0076 // Optimization 0077 ARG(sDCC_nooverlay, "nooverlay") 0078 ARG(sDCC_nogcse, "nogcse") 0079 ARG(sDCC_nolabelopt, "nolabelopt") 0080 ARG(sDCC_noinvariant, "noinvariant") 0081 ARG(sDCC_noinduction, "noinduction") 0082 ARG(sDCC_no_peep, "no-peep") 0083 ARG(sDCC_noloopreverse, "noloopreverse") 0084 ARG(sDCC_opt_code_size, "opt-code-size") 0085 ARG(sDCC_opt_code_speed, "opt-code-speed") 0086 ARG(sDCC_peep_asm, "peep-asm") 0087 ARG(sDCC_nojtbound, "nojtbound") 0088 0089 // PIC16 Specific 0090 if (info->instructionSet()->set() == AsmInfo::PIC16) { 0091 ARG(sDCC_nodefaultlibs, "nodefaultlibs") 0092 ARG(sDCC_pno_banksel, "pno-banksel") 0093 ARG(sDCC_pstack_model_large, "pstack-model=large") 0094 ARG(sDCC_debug_xtra, "debug-xtra") 0095 ARG(sDCC_denable_peeps, "denable-peeps") 0096 ARG(sDCC_calltree, "calltree") 0097 ARG(sDCC_fstack, "fstack") 0098 ARG(sDCC_optimize_goto, "optimize-goto") 0099 ARG(sDCC_optimize_cmp, "optimize-cmp") 0100 ARG(sDCC_optimize_df, "optimize-df") 0101 } 0102 #undef ARG 0103 0104 if (!KTLConfig::sDCC_install_prefix().isEmpty()) { 0105 QString incDir = ""; 0106 switch (info->instructionSet()->set()) { 0107 case AsmInfo::PIC14: 0108 incDir = "pic14"; 0109 break; 0110 case AsmInfo::PIC16: 0111 incDir = "pic16"; 0112 break; 0113 default: 0114 qCWarning(KTL_LOG) << "unsupported PIC instruction set " << info->instructionSet()->set(); 0115 } 0116 *m_languageProcess << (QString("-I%1/share/sdcc/include").arg(KTLConfig::sDCC_install_prefix())); 0117 *m_languageProcess << (QString("-I%1/share/sdcc/include/%2").arg(KTLConfig::sDCC_install_prefix()).arg(incDir)); 0118 *m_languageProcess << (QString("-I%1/share/sdcc/non-free/include/%2").arg(KTLConfig::sDCC_install_prefix()).arg(incDir)); 0119 } 0120 0121 if (!KTLConfig::miscSDCCOptions().isEmpty()) { 0122 // note: this will not work with quotes inside the text; those need special parsing 0123 *m_languageProcess << (KTLConfig::miscSDCCOptions().split(QRegExp(" "))); 0124 } 0125 // END Pass custom sdcc options 0126 0127 *m_languageProcess << ("--debug"); // Enable debugging symbol output 0128 *m_languageProcess << ("-S"); // Compile only; do not assemble or link 0129 0130 QString asmSwitch; 0131 switch (info->instructionSet()->set()) { 0132 case AsmInfo::PIC12: 0133 // Last time I checked, SDCC doesn't support Pic12, and probably never will, but whatever... 0134 asmSwitch = "-mpic12"; 0135 break; 0136 case AsmInfo::PIC14: 0137 asmSwitch = "-mpic14"; 0138 break; 0139 case AsmInfo::PIC16: 0140 asmSwitch = "-mpic16"; 0141 break; 0142 } 0143 0144 *m_languageProcess << (asmSwitch); 0145 0146 *m_languageProcess << ("-" + options.m_picID.toLower()); 0147 0148 *m_languageProcess << (options.inputFiles().first()); 0149 0150 *m_languageProcess << ("-o"); 0151 *m_languageProcess << (options.intermediaryOutput()); 0152 0153 if (!start()) { 0154 KMessageBox::error(LanguageManager::self()->logView(), i18n("Compilation failed. Please check you have sdcc installed.")); 0155 processInitFailed(); 0156 return; 0157 } 0158 } 0159 0160 bool SDCC::isError(const QString &message) const 0161 { 0162 if (message.startsWith("Error:")) 0163 return true; 0164 0165 return false; 0166 } 0167 0168 bool SDCC::isStderrOutputFatal(const QString &message) const 0169 { 0170 qCDebug(KTL_LOG) << "message=" << message; 0171 if (message.startsWith("Processor:")) 0172 return false; 0173 0174 return false; // note: return code from SDCC will tell if anything is fatal 0175 // return true; // 2017.06.18 - by default stderr messages are not fatal 0176 } 0177 0178 bool SDCC::isWarning(const QString &message) const 0179 { 0180 if (message.startsWith("Warning:")) 0181 return true; 0182 return false; 0183 } 0184 0185 ProcessOptions::ProcessPath::Path SDCC::outputPath(ProcessOptions::ProcessPath::Path inputPath) const 0186 { 0187 switch (inputPath) { 0188 case ProcessOptions::ProcessPath::C_AssemblyRelocatable: 0189 return ProcessOptions::ProcessPath::None; 0190 0191 case ProcessOptions::ProcessPath::C_Library: 0192 return ProcessOptions::ProcessPath::AssemblyRelocatable_Library; 0193 0194 case ProcessOptions::ProcessPath::C_Object: 0195 return ProcessOptions::ProcessPath::AssemblyRelocatable_Object; 0196 0197 case ProcessOptions::ProcessPath::C_PIC: 0198 return ProcessOptions::ProcessPath::AssemblyAbsolute_PIC; 0199 0200 case ProcessOptions::ProcessPath::C_Program: 0201 return ProcessOptions::ProcessPath::AssemblyRelocatable_Program; 0202 0203 case ProcessOptions::ProcessPath::AssemblyAbsolute_PIC: 0204 case ProcessOptions::ProcessPath::AssemblyAbsolute_Program: 0205 case ProcessOptions::ProcessPath::AssemblyRelocatable_Library: 0206 case ProcessOptions::ProcessPath::AssemblyRelocatable_Object: 0207 case ProcessOptions::ProcessPath::AssemblyRelocatable_PIC: 0208 case ProcessOptions::ProcessPath::AssemblyRelocatable_Program: 0209 case ProcessOptions::ProcessPath::FlowCode_AssemblyAbsolute: 0210 case ProcessOptions::ProcessPath::FlowCode_Microbe: 0211 case ProcessOptions::ProcessPath::FlowCode_PIC: 0212 case ProcessOptions::ProcessPath::FlowCode_Program: 0213 case ProcessOptions::ProcessPath::Microbe_AssemblyAbsolute: 0214 case ProcessOptions::ProcessPath::Microbe_PIC: 0215 case ProcessOptions::ProcessPath::Microbe_Program: 0216 case ProcessOptions::ProcessPath::Object_Disassembly: 0217 case ProcessOptions::ProcessPath::Object_Library: 0218 case ProcessOptions::ProcessPath::Object_PIC: 0219 case ProcessOptions::ProcessPath::Object_Program: 0220 case ProcessOptions::ProcessPath::PIC_AssemblyAbsolute: 0221 case ProcessOptions::ProcessPath::Program_Disassembly: 0222 case ProcessOptions::ProcessPath::Program_PIC: 0223 case ProcessOptions::ProcessPath::Invalid: 0224 case ProcessOptions::ProcessPath::None: 0225 return ProcessOptions::ProcessPath::Invalid; 0226 } 0227 0228 return ProcessOptions::ProcessPath::Invalid; 0229 }