Отговори на тема  [ 34 мнения ]  Отиди на страница Предишна  1, 2, 3
Управление на изходен код 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Управление на изходен код
Хм, конфигуриране без условия - това ще ми е интересно да го видя. Нали думата идва да каже че правиш конфигурация, или по-точно че я прилагаш. Как да го направиш без да имаш конфигурация?
Принципно, конфигуриране е някакъв вид промяна на нещо - нещо темплейтно да стане нещо конкретно. Съответно всяко парче данни (например файл) може първо да се опише с някакви "параметри", т.е. полета за конкретизиране, и не може да се ползва преди към него да се приложи конкретна стойност на параметрите. Конфигурацията е конкретизация на всички тия параметри. Ама исках да кажа, че може и да нямаш явно конфигуриране. Но ако имаш такова, не можеш да минеш нататък без да изпълниш стъпката конфигуриране, която искат темплейт и конфигурация, и вади нещото за следващата стъпка.
За да нямаш стъпката конфигуриране, трябва да ползваш вече конкретизирани "файлове" и други зависимости - т.е. да си изградиш изолирано обкръжение, в което си конкретизирал (контейнер, виртуалка, физическа машина). Само че това значи да "вградиш" всичко при теб - т.е. в репото ти да има компилатора, библиотеки и всичко друго, чак до това да не ползваш нищо от ОС-а. Ако не съм сложил път до компилатора, а само "arm-none-eabi-gcc", нищо не си изолирал - на тая система може да има друга версия и да направя некоректен билд.
Тука пак ще бодна една аналогия с функционалното програмиране - процесът (стъпката, функцията) се привежда във форма с един аргумент - т.е. стъпката казва "дай ми сорса, нищо друго, аз съм конкретизирана и знам с кой компилатор, с какви опции и т.н. да викам". Тая функция не е каквото знаем ние в C - тя е динамично изчиследна такава, създадена и получена като резултат от викане на конструираща функция (функтор) или нещо подобно. За нашите цели - това е скрипт, който получава компилатор, променливи, и т.н. и "връща" обкръжение, в което тия неща са константи.
В случая с процесите/компилатори и т.н., това значи да си конкретизирал едно обкръжение, в което $CC примерно вече е ясно, има стойност и съм се погрижил да е вярното. Сорсът не му пука как и какво съм сложил там. Ако сорса казва - "може и така, може и иначе да ме билднеш", т.е. с една или друга стойност на променлива на обкръжението, която примерно влиза като преддефиниран символ, то значи че не сме стигнали още до формата с един аргумент (два са - сорса и символа). Трябва да минем през конфигуриране, което от предходния, недовършен (темплейтен) environment да конкретизира че CFLASG трябва да има нещо заредено, и така тоя новия става "environment с един вход/аргумент" - само сорса е променлив.
Хитрото е че така конфигурацията отива на отделна стъпка в билд процеса - нейната промяна води до еднократно ребилдване (конкретизиране) на обкръжението (контейнера, виртуалката) и после това се ползва директно. Смяната на сорса (c,h) не тригерира тоя процес - обкръжението няма вход "c/h", има само "cfg" (примерно) - нов сорс код води до изпълнение на билд процеса (компилирането) във вече подготвения environment.

Не казвам че говоря нови неща - това се е случвало и така работят всички смислени билд процеси. Просто съм на тази тема в момента и се боря. Опитвам се да изчистя погледа върху тия процеси и да се търси общото в различните стъпки. В CI нещата са принципно същите, с тая разлика че не се допускат ръчни стъпки - всичко трябва да е описано като артифакти (файлове, на репота) и всяка промяна в репо трябва автоматично да предизвика промените нататък по веригата. Т.е. да е "жива" система, реагираща сама на всяка промяна.
Само с гит/свн това е трудно да се постигне - за да стане тая "живина" трябва да се движи от някого, и там единствения шанс са hook-овете към репозиторитата. Това, което може да се улесни, е тия hook-ове да се движат от някой отгоре - инструмент, система, за да се избегне повторението, т.е. копи-пеист. И да има някакъв приятен начин цялата информация за връзките да може да се поиска, да се визуализира и после да се редактира. Това правят всичките CI.
Разликите са в подходите им - едни дават инструменти на съвсем ниско ниво, и ти си свободен да закачаш което както искаш, вкл. и неправилно - няма критерий, по който системата да ти каже "това е неправилно, щото прилича на двупосочна зависимост". Други стъпват по-нагоре и питат "какви са ти зависимостите - дай ми кой други пакети (проекти) ти трябват - примерно ексето казва трябва ми либмиро.а@1.0, и грижата за връзката остави на мен". Т.е. декларативно описваш зависимостите и не се интересуваш някой дали не е променил url-а на репото на libusb. Това е важно да е така, когато от системата ще искаш да оптимизира работата - да пуска паралелно билдове, да прехвърля билдовете по много разпределени нодове (билд сървъри), да не допуска билда на екзето да мине с предишната версия на либмиро, щото библиотеката е билдната по-късно и т.н. Или защото вече я има билдата в подходяща вариант (конфигурация), и е безсмислено пак да се билдва.


Вто Апр 28, 2020 8:00 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 1:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Управление на изходен код
gicho написа:
Zdrav написа:
Факт е че понеже git няма концепция за папки и структури от папки, при git всички сорсове от едно репозитори също "отиват" в "общ кюп". Ползването на референции към други репозиторита е препратка към други "общи кюпове".

Това е спорно - на гит можеш да сложиш и папка, и файл, и цяло дърво. ...

Споровете между различни религии са безсмислени :D И в случая гледано от вън - да наистина можеш да "сложиш" папка и цяло дърво. Но гледано от вътре, от начина по който е организиран git отвътре, дървото от папки не се ползва така както се ползва във файловата система отвън. Предполагам всеки който е ползвал git се е чесал по врата, защо не може да "сложи" в репото празна папка. Всъщност спорното изречение беше част от доста по-дълъг пост, но имам навика да изрязвам излишно дългите обяснения преди да постна и след самоцензурата остана само това.
Основната идея беше, че използването на файловата система такава каквато е замислена още от зората на електронно изчислителните машини в днешно време налага мисловни модели, които пречат. Опитите да се решат новите проблеми със старите "номера на кучето" налагат ограничения. Едно от тези ограничения е използването на дърво от папки за структуриране на сорсовете в една софтуерна система. Но рискувам да влезем във философско-религиозна тематика ако продължа...

Всъщност, както се оказа по-късно, говорили сме за различни неща.

Миро, това което описваш е напълно нормално(ако изключим факта, че един човек трябва да подъжа над 100 проекта). Няма да е истина ако кажа че не се използва и не работи. Всеки е ползвал подобна организация на сорсовете и билда. При AUTOSAR така е организирана имплементацията на т.нар. Basic Software (BsW). Там са например комуникационните стекове. Наблюденията ми са от две различни имплементации на BsW и двете развити независимо една от друга от различни компании. За този вид SW тази организация е нещо нормално. Но лично аз не харесвам и винаги избягвам ако мога "условната компилация". В момента сърбам попарата надробена от тази организация на сорсовете, защото ми се налага да преглеждам и дебъгвам хиляди редове код дневно. За човек като теб на който това му е отрочето и го е гледал как расте и се развива, това не е проблем. Защото казваш искаш да знаеш/виждаш всички взаимовръзки. Но за мен който поддържа чужд код, наличието на код в полу-транжиран вид затруднява читаемостта на сорсовете. Вярно сорс едиторите предлагат някой благинки за елиминиране на частите от сорса които не влизат в даден билд, но от личен опит казано, често това води до подвеждане. И загуба на ценно време и... натоварва. Условната компилация когнитивно натоварва човека. Машината го мели и не го усеща. Чисто и просто лично предпочитание - да не използвам условно компилиране по дизайн. Използвам го като кръпки в по-късен етап от проекта, когато трябва да се намери решение но не и да е предвидено по дизайн.

_________________
Най-опасният враг на истината и свободата е мнозинството.


Вто Апр 28, 2020 10:52 am
Профил
Ранг: Популярен
Ранг: Популярен

Регистриран на: Пон Дек 15, 2014 10:05 pm
Мнения: 324
Мнение Re: Управление на изходен код
Нещо от рода на external в SVN? Имаш диектория "Проект Х", имаш директория "Проект Й", в които си вкарал друга директория "Модул У", та, като промениш модула, после само ъпдейтваш проектите. С гит, също може да се измисли. В едно репо вкарваш скрипт, който да сваля друго репо и да ползва другото репо за проекта. За vcs не знам как би могло да стане, но предполагам има някакви подобни хватки.


Съб Май 09, 2020 12:00 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Управление на изходен код
external-ите и аналогичните submodule-и са вариант (обсъждани са по-назад в темата). Но си имат техните проблеми. Сам казвах проект А, Б и т.н., т.е. трябва да се гледа на всяко отделно репозитори като на отделен проект, а не само на набор от сорс файлове.
С две думи, "връзката" между проектите така че станат финалното приложение (т.е. библиотеки/компоненти, от които накрая се сглабя приложението) не се обслужват добре от директна връзка, която доставя сорс кода.
Като "консуматор" ти се обаждаш и питаш "къде е библиотеката за hal-а за stm32?" и някой ти казва SVN репо. Ти го слагаш като екстърнал - и се очаква да го закачих (интегрираш) в билда си. Съответно се оказва че имало мейкфайл, които описвал нещо, ама ползва един каква си променлива (примерно CC) за компилатор, или нещо си друго и при теб я не се компилира, я трябва от мейкфайл да обръщаш на cmake, eclipse managed или каквото друго искаш. Накрая се билдва, ама не работи, или, още по-зле работи, ама на всеки 3 месеца устройството гърми и трябва да се връща за ремонт от танзания. А причината - с твоя environment нещо се билдва по друг начин (компилатор, символ дефиниран, include и тем подобни).
В тоя момент се оказва че писача на HAL-а го тествал с 4.8 гцц, ти си го компилирак с 5.4 и нещо се объркало. Кой сега е за мъмрене пред колектива?
Ако на теб, като отговорен за финалното приложение, ти кажат от другия отдел "няма да даваш елф/хекс, дай сорс и ние ще си го билдваме", и нещо се омаже по подобен начин, ще искаш да ползват билднатия от теб елф/хекс да се флаши за клиентите. Същото важи за писача на библиотеката - и той ще иска да ползваш проверена от него библиотека (примерно *.a, *.so, *.dll) или нещо подобно, с аргумента че е проверено от QA отдела.
Та идеята е че всеки самостоятелен проект има нужда от "процес" и стъпки, които са допълнително към сорса, т.е. се случват за всяка промяна на сорса. След качването на нова версия (check-in) се очаква да се билдне, unit тества и т.н. В малките/еднолични екипи това обикновено се случва от един човек, на един компютър, в един скрипт примерно. Промените в другите проекти са му ясни, знае ги, и има достъп до сорса там.
Но когато трябва да се изчистят процесите, и например тоя код да се release-не за ползване от "клиентите" (вътре в фирмата, QA, или понякога и извън фирмата - примерно доставят библиотека с която клиентите да работят с твоето устройство/модул), не искаш и не можеш да даваш просто сорса, и да разчиташ че те ще го билднат правилно. Всъщност можеш, ако сложиш отгоре лицензен хедър "не носим нито вар, нито цимент, нито някаква отговорност".

Всички тия усложнения са довели до извода, че връзките между елементите в проекта трябва да се декларират и управляват от самостоятелно ниво. Това позволява контрол, проследимост и hook-ове на входа и изхода на всяка стъпка. Най-малкото, имайки един прилично голям SVN сървър с няколко стотин репозиторита, понякога ти се иска да кажеш "аджеба, кой ползва моята библиотека като external, и за всеки ползващ, на коя версия е забита връзката?"
Виждал съм подходи, при които svn:external пропъртитата не са описани директно, а се слагат от скриптове, които се изпълняват примерно на всеки update, така че истинската информация към къде да е насочено да идва от "друго място"
Но като цяло самият механизъм на svn:external не дава достатъчно удобства за лесно правене, пренасочване на връзки и т.н.
За да работи тоя подход се налага да се ползват/налагат правила за организация на репозиторитата - примерно всеки проект трябва да има папка 'export', в която да са публичните/интерфейсни хедъри, папка 'src' за сорсовете, папка "lib" за билднати библиотеки и т.н. Това обаче показва че има един процес, който от 'src" прави build и попълва 'lib" ( и може би export). Щом има процес значи има нужда от ясно отделен "вход" (репозитори със сорсовете) и изход - репозитори с export и lib.
Пак казвам, за дребни огранизации това е overkill, или е такова при липсата на готов инструментариум. При по-големи организации разни 'дреболии' много помагат - ако в горния пример приемем че двете репозиторита са условно кръстени "stm32_HAL_src" (за входното) и 'stm32_HAL_lib" (за изходното), и между тях е закачен процесът на билдване (и unit тестване), то е много вероятно в момент от времето t да имаме 2567 ревизии в stm32_HAL_src и... 15 ревизии в stm32_HAL_lib. Защо? Защото до ревизия 1000 на сорса кода не се е билдва успешно - проби, грешки. След ревизия 1000 почнал да се билдва, но имало 200 ревизии, в който някой само сменял коментари да го разкраси, още 200 в които правил други промени, които след компилиране вадели абсолютно същия *.a файл след билда (същия хеш) - преименувал променливи, функции, ровичкал по "мъртъв" код, и т.н.
Отделно, с svn особено, да чекаутваш повече файлове от нужните си е време, така че имайки отделни репота за "изхода" ти позволява да дръпнеш 2 файла, вместо 2022 сорса и хедъра.
Ако се опиташ да оставил билднатите библиотеки в първото (сорс) репо, примерно в папка "lib", имаш проблем - тоя либ за каква архитектура е билднат, как е конфигуриран билда? За да може да се ползва това изисква да "таг"-ваш (не ако svn таг-ове) в тая папка - т.е. да стане "lib/stm32_gcc_5.4_OptLevel2". Ако обаче в тая библиотека ползаш други (зависим си), това ще заприлича на "/lib/stm32_gcc_5.4_OptLevel2_lwip_2.1_rel_NoPacket" и т.н.

Edit: за бинарита (компилирани библиотеки, изпълними файлове) си има отделен вид системи за версионализиране, различни от тези за сорс контрол - това са artifact repository-та (artifactory на jfrog е много популярно), S3 на амазон или съвместими клонинги, разни от java света като maven. Те са специализирани и се справят по-добре с тази задача, защото изискванията са по-различни от тези за сорсовете - всяко качено нещо е трябва да е наименовано (tag-нато), размерите са големи, има нужда от метаданни за тях (това е за aarch64, другото е за x86,...). Не ги и познавам толкова в подробности как работят вътрешно.


Съб Май 09, 2020 9:21 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 34 мнения ]  Отиди на страница Предишна  1, 2, 3

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 2 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни