📄 expmfile.cpp
字号:
/**************************************************************************
Project: WinAVRIDE Class: Makefile Export
Copyright (C) 2005 Philipp Schober
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
History
19.Feb 2005 - First Release (V1.0)
****************************************************************************/
#include <vcl.h>
#include "OptionsDlg.h"
#include "DirDialog.h"
#pragma hdrstop
#include "ExpMFile.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
//---------------------------------------------------------------------------
bool __fastcall TExpMFile::Export (AnsiString fname, AnsiString prj,
TStringList *clist, TStringList *hlist)
{
TFileStream *stream;
TStringList *deplist;
AnsiString temp, t;
int i, h, d;
stream = new TFileStream (fname, fmCreate);
temp = "#makefile exported from WINAVRIDE\r\n";
temp += "#Projekt File : " + prj + "\r\n\r\n";
stream->Write (temp.c_str (), temp.Length ());
// --------------------- Misc Definitions ---------------------
temp = "#Misc Definitions\r\n";
temp += "OBJ =";
for (i = 0;i < clist->Count;i++)
{
temp += " " + SlashConvert (ChangeExt (clist->Strings[i], ".o"));
}
temp += "\r\n";
temp += "TARGET = " + SlashConvert (OptDlg->OutputName) + "\r\n";
stream->Write (temp.c_str (), temp.Length ());
temp = "CC = avr-gcc\r\nOBJCOPY = avr-objcopy\r\nOBJDUMP = avr-objdump\r\n";
temp += "SIZE = avr-size\r\nREMOVE = rm\r\nNM = avr-nm\r\n\r\n";
stream->Write (temp.c_str (), temp.Length ());
// --------------------- Compiler Flags ---------------------
temp = "#Compiler Options\r\n";
temp += "CFLAGS = -mmcu=" + OptDlg->options.MCUType + "\r\n";
t = DirDlg->Inc_Dir;
while (t != NULL)
{
i = t.Pos (";");
if (i == 0)
{
temp += "CFLAGS += -I" + t + "\r\n";
break;
}
else temp += "CFLAGS += -I" + t.SubString (1, i - 1) + "\r\n";
t.Delete (1, i);
}
stream->Write (temp.c_str (), temp.Length ());
switch (OptDlg->options.OptimBox)
{
case 0: temp = "CFLAGS += -O0";
break;
case 1: temp = "CFLAGS += -O1";
break;
case 2: temp = "CFLAGS += -O2";
break;
case 3: temp = "CFLAGS += -O3";
break;
case 4: temp = "CFLAGS += -Os";
break;
}
switch (OptDlg->options.DbgGroup)
{
case 1:
case 2:
case 3: temp += " -gstabs\r\n";
break;
case 4: temp += " -gdwarf-2\r\n";
break;
default: temp += "\r\n";
}
stream->Write (temp.c_str (), temp.Length ());
switch (OptDlg->options.StdGroup)
{
case 0: temp = "CFLAGS += -std=c89\r\n";
break;
case 1: temp = "CFLAGS += -std=gnu89\r\n";
break;
case 2: temp = "CFLAGS += -std=c99\r\n";
break;
default: temp = "CFLAGS += -std=gnu99\r\n";
}
if (OptDlg->options.NoWarn)
{
temp += "CFLAGS += -fsyntax-only\r\n";
}
else
{
if (OptDlg->options.AllWarn) temp += "CFLAGS += -W\r\n";
else
{
if (OptDlg->options.PartWarn) temp += "CFLAGS += -Wall\r\n";
else
{
if (OptDlg->options.PedaWarn) temp += "CFLAGS += -pedantic\r\n";
if (OptDlg->options.NoImpWarn) temp += "CFLAGS += -Wno-import\r\n";
if (OptDlg->options.CharSubsWarn) temp += "CFLAGS += -Wchar-subscripts\r\n";
if (OptDlg->options.ComWarn) temp += "CFLAGS += -Wcomment\r\n";
if (OptDlg->options.FormWarn) temp += "CFLAGS += -Wformat\r\n";
if (OptDlg->options.ImplWarn) temp += "CFLAGS += -Wimplicit\r\n";
if (OptDlg->options.BracWarn) temp += "CFLAGS += -Wmissing-braces\r\n";
if (OptDlg->options.ParWarn) temp += "CFLAGS += -Wparentheses\r\n";
if (OptDlg->options.RetTypWarn) temp += "CFLAGS += -Wreturn-type\r\n";
if (OptDlg->options.SwitchWarn) temp += "CFLAGS += -Wswitch\r\n";
if (OptDlg->options.SwiDefWarn) temp += "CFLAGS += -Wswitch-default\r\n";
if (OptDlg->options.UnusWarn) temp += "CFLAGS += -Wunused\r\n";
if (OptDlg->options.UninitWarn) temp += "CFLAGS += -Wuninitialized\r\n";
if (OptDlg->options.PragWarn) temp += "CFLAGS += -Wunknown-pragmas\r\n";
}
if (OptDlg->options.SysHeadWarn) temp += "CFLAGS += -Wsystem-headers\r\n";
if (OptDlg->options.UndefWarn) temp += "CFLAGS += -Wundef\r\n";
if (OptDlg->options.EndifWarn) temp += "CFLAGS += -Wendif-labels\r\n";
if (OptDlg->options.ProtWarn) temp += "CFLAGS += -Wstrict-prototypes\r\n";
if (OptDlg->options.NestWarn) temp += "CFLAGS += -Wnested-externs\r\n";
if (OptDlg->options.InlineWarn) temp += "CFLAGS += -Winline\r\n";
if (OptDlg->options.UnreaWarn) temp += "CFLAGS += -Wunreachable-code\r\n";
}
}
if (OptDlg->options.TinyStack) temp += "CFLAGS += -mtiny-stack\r\n";
if (OptDlg->options.GenList) temp += "CFLAGS += -Wa,-ahlms=$(<:.c=.lst)\r\n";
if (OptDlg->options.AddComp != "") temp += "CFLAGS += " +
OptDlg->options.AddComp + "\r\n";
stream->Write (temp.c_str (), temp.Length ());
// ----------------------- Linker Flags --------------------------
temp = "\r\n#Linker Options\r\n";
temp += "LDFLAGS = -mmcu=" + OptDlg->options.MCUType + "\r\n";
if (OptDlg->options.GenMap)
{
temp += "LDFLAGS += -Wl,-Map=$(TARGET).map";
if (OptDlg->options.CRef) temp += ",--cref";
temp += "\r\n";
}
if (OptDlg->options.MathBox) temp += "LDFLAGS += -lm\r\n";
if (OptDlg->options.prntGroup != 0)
{
if (OptDlg->options.prntGroup == 2) temp += "LDFLAGS += -Wl,-u,vfprintf -lprintf_flt\r\n";
else temp += "LDFLAGS = -Wl,-u,vfprintf -lprintf_min\r\n";
}
if (OptDlg->options.scnGroup != 0)
{
if (OptDlg->options.scnGroup == 2) temp += "LDFLAGS = -Wl,-u,vfscanf -lscanf_flt\r\n";
else temp += "LDFLAGS = -Wl,-u,vfscanf -lscanf_min\r\n";
}
t.printf ("LDFLAGS += -Wl,-Tdata=0x%x\r\n", OptDlg->DataStart);
if (OptDlg->RelocData) temp += t;
t.printf ("LDFLAGS += -Wl,--defsym=__heap_end=0x%x\r\n", OptDlg->HeapEnd);
if (OptDlg->DefHeapEnd) temp += t;
t.printf ("LDFLAGS += -Wl,--defsym=__heap_start=0x%x\r\n", OptDlg->HeapStart);
if (OptDlg->DefHeapStart) temp += t;
if (OptDlg->options.AddLink != "") temp += "LDFLAGS += " +
OptDlg->options.AddLink += "\r\n";
temp += "\r\n";
stream->Write (temp.c_str (), temp.Length ());
// ------------------- Generating Main Rules ---------------------
temp = "build: begin";
if (OptDlg->options.OutputFormat == "srec") temp += " $(TARGET).src";
else if (OptDlg->options.OutputFormat == "binary") temp += " $(TARGET).bin";
else temp += " $(TARGET).hex";
if (OptDlg->options.GenEEPROM) temp += " $(TARGET).eep";
if (OptDlg->options.DbgGroup == 2 || OptDlg->options.DbgGroup == 3) temp += " $(TARGET).cof";
if (OptDlg->options.ExtLst) temp += " $(TARGET).lss";
if (OptDlg->options.SymTab) temp += " $(TARGET).sym";
temp += " showsize end\r\n";
temp += "showsize:\r\n\t@echo\r\n\t$(SIZE) -A $(TARGET).elf\r\n";
temp += "begin:\r\n\t@echo ----------- begin -----------\r\n\t@echo\r\n";
temp += "end:\r\n\t@echo\r\n\t@echo ------------ end ------------\r\n\r\n";
stream->Write (temp.c_str (), temp.Length ());
// ------------- Generating Hex/Bin File -----------------------
temp = "#Rule for generating Hex/Bin File\r\n";
if (OptDlg->options.OutputFormat == "srec") temp += "$(TARGET).src:";
else if (OptDlg->options.OutputFormat == "binary") temp += "$(TARGET).bin:";
else temp += "$(TARGET).hex:";
temp += "$(TARGET).elf\r\n";
temp += "\t@echo\r\n\t@echo Generating Hex/Bin File\r\n";
temp += "\t$(OBJCOPY) -O " + OptDlg->options.OutputFormat + " ";
temp += "$(TARGET).elf $(TARGET)";
if (OptDlg->options.OutputFormat == "srec") temp += ".src\r\n\r\n";
else if (OptDlg->options.OutputFormat == "binary") temp += ".bin\r\n\r\n";
else temp += ".hex\r\n\r\n";
stream->Write (temp.c_str (), temp.Length ());
// ------------------ Generating EEPROM File -------------------
if (OptDlg->options.GenEEPROM)
{
temp = "#Rule for generating EEPROM File\r\n";
temp += "$(TARGET).eep:$(TARGET).elf\r\n";
temp += "\t@echo\r\n\t@echo Generating EEPROM File\r\n";
temp += "\t$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom=\"alloc,load\" \\\r\n";
temp += "\t-O " + OptDlg->options.OutputFormat;
temp += " $(TARGET).elf \\\r\n\t$(TARGET).eep\r\n\r\n";
stream->Write (temp.c_str (), temp.Length ());
}
// ----------------- Generating (Ext)COFF Output ---------------
if (OptDlg->options.DbgGroup == 2 || OptDlg->options.DbgGroup == 3)
{
temp = "#Rule for generating (Ext)COFF File\r\n";
temp += "$(TARGET).cof:$(TARGET).elf\r\n";
temp += "\t@echo\r\n\t@echo Generating COFF File\r\n";
temp += "\t$(OBJCOPY) --debugging --change-section-address .data-0x800000 \\\r\n";
temp += "\t--change-section-address .bss-0x800000 \\\r\n";
temp += "\t--change-section-address .noinit-0x800000 \\\r\n";
temp += "\t--change-section-address .eeprom-0x810000 \\\r\n";
if (OptDlg->options.DbgGroup == 2) temp += "\t-O coff-avr ";
else temp += "\t-O coff-ext-avr ";
temp += "$(TARGET).elf $(TARGET).cof\r\n\r\n";
stream->Write (temp.c_str (), temp.Length ());
}
// ----------------- Generating Extended Listing ---------------
if (OptDlg->options.ExtLst)
{
temp = "#Rule for generating Extended Listing File\r\n";
temp += "$(TARGET).lss:$(TARGET).elf\r\n";
temp += "\t@echo\r\n\t@echo Generating Extended Listing File\r\n";
temp += "\t$(OBJDUMP) -h -S $(TARGET).elf > $(TARGET).lss\r\n\r\n";
stream->Write (temp.c_str (), temp.Length ());
}
// ------------------- Generating Symbol Table -----------------
if (OptDlg->options.SymTab)
{
temp = "#Rule for generating Symbol Table\r\n";
temp += "$(TARGET).sym:$(TARGET).elf\r\n";
temp += "\t@echo\r\n\t@echo Generating Symbol Table\r\n";
temp += "\t$(NM) -n $(TARGET).elf > $(TARGET).sym\r\n\r\n";
stream->Write (temp.c_str (), temp.Length ());
}
// -------------------- Generating ELF File --------------------
temp = "#Rule for generating ELF File\r\n";
temp += "$(TARGET).elf:$(OBJ)\r\n";
temp += "\t@echo\r\n\t@echo Linking : " + ExtractFileName (OptDlg->OutputName) + "\r\n";
temp += "\t$(CC) -o $(TARGET).elf $(OBJ) $(LDFLAGS)\r\n\r\n";
temp += "#Rules for generating Object Files\r\n";
stream->Write (temp.c_str (), temp.Length ());
// ------------------- Generating Object Files ----------------
for (i = 0;i < clist->Count;i++)
{
temp = SlashConvert (ChangeExt (clist->Strings[i], ".o")) + ":";
temp += SlashConvert (clist->Strings[i]);
for (h = 0;h < hlist->Count;h++) // Get Dependencies
{
deplist = (TStringList *)hlist->Objects[h];
for (d = 0;d < deplist->Count;d++)
{
if (deplist->Strings[d] == clist->Strings[i])
{
temp += " " + SlashConvert (hlist->Strings[h]);
}
}
}
temp += "\r\n";
temp += "\t@echo\r\n\t@echo Compiling : " + ExtractFileName (clist->Strings[i]) + "\r\n";
temp += "\t$(CC) -c " + SlashConvert (clist->Strings[i]) + " $(CFLAGS)\r\n";
if (OptDlg->options.SaveTempBox)
{
temp += "\t$(CC) -S " + SlashConvert (clist->Strings[i]) + " $(CFLAGS) -save-temps\r\n";
}
temp += "\r\n";
stream->Write (temp.c_str (), temp.Length ());
}
// ---------------------- Cleaning Rule -----------------------
temp = "#Cleaning Rule\r\n";
temp += "clean:\r\n\t@echo Cleaning...\r\n\t$(REMOVE) $(OBJ)\r\n";
temp += "\t$(REMOVE) $(TARGET).elf\r\n";
if (OptDlg->options.DbgGroup == 2 || OptDlg->options.DbgGroup == 3) temp += "\t$(REMOVE) $(TARGET).cof\r\n";
if (OptDlg->options.GenMap) temp += "\t$(REMOVE) $(TARGET).map\r\n";
if (OptDlg->options.OutputFormat == "srec") temp += "\t$(REMOVE) $(TARGET).src\r\n";
else if (OptDlg->options.OutputFormat == "binary") temp += "\t$(REMOVE) $(TARGET).bin\r\n";
else temp += "\t$(REMOVE) $(TARGET).hex\r\n";
if (OptDlg->options.GenEEPROM) temp += "\t$(REMOVE) $(TARGET).eep\r\n";
if (OptDlg->options.GenList) temp += "\t$(REMOVE) $(OBJ:.o=.lst)\r\n";
if (OptDlg->options.SaveTempBox)
{
temp += "\t$(REMOVE) $(OBJ:.o=.i)\r\n";
temp += "\t$(REMOVE) $(OBJ:.o=.s)\r\n";
}
if (OptDlg->options.ExtLst) temp += "\t$(REMOVE) $(TARGET).lss\r\n";
if (OptDlg->options.SymTab) temp += "\t$(REMOVE) $(TARGET).sym\r\n";
stream->Write (temp.c_str (), temp.Length ());
delete stream;
return true;
}
//---------------------------------------------------------------------------
AnsiString __fastcall TExpMFile::ChangeExt (AnsiString Source, AnsiString ext)
{
AnsiString obj;
obj = Source;
obj.Delete (obj.Pos (ExtractFileExt (obj)), 3);
obj += ext;
return obj;
}
//---------------------------------------------------------------------------
AnsiString __fastcall TExpMFile::SlashConvert (AnsiString src)
{
int i;
for (i = 1;i < src.Length () + 1;i++)
{
if (src[i] == '\\') src[i] = '/';
}
return src;
}
//---------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -