zepete: (Default)
[personal profile] zepete

Раньше я писал, что внедрить свой скрипт в OPENWRT можно тремя способами: поместить файл в определенный каталог, создать пакет, который который будет выполнять этот скрипт при попытке установки этого пакета, или создать пакет, который будет, тупо, копировать файлы во flash маршрутизатора.

Теперь я придумал способ, как объединить два последних способа, то есть, что бы при компиляции с внедрением пакета в прошивку, файл со скриптом внедрялся в прошивку, а при компиляции без внедрения в прошивку, он исполнялся при установке.

Это можно сделать, просто, добавив текст скрипта в нужное место файла Makefile, но этот способ чреват расхождениями в выполнении скрипта при разных настройках сборщика, ибо последовательности команд берутся с разных мест.

Поэтому, для предотвращения рассогласования версий скриптов, я придумал более хитрый способ.

Способ основан на нескольких свойствах Makefile linux. Они описаны здесь.
Важные свойства мешающие и помогающие создавать многострочные переменные.
1. Секции define/endef, в которых пишется текст скрипта, являются простым объявлением переменной.
2. Между define и endef директивы Makefile не обрабатываются, а считаются значением переменной,
3. Объявление переменной при помощи define/endef - это единственный способ задания значения переменной включающей перевод строки.
4. Пустые строки между define и endef удаляются, что бы они остались, надо вставить хотябы один пробел в эти строки.
5. Для вызова внешних команд с получением результата ее работы в переменную, надо пользоваться конструкцией "variable:=$(shell execute_bash_command)", которая выполняет команду "execute_bash_command" и возвращает вывод этой команды в переменную "variable", заменив переводы строки на пробел.
6. Для замены подстрок в строке используется конструкция var_out:=$(subst find_string,replace_string,var_in), где var_in - исходная строка; var_out - результат работы; replace_string - на что будет заменяться найденный find_string.
7. Условия компиляции содержатся в переменной вида CONFIG_PACKAGE_NameOfMyPacket, где NameOfMyPacket - это имя пакета. Может иметь значение y - внедрение в прошивку или m - отдельная компиляция.
8. Переменные проверяются конструкциями вида ifeq|ifneq|ifdef|ifndef|else и завершающем endif.

Отсюда видно, что для построения пакета, изменять секцию define Package/NameOfMyPacket/install не надо, ибо если строится пакет с внедрением файла в прошивку, то она необходима, а если нет, то она не мешает, ибо несколько лишних килобайт компьютер не перегрузят.
А потребуется условно обрабатывать только секцию Package/NameOfMyPacket/preinst.
То есть она будет в первом приближении выглядеть так.

ifeq ($(CONFIG_PACKAGE_NameOfMyPacket),m) # выполняется только если задано создание пакета без внедрения в прошивку.
........................
........................
........................
........................
endif

Теперь необходимо в переменную Package/NameOfMyPacket/preinst занести текст из файла копируемого в прошивку при внедрении.
Это делать буду в четыре этапа.
1. Создал скрипт, который будет выводить на консоль содержимое файла, в котором переводы строки заменены на магическую строку символов и в конце вывода добавлена команда exit 1, которую потом можно будет заменить на другую в Makefile и помещу его в каталог с Makefile.

#!/bin/sh
#***********************************************************************
#*скрипт заменяющий перевод строки на !!!separator!!! и добавляющий    *
#*строку с командой "exit 1" в конец вывода, для предотвращения уста-  *
#*установки.                                                           *
#*Как запускать: gettextfile.sh <имя обрабатываемого файла>            *
#*Требуется для предотвращения конфликта скобок в Makefile             *
#*7 января 2014 года, zepete.livejournal.com                           *
#***********************************************************************
cat $1 | awk '{printf "%s!!!separator!!!",$0}\
END{printf "!!!separator!!!!!!separator!!!exit 1!!!separator!!!!!!separator!!!"}'

2. Вызвал этот скрипт из Makefile, воспользовавшись 5 свойством.
scripttext:=$(shell bash gettextfile.sh ./files/scriptfile.sh)
У меня уже в Makefile есть содержимое скрипта, но по пока без перевода строк.
3. Теперь в этот скрипт надо добавить переводы строки. Это можно сделать при помощи свойств 3,4 и 6. То есть сначала создать переменную содержащую перевод строки при помощи define/endef, а потом при помощи subst заменить !!!separator!!! на значение этой переменной. Дело осложняется тем, что в define/endef не могут быть одни переводы строки, поэтому туда я помещаю две легко разыскиваемые строки для последующего их удаления.
define linebreak
!!!end_of_line!!!
!!!begin_of_line!!!
endef

scripttext:=$(subst !!!separator!!!,$(linebreak),$(scripttext))

4. Для окончательного возвращения к исходному состоянию осталось только удалить маркеры конца и начала строки той же командой subst.

scripttext:=$(subst !!!begin_of_line!!!,,$(scripttext))
scripttext:=$(subst !!!end_of_line!!!,,$(scripttext))
Package/0-prepareflash/preinst:=$(scripttext)

В результате секция Package/NameOfMyPacket/preinst пришла к виду.

define linebreak
!!!end_of_line!!!
!!!begin_of_line!!!
endef

ifeq ($(CONFIG_PACKAGE_0-prepareflash),m)
scripttext:=$(shell bash gettextfile.sh ./files/prepareflash.sh)
scripttext:=$(subst !!!separator!!!,$(linebreak),$(scripttext))
scripttext:=$(subst !!!begin_of_line!!!,,$(scripttext))
scripttext:=$(subst !!!end_of_line!!!,,$(scripttext))
Package/0-prepareflash/preinst:=$(scripttext)
endif

Преобразовав таким образом скрипт для переноса /overlay и настройки сети, я получил два Makefile.


#************************************************************************
#* Скрипт автоматизирующий перенос /overlay (изменяемой части прошивки) *
#* на USB диск. Запускается командой "prepareflash.sh" с установленным  *
#* USB накопителем.                                                     *
#* 7 января 201я года, zepete.livejournal.com                           *
#************************************************************************

include $(TOPDIR)/rules.mk

# имя пакета, я добавил в начале "0-" для удобства навигации в катологе
# /package
# !!!ВНИМАНИЕ!!! имя пакета должно совпадать с именем директории,
# иначе будет возникать ошибка *** No rule to make target
PKG_NAME:=0-prepareflash
# версия пакета
PKG_VERSION:=1
# версия Makefile
PKG_RELEASE:=2
#на каких устройствах может запускаться
#PKGARCH:=all

include $(INCLUDE_DIR)/package.mk

#описание пакета для "make menuconfig"
#слово после '/' должно совпадать с PKG_NAME
define Package/0-prepareflash
#зарезервировано
SECTION:=1
#название меню, в котором будет находиться скрипт
CATEGORY:=my scripts
# какие пакеты необходимо установить дополнительно
# DEPENDS:=+
#краткое описание пакета, в конце необходимо добавить
# несколько пробелов для корректного отображения
# в make menuconfig
TITLE:=create extenal overlay
#к кому обращаться за помощью
MAINTAINER:=zepete
#адресс пакета в интернете
URL:=zepete.livejournal.com
# опция make menuconfig по умолчанию
# n - не компилировать
# m - компилировать
# y - компилировать и внедрять
DEFAULT:=y
endef



#подробное описание пакета
define Package/0-prepareflash/description
0-prepareflash delete all partition on /dev/sda,
make there swap partition size more 256K
and partition type ext2 on witch place /overlay.
For run need execute command line "prepareflash".
endef

#обязательный раздел
#без него будет возникать ошибка
# 'No targets specified and no makefile found'
#нужен для компиляции пакета из исходных кодов
define Build/Compile
endef

#обязательный и бесполезный раздел
# него будет возникать ошибка
# 'No targets specified and no makefile found'
define Build/Configure
endef


#скрипт bash без '#!/bin/sh' описывающий установку пакета,
# то есть какие файлы надо копировать
# !!!ВНИМАНИЕ!!! первым символом в строке должен быть ''
# пробел вызовет ошибку при компиляции: '*** missing separator'
define Package/0-prepareflash/install
#создание директории.
#Создавать директорию обязательно, иначе не смогут скопироваться файлы
# '$(INSTALLDIR)' - это псевдоним "install -d -m0755" (читать, писать и
# выполнять может хозяин, а все остальные только читать и писать
$(INSTALL_DIR) $(1)/sbin
# копирование файла
# копирование файлов по одному с заданными атрибутами
# '$(INSTALL_BIN)' - псевдоним для "install -m0755" (читать, писать и
# выполнять может хозяин, а все остальные только читать и писать)
# '$(INSTALL_DATA)' - псевдоним для "install -m0644" (хозяин может читать и
# изменять, а все остальные только читать
# '$(INSTALL_CONF)' - псевдоним для "install -m0600" (хозяин может читать и
#изменять, а все остальные не имеют прав.
$(INSTALL_BIN) ./files/prepareflash.sh $(1)/sbin/prepareflash.sh
#альтернативный способ копирования файлов группой сразу
# cp ./files/* $(1)/sbin
# chmod 755 *
endef

define linebreak
!!!end_of_line!!!
!!!begin_of_line!!!
endef

ifeq ($(CONFIG_PACKAGE_0-prepareflash),m)
scripttext:=$(shell bash gettextfile.sh ./files/prepareflash.sh)
scripttext:=$(subst !!!separator!!!,$(linebreak),$(scripttext))
scripttext:=$(subst !!!begin_of_line!!!,,$(scripttext))
scripttext:=$(subst !!!end_of_line!!!,,$(scripttext))
Package/0-prepareflash/preinst:=$(scripttext)
endif

$(eval $(call BuildPackage,0-prepareflash))


#************************************************************************
#* Скрипт автоматически настраивающий сеть                              *
#*                                                                      *
#*                                                                      *
#* 8 января 2014 года zepete.livejournal.com                            *
#************************************************************************

include $(TOPDIR)/rules.mk

# имя пакета, я добавил в начале "0-" для удобства навигации в катологе
# /package
# !!!ВНИМАНИЕ!!! имя пакета должно совпадать с именем директории,
# иначе будет возникать ошибка *** No rule to make target
PKG_NAME:=0-setupnetwork
# версия пакета
PKG_VERSION:=1
# версия Makefile
PKG_RELEASE:=2
#на каких устройствах может запускаться
#PKGARCH:=all

include $(INCLUDE_DIR)/package.mk

#описание пакета для "make menuconfig"
#слово после '/' должно совпадать с PKG_NAME
define Package/0-setupnetwork
#зарезервировано
 SECTION:=1
#название меню, в котором будет находиться скрипт
 CATEGORY:=my scripts
# какие пакеты необходимо установить дополнительно
#  DEPENDS:=+
#краткое описание пакета, в конце необходимо добавить
# несколько пробелов для корректного отображения
# в make menuconfig
 TITLE:=script for setup network interface
#к кому обращаться за помощью
 MAINTAINER:=zepete
#адресс пакета в интернете
 URL:=zepete.livejournal.com
# опция make menuconfig по умолчанию
# n - не компилировать
# m - компилировать
# y - компилировать и внедрять
 DEFAULT:=y
endef

 

#подробное описание пакета
define Package/0-setupnetwork/description
0-setupnetwork it is ash script for
search wifi AP, setup wlan0 on wifiAP how wan interface,
and configure rj45 how lan.
endef

#обязательный раздел
#без него будет возникать ошибка
# 'No targets specified and no makefile found'
#нужен для компиляции пакета из исходных кодов
define Build/Compile
endef
 
#обязательный и бесполезный раздел
# него будет возникать ошибка
# 'No targets specified and no makefile found'
define Build/Configure
endef


#скрипт bash без '#!/bin/sh' описывающий установку пакета,
# то есть какие файлы надо копировать
# !!!ВНИМАНИЕ!!! первым символом в строке должен быть '<tab>'
# пробел вызовет ошибку при компиляции: '*** missing separator'
define Package/0-setupnetwork/install
#создание директории.
#Создавать директорию обязательно, иначе не смогут скопироваться файлы
# '$(INSTALLDIR)' - это псевдоним "install -d -m0755" (читать, писать и
# выполнять может хозяин, а все остальные только читать и писать
 $(INSTALL_DIR) $(1)/sbin
# копирование файла
# копирование файлов по одному с заданными атрибутами
# '$(INSTALL_BIN)' - псевдоним для "install -m0755" (читать, писать и
# выполнять может хозяин, а все остальные только читать и писать)
# '$(INSTALL_DATA)' - псевдоним для "install -m0644" (хозяин может читать и
# изменять, а все остальные только читать
# '$(INSTALL_CONF)' - псевдоним для "install -m0600" (хозяин может читать и
#изменять, а все остальные не имеют прав.
 $(INSTALL_BIN) ./files/setupnetwork.sh $(1)/sbin/setupnetwork.sh
#альтернативный способ копирования файлов группой сразу
#  cp ./files/* $(1)/sbin
# chmod 755 *
endef

define linebreak
!!!end_of_line!!!
!!!begin_of_line!!!
endef

ifeq ($(CONFIG_PACKAGE_0-setupnetwork),m)
scripttext:=$(shell bash gettextfile.sh ./files/setupnetwork.sh)
scripttext:=$(subst !!!separator!!!,$(linebreak),$(scripttext))
scripttext:=$(subst !!!begin_of_line!!!,,$(scripttext))
scripttext:=$(subst !!!end_of_line!!!,,$(scripttext))
Package/0-setupnetwork/preinst:=$(scripttext)
endif

$(eval $(call BuildPackage,0-setupnetwork))


Profile

zepete: (Default)
zepete

January 2026

S M T W T F S
    1 23
4 56 78910
11121314151617
18192021222324
25262728293031

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 14th, 2026 02:08 pm
Powered by Dreamwidth Studios