Системы сборки программ

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Системы сборки программ

Сообщение Vooon » 25 фев 2008, 17:16

недавно открыл для себя SCons
и был приятно удивлен на сколько просто собирается моя прога
и на сколько проще его скрипт по сравнению с мейковским:

мой Makefile (в котором я уже боюсь трогать тело т.к. уже не помню что зачем :oops: ):
Код: Выделить всё
# Output files name (no extension)
target      :=   main
# CPU Core freq (in Hz)
f_cpu      :=   14745600UL
# Chip
mcu         :=   atmega8
# Sourcess dirs
srcdirs      :=   . lcd wake
# compiler
cc         :=   avr-gcc
# size
size      :=   avr-size
# objcopy
objcopy      :=   avr-objcopy
# objdump
objdump      :=   avr-objdump
# compiler flags
ccflags      :=   -Wall -x c++ -g -Os -DF_CPU=$(f_cpu) -mmcu=$(mcu)
# linker flags
ldflags      :=   --relax -Wl -g -mmcu=$(mcu)
# compiler and linker log
cclog      :=   cc.log
# doxygen log
doxlog      :=   dox.log
# doxygen output dir
doxdir      :=   ./doc
# programmer comand (full comand)
programmer   :=   uisp -dprog=abb -dlpt=/dev/parport0 --erase --upload --verify if=./$(addsuffix .hex,$(target))
# setings out file
settings   :=   setings.h
# project configuration file
conf      :=   project.xml

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

rm         :=   rm -rf
doxygen      :=   doxygen
VPATH      :=   $(srcdirs)
search      :=   $(addsuffix /*.cpp,$(srcdirs))
cog         :=   cog.py -cr -I cogpy -D xmlconf=$(conf) $(addprefix -I,$(srcdirs))      \
            $(wildcard $(addsuffix /*.cpp,$(srcdirs)))                        \
            $(wildcard $(addsuffix /*.h,$(srcdirs)))

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

all: cleanlog hex lst

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

# parse python generatogs (cogging files)
cog:
   @ehco " * Cogging files:"
   $(cog)

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

# create elf
elf: $(addsuffix .elf,$(target))
$(addsuffix .elf,$(target)): $(notdir $(patsubst %.cpp,%.o, $(wildcard $(search))))
   @echo " * Create output elf file:"
   $(cc) $(ldflags) $^ -o $(addsuffix .elf,$(target)) 2>>$(cclog)

# create hex
hex: $(addsuffix .hex,$(target))
$(addsuffix .hex,$(target)): elf
   @echo " * Create hex from elf:"
   -$(objcopy) -R.eeprom -O ihex $(addsuffix .elf,$(target)) $(addsuffix .hex,$(target)) 2>>$(cclog)

# create eep
eep: $(addsuffix .eep,$(target))
$(addsuffix .eep,$(target)): elf
   @echo " * Create eep from elf:"
   -$(objcopy) -j.eeprom --set-section-flags .eeprom="alloc,load"            \
   --change-section-lma .eeprom=0 --no-change-warnings -O ihex               \
   $(addsuffix .elf,$(target)) $(addsuffix .eep,$(target)) 2>>$(cclog)

# create lst
lst: $(addsuffix .lst,$(target))
$(addsuffix .lst,$(target)): elf
   @echo " * Create lst from elf:"
   $(objdump) -S $(addsuffix .elf,$(target)) > $(addsuffix .lst,$(target)) 2>>$(cclog)

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

# create coff file
coffconv   :=   $(objcopy) --debugging --change-section-address .data-0x800000   \
            --change-section-address .bss-0x800000                     \
            --change-section-address .noinit-0x800000                  \
            --change-section-address .eeprom-0x810000

coff: elf
   @echo " * Create cof from elf:"
   $(coffconv) -O coff-avr $(addsuffix .elf,$(target)) $(addsuffix .cof,$(target)) 2>>$(cclog)
extcoff: elf
   @echo " * Create extended cof from elf:"
   $(coffconv) -O coff-ext-avr $(addsuffix .elf,$(target)) $(addsuffix .cof,$(target)) 2>>$(cclog)

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

# create o file
%.o: %.cpp
   $(cc) $(ccflags) $(addprefix -I,$(srcdirs)) -MD -c  $< 2>>$(cclog)


#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

# create doxygen documentation
dox:
   @echo " * Create documentation:"
   $(rm) $(doxylog)
#    $(cog) Doxyfile
   $(doxygen) 2>> $(doxylog)

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

program:
   @echo " * Programming the chip:"
   $(programmer)

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

size:
   @echo " * Proramm size:"
   $(size) --mcu=$(mcu) --format=avr $(addsuffix .elf,$(target))
#   $(size) $(addsuffix .elf,$(target))

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

garbage:
   @echo " * Garbage collection:"
   $(rm) $(wildcard *.d) $(wildcard *.o) $(cclog) $(doxlog)
cleanlog:
   @echo " * Cleaning log files:"
   echo 'Compiller & Linker log:' > $(cclog)
   echo 'Doxygen log:' > $(doxlog)

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

clean:
   @echo " * Clean:"
   $(rm) $(wildcard *.elf) $(wildcard *.hex) $(wildcard *.d) $(wildcard *.o)   \
   $(wildcard *.lst) $(cclog) $(doxlog)
deepclean:
   @echo " * Deep clean:"
   $(rm) $(wildcard *.elf) $(wildcard *.hex) $(wildcard *.d) $(wildcard *.o)   \
   $(wildcard *.lst) $(cclog) $(doxlog) $(doxdir)
#    $(cog) -x

#-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -

include $(wildcard *.d)


и SConstruct:
Код: Выделить всё
# settings
mcu = "atmega8"
f_cpu = "14745600UL"

# flags
ccflags = "-Wall -x c++ -g -Os -DF_CPU=%(f_cpu)s -mmcu=%(mcu)s"%locals()
ldflags = "--relax -Wl -g -mmcu=%(mcu)s"%locals()

# avr tools
cc = "avr-gcc"
ranlib = "avr-ranlib"
ar = "avr-ar"

lenv = Environment(CXX=cc, AR=ar, RANLIB=ranlib, CCFLAGS=ccflags, LINKFLAGS=ldflags)
penv = Environment(CXX=cc, CCFLAGS=ccflags, LINKFLAGS=ldflags, LIBPATH='.')

# lib's
lenv.Library("wake",   ["wake/wake.cpp"])
lenv.Library("pid",    ["pid/pid.cpp"])
lenv.Library("lcd",    ["lcd/lcd.cpp"])

penv.Program("main.elf",   ["main.cpp"], LIBS=["wake", "pid", "lcd"])

# TODO cmd's: elf2hex, program, doxygen


осталось только дописать вызов avr-objdump'a и программатора
(вобще собираюсь сделать хранение параметров проекта в xml-файле,
да и гуй можно сделать, Qt4 очень удобна, и есть PyQt4,
т.к. scons полностью написан на питоне и его сборочные скрипты тоже :) )

а что используете вы? (или пользуетесь иде с авто-сборкой?)
Последний раз редактировалось Vooon 25 фев 2008, 17:51, всего редактировалось 1 раз.
Причина: SConstruct updated
Linux user | Firefox user
Аватара пользователя
Vooon
Site Admin
 
Сообщения: 3339
Зарегистрирован: 09 фев 2006, 15:36
Откуда: Москва
Skype: vooon341
прог. языки: Python, C, Bash, JavaScript, C++, PHP
ФИО: Владимир Ермаков

Re: Системы сборки программ

Сообщение Digit » 25 фев 2008, 19:15

...э-э... я как на другой планете побывал :)
Пользуюсь CV_AVR
злой полицейский
Аватара пользователя
Digit
 
Сообщения: 3339
Зарегистрирован: 27 ноя 2004, 00:42
Откуда: совсем Москва
ФИО: Григорий

Re: Системы сборки программ

Сообщение Сергей » 27 фев 2008, 23:53

Я всегда юзал обычный Make, makefilы собирал с помощью гугла и книжек, вообще удобно, не сказать что уж очень сложно. Автосборку не юзал
Сергей
 
Сообщения: 3744
Зарегистрирован: 29 дек 2004, 23:15
Откуда: Санкт-Петербург
прог. языки: C, C++, C#, Asm
ФИО: Кашликов Сергей

Re: Системы сборки программ

Сообщение Vooon » 28 фев 2008, 09:46

Переписал - теперь еще удобнее пользовать, если кому нужен шаблон проекта могу прицепить :)

/
  • bin
  • build
    • scons
      • avr.py
      • avrprog.py
      • doxygen.py
    • SConscript.avr
    • Doxyfile
  • doc
  • obj
  • src
    • main
      • main.h
      • main.cpp
      • SConscript
    • mlib
      • source.h
      • source.cpp
      • SConscript

SConscript:
Код: Выделить всё
def get_svn_revision(path='.'):
   rev = None
   if path is None:
      path = __name__.__path__[0]
   entries_path = '%s/.svn/entries' % path
   import os, re
   if os.path.exists(entries_path):
      entries = open(entries_path, 'r').read()
      # Versions >= 7 of the entries file are flat text.  The first line is
      # the version number. The next set of digits after 'dir' is the revision.
      if re.match('(\d+)', entries):
         rev_match = re.search('\d+\s+dir\s+(\d+)', entries)
         if rev_match:
            rev = rev_match.groups()[0]
   return rev or 0

project_name = "Station"
major,minor,revision,svn_rev = 0,0,1,get_svn_revision()

# initialize options
opts = Options("custom.py")
avrEnv = Environment( toolpath=["build/scons"] ,
   DOXY_VERSION="%s.%s.%s SVN %s"%(major,minor,revision,svn_rev))

# include avr setup script, but do not change dir
SConscriptChdir(0)
SConscript("build/SConscript.avr", exports="avrEnv opts" )
SConscriptChdir(1)

Help(opts.GenerateHelpText(avrEnv))

Export("avrEnv")

# Include all needed modules, collect build files
module = "main"
use_libs = ["mlib"]
use_components = [module]
objs = []
libs = []
for component in use_components:
    o = avrEnv.SConscript("${SRCDIR}/%s/SConscript" % component, build_dir="$OBJDIR/"+module+"/%s" % component, duplicate=0)
    objs.extend(o)

for lib in use_libs:
    o = avrEnv.SConscript("${SRCDIR}/%s/SConscript" % lib, build_dir="$OBJDIR/" + lib, duplicate=0)
    libs.append(avrEnv.Library("${BINDIR}/" + lib, o))

wake_info = "%s;v:%s.%s.%s;svn:%s"%(project_name,major,minor,revision,svn_rev)
avrEnv.Append(CCFLAGS = " -DWAKE_INFO_STR=\"\\\"%s\\\"\" -DWAKE_INFO_LEN=%s"%(wake_info,len(wake_info)+1))

# Build main program (default)
prog = avrEnv.Program("${BINDIR}/" + module, objs, LIBS=libs)
hex_ = avrEnv.HexObject("${BINDIR}/" + module, prog)
eep  = avrEnv.EepObject("${BINDIR}/" + module, prog)
lst  = avrEnv.Listing("${BINDIR}/" + module, prog)
Default(prog, hex_, lst)

# Install Targets
isp = avrEnv.Upload("install", hex)
Alias("program", lst)

doc = avrEnv.Doxygen("build/Doxyfile")
Alias("doxygen", doc)


SConscript.avr:
Код: Выделить всё
# SCons script to setup AVR build environment
Import("avrEnv opts")

# set up environment
t = Tool("avr", avrEnv["toolpath"])
t(avrEnv)
p = Tool("avrprog", avrEnv["toolpath"])
p(avrEnv)
d = Tool("doxygen", avrEnv["toolpath"])
d(avrEnv)

# initialize default options
opts.Add( "MCU", "Target architecture", "atmega8" )
opts.Add( "F_CPU", "Target CPU Freq", "14745600UL" )
opts.Add( "WARNLEVEL", "Warning level", "-Wall" )
opts.Add( "AVRPROGDEV", "AVR programming device", "/dev/parport0" )
opts.Add( EnumOption("AVRFORMAT", "Output file format", "ihex", allowed_values=('ihex','srec')) )
opts.Add( PathOption("OBJDIR", "Temporary build path", "obj", PathOption.PathIsDirCreate) )
opts.Add( PathOption("SRCDIR", "Source directory", "src") )
opts.Add( PathOption("BINDIR", "Binary output directory", "bin") )

opts.Update(avrEnv)

Return("avrEnv")


SConscript:
Код: Выделить всё
Import("avrEnv")

objs = [
   avrEnv.Object("source.cpp"),
   ]

Return("objs")
Linux user | Firefox user
Аватара пользователя
Vooon
Site Admin
 
Сообщения: 3339
Зарегистрирован: 09 фев 2006, 15:36
Откуда: Москва
Skype: vooon341
прог. языки: Python, C, Bash, JavaScript, C++, PHP
ФИО: Владимир Ермаков


Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot], Yandex [Bot] и гости: 15