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

Регистриран на: Пет Юни 03, 2005 8:39 pm
Мнения: 1971
Мнение Управление на изходен код
Как да използвам общ код между различни проекти? Правя уточнението, че става дума само за личните ми неща, т.е. ползвателят е един. За пример - написал съм си библиотека за работа с rtc, която компилирам в зависимост от използвания контролер. Как мога да я вкарам в vcs, така че да мога да я използвам в различни проекти, т.е. сорс кода и да бъде само на едно място.

_________________
Определянето стойността на дадена величина се нарича ИЗМЕРВАНЕ!


Съб Апр 25, 2020 6:03 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Управление на изходен код
Много дълбока тема за code reuse. VCS-a няма отношение - кода трябва да си е организиран/написан както трябва - гит или нещо друго няма да ти помогне.
Принципно това значи да изолираш единичен алгоритъм, да изведеш външните неща, от които той зависи (dependencies) и тогава да ходиш нататък.
В обектното има един набор от 5 правила, наречени SOLID - https://en.wikipedia.org/wiki/SOLID - това е добро начало за четене.
Във функционалното са още по-крайни - не се допускат зависимости в алгоритмите - всички зависимости се организират и решават в "интеграционното" ниво (т.е. в не-библиотечния код), т.е. в кода, който взима компонентите и прави крайния вариант на фирмуер (т.е. exe-то, а компонентите са DLL-ите).
Писането на компоненти, които няма зависимости от друг сорс код, е малко tricky и иска обръщане на мисленето. Много хора примерно казват че е невъзможно или непрактично - най-малкото може да ти потрябва да алоцираш памет, запишеш или прочетеш файл или друго I/O. Тук идват разните познания, дето са силно развити като концепции във функционалното програмиране - I/O винаги е извън алгоритмите, алоциране няма - ако на компонента ти му трябва памет то той трябва да я получи като аргумент, т.е. някой извън него (преди него) да я е алоцирал (или стек, или глобална, няма значение за компонента, той очаква пойтър с валидна зона). Ако трябва да се запише нещо във файл, то записа не се съдържа в компонента който генерира пакетите за модбъс протокола примерно, или какъвто там алгоритмичен(библиотечен, преизползваем) компонент имаш.
Друг начин да се обясни тази концепция за премахване на зависимостите от компонентите, е да си представиш как се случва потока на викане и предаване на информация:
- "класически" вариант - викаш функцията "modbus_read_register(hSerial, REG_10h)", която вътре в кода си има викане на функция или функционален пойнтър за пращане по серийния. Т.е. тя съдържа две части - в първата подготвя съдържанието на фрейма, а във втората вика И/О функцията за да продължи "flow"-a. Реално даже може да са три:
- алоциране на памет за фрейма
- подготвяне (сериализиране) на данните в подходящия фрейм
- предаване по серийния чрез викане на някаква друга функция, примерно Serial.Write()
Ако направим препратка към "S"-то в SOLID-a ще видим че вече чупим идеята - там пише "single responsibility" или "single reason for change". А ние сме набалбукали 3 отговорности, и три причина да се смени:
- някой сменя начина на работа с паметта - примерно забранява ползването в новия проект на динамична памет, или предлагат ново API/абстракция за алоциране - и това ни кара да ровичкаме кода на нашата modbus функция
- някой казва "поддържайте новата версия на модбъс спецификацията, дето ISO са я пуснали миналата седмица" и ни връчва документа - и ние ходим да променяме кода на modbus функцията (това е ок, тази причина за промяна е оная "единствената", дето SOLID ни я разрешава - щото функцията ни се казва modbus и смяната в модбъс спецификациите е нормално да изискват промяна в кода)
- някой сменя апи-то за достъп до серийния, или казва "освен по сериен, всички пакети да се пращат и в един файл за логване", или да се пращат едновременно на 3 серийни порта, или нещо друго - ние пак ходим да пипаме сорса на модбъс функцията, въпреки че протокола си е еднакъв от 20 години
Сега, в обектното има друг подход за решаване на някой от тия проблеми - примерно абстрактни апи-та за И/О, които обаче слагат един слой от код (поне) между истинския алгоритъм и И/О-то. А и решава частично проблема - ако трябва да се лог-ват пакетите ще се наложи да направим промяна в И/О функцията за да може тя хем да логва, хем да си върши работата.
"Функционалният" подход обаче има и друг бонус - решава ония зависимости в началото и гарантира че нямаш работа в сорса на модбъс кода, ако протокола не се сменил и нямаш бъг. В сценария горе това означава че modbus_read_register става "чиста" (pure) функция - това значи че работи само с аргументите си. Съответно тя става нещо като:
Код:
modbus_read_register(pbyBuffer, regNum);

pbyBuffer е предварително нагласеното място, където нашТа функция ще си пише байтчетата на фрейма според документацията на модбъс протокола
regNum е аргумент, без който функцията няма да знае как да подготви фрейма, може да са повече, но всичките са специфични и имат обосновка в документа на модбъс стандарта
Тук се вижда, че ако сме прецизни тая функция ще подготви фрейма, но няма да е сметнала чексумата - щото сме и забранили да вика crc функцията. А вътре в нея няма да сложим алгоритъма за crc по две причини:
- ще нарушим принципа за single responsibility
- ще трябва да слагаме кода за crc на няколко места - примерно и в modbus_write_register().
Та в този случай правим следното - на горното ниво, което е избрало къде да сложи буфера, т.е. в стек, хийп или глобална памет, ние сме повикали първо modbus_read_register() и след това викаме crc(pbyBuffer) и слагаме байта за crc някъде (даже не е нужно да то връщаме в буфера, щото после можеш да пратим два отделни парцала - pbyBuffer и после байта за crc).

По-общо, всяка една зависимост, която имаш в кода, затруднява преизползването на кода в следващ проект. Ти си решаваш докъде искаш да стигнеш в "чистенето" - ако примерно може да си позволиш да кажеш че винаги ще има някакъв вид ОС, примерно POSIX, т.е. няма да правиш други проекти, можеш да си ползваш апи-тата им спокойно. Но няма да ти е лесно да ползваш този компонент на bare metal примерно.
Ако останеш на варианта да си имат някакви зависимости трябва да избереш начин за менажирането им - има вече добри package manager-и и за c/c++ - conan.io примерно. Можеш да ползваш механизмите на git/svn за модули - submodules/externals, но това си има доста ограничения.

Едит: ако е само за сорс контрол въпросът ти, първо трябва да избереш каква система ще ползваш. Препоръчвам гит, и за по-лесно някаква по-тежка услуга от типа на github, gitlab, bitbucket. Ако държиш при теб да е сървъра можеш да сложиш или гитлаб (малко е тежичък), или по-леката gitea. Като за начало няма да ти липсва нищо в гитеа-а, но за в бъдеще от гитлаб можеш да ползваш някой екстри.
Ако не ти пречи че кода ще се качва някъде в нета, гитхъб имат private репозиторита - другите няма да ти виждат кода, т.е. няма да е public, но остава риска че все пак е на друг сървър.
Като си инсталираш или се регистрираш там някъде, следваш документацията им да си направиш нов проект, и примерно гитлаб-а директно ти показва какво да напишеш в конзолата - ако ще качваш код от съществуваща папка например.
Можеш да ползваш графични клиенти за git - примерно TortoiseGit, който е особено подходящ ако имаш опит с svn, или пък в еклипса има също клиент вграден.


Съб Апр 25, 2020 9:14 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Юни 03, 2005 8:39 pm
Мнения: 1971
Мнение Re: Управление на изходен код
Малийй, много сложно. Искам просто :). Ако се придържаме към примера, който посочих - днес промених малко кода. Обаче същия код го имам на още 2-3 места. Сега трябва да го променя ръчно в тези 2-3 места. Искам по някакъв начин този код да се взема от едно място, т.е. ако го променя да го правя на едно място. Няма проблем коя vcs система да се ползва. Имам пуснати svn, git и cvs.

_________________
Определянето стойността на дадена величина се нарича ИЗМЕРВАНЕ!


Съб Апр 25, 2020 9:49 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 8:21 pm
Мнения: 27996
Местоположение: София
Мнение Re: Управление на изходен код
няма как да стане просто ако искаш да я използваш в други проекти и д не я буташ за д я напаснеш, което пък автомтично значи че ако я направиш за един,з адругите вече няма да работи ...това е нещо което много добре трябва да обмислиш до колко и в каква степен ти е нужно.


Съб Апр 25, 2020 10:03 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Юни 03, 2005 8:39 pm
Мнения: 1971
Мнение Re: Управление на изходен код
Защо да не работи. Работи си :). От тази гледна точка проблем няма.

_________________
Определянето стойността на дадена величина се нарича ИЗМЕРВАНЕ!


Съб Апр 25, 2020 10:18 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 1:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Управление на изходен код
gicho написа:
Много дълбока тема за code reuse. VCS-a няма отношение - кода трябва да си е организиран/написан както трябва - гит или нещо друго няма да ти помогне.

Абе и vcs може да помогне. Но първо трябва по дизайн въпросния сорс код да е преизползваем и интегрируем в различните проекти.
После всеки проект в отделно репозитори и въпросния сорс код в негово си репозитори.
Проектите които ползват въпросния сорс, правят референции към версии(тагове) от репозиторито на "въпросния" сорс.

Така отделните проекти могат да референсват различни версии на "въпросния" сорс код.
За референсване при svn ползваш svn:external, при git ползваш submodule.
Съответно когато правиш checkout на проекта, в работното копие получаваш съответната версия на "въпросния" сорс.
И сега вече би трябвало да разбереш колко безсмислено е да се каже: "Искам по някакъв начин този код да се взема от едно място..."
ако не си уточнил дали под "място" се има предвид локация във файловата система или референция към версия на сорс код под version control.

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


Съб Апр 25, 2020 10:44 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 8:21 pm
Мнения: 27996
Местоположение: София
Мнение Re: Управление на изходен код
syscop написа:
Защо да не работи. Работи си :). От тази гледна точка проблем няма.

Е това вече става това за което Здрав е писал, всеки проект си има копие на тоя код в неговото репозитори който вече може и да го форкваш, кода де, ама тогава не е точно това за което питаше като че ли. То това става и без vcs и на ръка може да го правиш това.


Съб Апр 25, 2020 10:51 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 1:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Управление на изходен код
ToHu написа:
syscop написа:
Защо да не работи. Работи си :). От тази гледна точка проблем няма.

Е това вече става това за което Здрав е писал, всеки проект си има копие на тоя код в неговото репозитори ...

Здрав каза референции а не копи-пействане ;)

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


Съб Апр 25, 2020 10:52 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 8:21 pm
Мнения: 27996
Местоположение: София
Мнение Re: Управление на изходен код
Да това казваш, но в момента в който почнеш да му правиш версии разликата става доста минимална, най-вече удобството svn-а да се грижи за версиите когато се появят.


Съб Апр 25, 2020 11:26 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 1:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Управление на изходен код
ToHu, що държиш да изказваш мнение по всички теми?!?

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


Съб Апр 25, 2020 11:42 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Сеп 26, 2004 8:21 pm
Мнения: 27996
Местоположение: София
Мнение Re: Управление на изходен код
Zdrav написа:
ToHu, що държиш да изказваш мнение по всички теми?!?

Сори, нямах намерение и да изказвам мнение точно по тая тема.


Нед Апр 26, 2020 12:27 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пет Юни 03, 2005 8:39 pm
Мнения: 1971
Мнение Re: Управление на изходен код
Zdrav написа:
...
Проектите които ползват въпросния сорс, правят референции към версии(тагове) от репозиторито на "въпросния" сорс.

Така отделните проекти могат да референсват различни версии на "въпросния" сорс код.
За референсване при svn ползваш svn:external, при git ползваш submodule.
Съответно когато правиш checkout на проекта, в работното копие получаваш съответната версия на "въпросния" сорс.
И сега вече би трябвало да разбереш колко безсмислено е да се каже: "Искам по някакъв начин този код да се взема от едно място..."
ако не си уточнил дали под "място" се има предвид локация във файловата система или референция към версия на сорс код под version control.


Нещо такова трябва да организирам, ще се мъча :).
Едно място във vcs-a. Сега като пипна нещо по сорса трябва да обновявам на всички места, където се ползва парчето код. т.е. ако го ползвам в два проекта, то го има на две отделни места във vcs-a по едно за всеки проект.

_________________
Определянето стойността на дадена величина се нарича ИЗМЕРВАНЕ!


Нед Апр 26, 2020 9:14 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Управление на изходен код
Както казах в началото, submodule/external е нещото, което на ниво git/svn спестява копирането и позволява "компонента" да живее на самостоятелно място, различно от това на приложенията, които го ползват. Съответно модификациите в компонента се правят на едно място - в неговото репозитори. Това е аналогично на поинтър в C - има го някъде нещото и пускаме референция към него.
Проблемите стават по-явни, когато искаш да направиш таг-ване на сорса - т.е. когато искаш да кажеш "днес минахме всички тестове, пуснахме го на всички машини (приложения), всичко работи, искат това състояние да го маркирам като версия release 1.0". Това значи че искаш след години да можеш да възстановиш състоянието точно както е било в този ден, независимо че си сменял кода във много от компонентите и проектите и имаш вече release 255.0. За да се случи това трябва да използваш тия линкове (т.е. external при svn/ submodule при git) да сочат точно към определено състояние, т.е. версия, на сорса на компонентите. Това на svn означава всеки линк да пише в себе си коя версия на външното репозитори (компонента) иска да ползва - примерно ревизия 10. В този случай то винаги ще взима ревизия 10 на rtc сорса (репозиторито), въпреки че ти си сменял и са се появили там версия 11, 12, .. 200.
Докато разработваш обаче често ти се налага да промениш нещо в rtc и веднага да го вземеш в приложението, за да го тестваш примерно. Или трябва да си работиш локално през това време, защото качването на версия 11 в rtc няма да го прати в приложението, щото то е написало "искам точно 10 на rtc", или трябва да смениш линка към 11, и т.н. За да не ти се налага това, при svn можеш да "пропуснеш" да кажеш коя точно версия искаш, и тогава линка сочи към най-новата налична - т.е. ако смениш на 11 в ртц, то на следващия ъпдейт на приложението ще получиш последната, т.е. 11. Това се вика head версия - последната качена и налична на сървъра.
Когато си свършил работата по дадения бъг фикс или нова функционалност, и си стигнал примерно до 14-та версия на ртц, трябва да направиш споменатото таг-ване - т.е. да означиш едно копие, което обаче винаги в бъдеще да ползва точно 14, а не последната. При таг-ването трябва всички external да се проверят че не са към head, а сочат към фиксирано число - т.е. 14 за линка за ртц. По-новите клиенти за svn го могат това автоматично и питат дали искаш да го направиш - ако си съгласен те обикалят всички описани линкове към външни (externals), виждат в момента коя им е версията (т.е. 14 на ртц) и сменят от head на конкретното 14.
Тук има едно усложнение, че може да имаш няколко нива на външни връзки - приложението ти е казало "ползвам ртц от еди къде си като външно", само че самото ртц, в неговото репо, може да е казало "ползвам "ос-абстракция" като външно за мен". Когато фиксираш ревизиите за таг/release, трябва да си сигурен че ако след време ще получиш точно същия код. Т.е. дори да си фикснал приложението да ползва ртц от 14-та ревизия, трябва да гарантираш че 14-та ревизия на ртц ползва ос-абстракция от точно фиксирана ревизия - т.е. не от head, а от 5-та на репозиторито "ос-абстракция". Т.е. фиксването, ако става автоматично, трябва да е рекурсивно през всички "линкове".
Това изисква да спазваш тая логика и да се съобразяваш винаги с нея - един от начините е никога да не ползваш "head" в линковете, а винаги да слагаш точни числа. Така си сигурен че при всяко тагване имаш точна версия и няма риска да удариш на някакъв дълбоко заринат external, който е останал на head и след година като изтеглиш кода от свн за тоя таг/release, да получиш различно състояние щото някой е качил нова версия в това далечно проектче. Така обаче губиш екстрата проекта да се развива и като екип да "колаборирате" върху няколко репозиторита, без да се налага постоянно да сменяте числа на връзки.
При гит нещата са решени по-касапски - там не можеш да закачиш submodule към "head" - там винаги даваш точна, съществуваща версия. Т.е. отнета ти е възможността да насочваш към "най-последната".

Работата става още по-дълбока, ако в процеса на работа се окаже че трябва да работиш по тоя компонент и да му правиш тестове, без да знаеш кой и къде го ползва (кой е насочил външна връзка към твоя код). Тъй като твоя rtc сам по себе си не е изпълним, ти не можеш да го тестваш, преди да го компилираш до нещо. А за да го компилираш до нещо трябва да му направиш някакъв примерен проект - примерно нещо, което го билдва за PC и може да го стартира от командния ред за да му праща тестови викания и да вижда как се държи. Това значи в репозиторито на rtc да имаш някакъв вид проектно описание - makefile, cmake и друго такова.
За да може някой да ползва отвън твоя "компонент", трябва да измислиш начин да доставяш освен самия код (*.c/h), още и "проектна информация" - кой c файлове, кои хедъри, с какви компилаторски опции да се билдва и т.н. Това може да стане с някакъв "*.mak" файл, който да се include-ва от проектите, които искат да го ползват. Има много начини, но поради липсата на идея на пакети/модули в c/c++ (мая тая година с 20-тата версия може да има нещо), няма един стандартен и общоприложим такъв. Т.е. какъв начин прилагаш зависи от теб и от избраната билд система (makefile, cmake, ...), като тя не ти помага да събереш сорсовете - това трябва да го направиш ти, чрез external линкове.

Всичките тия неща са проблем не само при теб, но и при много сериозни фирми, които са искали да организират проектите си и да си гарантират че няма грешки. Споменатата билд система (make, cmake) играе ролята на "обединител" на крайния проект - т.е. крайното нещо, което ползва различни компоненти и ги организира, казвайки с кой компилатор и какви опции да се билдва, за да стане фирмуера който е за устройство А.
Има два вида билд системи - файл базирани такива (популярните make, ...), които казват така: "някой да ни събере нужните файлове на това ПЦ, в йерархията която сте ми казали, и аз ще ги обработя/компилирам/линкна". Другите, които за C/C++ са единици, са разпределени - те се грижат да съберат описаните компоненти от сървърите, и да билднат, без да изискват ти да им направиш работна папка с всички файлове. За справка cmake има подобна функционалност, но наистина качествено решение е споменатото в горния ми пост conan.io: https://conan.io/. Там в описанието казваш "искам да ползвам rtc версия 1.00" и системата (конан-а) се грижи да го намери по конфигурираните репозиторита, да прецени дали как да го билдне (може вече да е билднато в подходящ вариант - т.е. компилатор и други зависимости) и да го сложи някъде из проекта, така че да знае как да го добави пък накрая на линкера. От теб не се иска нищо повече от това да инклуднеш хедъра rtc.h и да викаш функциите - пътища до хедърите и библиотеките ги настройва той. Това е много подобно на линукските package manager-и (apt/deb) - казваш "инсталирай ми libusb1.0" и той ти смъква хедърите и библиотеките на системата, за да можеш смело да пишеш, без да правиш каквото и да е в makefile-а. Само че линукските изискват някой да е билднал пакета и да го е сложил за твоята платформа на техните сървъри - докато конан-а може както да ползва вече качени готови (ако са съвместими), така и да ти го компилира, щото има силно уникална платформа (профил) - примерно пик24. Другата екстра е че тия системи работят с версии/тагове - т.е. грижат се за онова таг-ване, което горе писах че се прави и изисква фиксиране на ревизиите към определено състояние.

В момента аз ползват и трети вариант - всички тия нужди да се свършат от системата за continuous integration (CI/CD). Всъщност за да може да се случи там, самата система за CI трябва да е доста добре измислена - засега съм намерил само една такава - това е TeamCity на JetBrains ( :prayer: =D> ). Феноменални са, и за малки екипи са безплатни (100 проекта/ 3 билд машини). Та те правят всичко това без външна помощ. Ама много ми стана писането, та ако има интерес ще обясня как се прави там - става бонбон :-) А като бонус, TeamCity се закача много елегантно към gitlab или github, вкл. и локално инсталиран гитлаб.


Нед Апр 26, 2020 9:24 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Сря Яну 26, 2005 1:01 pm
Мнения: 1952
Местоположение: Варна
Мнение Re: Управление на изходен код
gicho, много ги усукваш нещата.
Когато работиш по модула, винаги можеш да направиш бранч, също и бранч в репото на проекта който ползва модула. Съответно докато работиш референцията се насочва към бранча на модула. Когато дойде време да се интегрира - правиш мърдж на бранча и таг-ваш. Съответно и в репо-то на проекта който ползва модула.
А когато тагваш в репото на проекта ползващ модула, hook-ве към сървър страната на съответния vcs, може да се направят така че да ти напомня или да те бие през ръцете ако референциите не сочат към таг-ове.
Близко е до ума и предполагам, че и при вас правите нещо пододбно. Така че всеки проблем на този workflow(тертип на работа) си има и решението.

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


Нед Апр 26, 2020 10:09 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Пон Мар 13, 2006 12:59 pm
Мнения: 3855
Местоположение: Габрово
Мнение Re: Управление на изходен код
Чакай сега, компонента "rtc" си има репо и там бранчове и тагове мога да правя, щото примерно съм му maintainer - съгласен съм. Обаче как така ще направя бранч в проектите, които консумират модула ми? Първо, те не са мои и е много вероятно да нямам права там, второ - за да го направя трябва да ги знам кои са тия репота, дето ме ползват. А те може да са десетки и на произволни места - съответно няма даже и команда от svn туловете да ми върне кои са тия, дет ме ползват. Т.е. за да го направя това ми трябва инструментариум и концепция/pattern - примерно че всеки който ме вземе да ме ползва трябва да се впише в списък при мен, за да го знам, че бранчове започващи с "feature-*" да се третират еди как си и т.н. Това не е ок, или поне не е логично да се прави ръчно - следователно трябва да се оставят на някого "свише", който да измисли правилния подход.
Но и да тръгна в тая посока, feature branch-а ми "оптимизиране на консумираната памет на rtc" не виждам как така ще се появява в проект "електромер с часовник", както и къде е нуждата от тоя бранч в електромера?
Логиката при мен е че ако правя бранч или таг, или пък в trunc/master качвам, искам да се задейства нещо и новия код да се провери - и то със всички възможни интеграции, т.е. всички проекти и конфигурациите им, който са го ползвали. За консуматорите няма значение кой таг или бранч ползват, просто щото не зная какво значи "оптимизиране на консумираната памет на rtc".
Та всичката тая логика, барабар с хуковете и проверките, съм преценил че е твърде ресурсоемко да се прави ръчно. И тук идва CI системата от gitlab + teamcity. Едното дава репозиторита и работа с кода, другото е закачено на hook за да разбира кога има качване на код (събитие). Бранчовете и "merge request"-ите се движат от гитлаб-а - когато има issue то тръгва и генерира merge request, който пък автоматично прави нов feature branch в репото. Всеки commit/push в репото праща сигнал на teamcity, който почва да билдва и тества кода. След като съм пуш-нал в репото на rtc, то сигнала е стигнал до teamcity-то и онова разбира че трябва да билдва. Тук идва цялата хубавина на TC - то поддържа граф на всички зависимости в проектите, за които знае - и затова то вижда че rtc се ползва в още 50 други проекта. Което значи че може да се наложи да се пуснат 50 различни билда, щото тия 50 проекта искат нещо специално и не им върши работа едно бинари (например, всичките 50 имат различни toolchain-ове). В този сценарии TC ще направи 50 билда - всеки от тях ще билдне вариант на rtc библиотеката и с конкретния ще пусне автоматично билда на следващите стъпки, примерно фирмуера на едно от 50-те, и така за всички.
За да разпознае дали ще му трябват 50 отделни варианта, ТС ползва зависимостите и позволява в проекта на rtc да обявиш параметър/променлива - например име на компилатора, или дефиниция "MAX_SESSIONS" или, по-смисленото за rtc, "TIME_FORMAT" или подобни. Така билда на ртц става параметризуем, или, както му викат в cmake, autotools и т.н. - конфигурира се.
Та ако няма такъв параметър ТС прави един билд, щото никой не е поискал вариант за билда, или по-точно ние не сме дали опция тоя билд да се конфигурира - тогава ще билдне rtc еднократно и либ файла ще се ползва един и същ от всичките 50 консуматора/интеграции.
Ако обаче имаме параметър (аз ползвам често "DOCKER_IMAGE_NAME", защото имам докер контейнери с различните toolchain-ове, които също се билдват автоматично от ТС, ама това е друга тема) - та понеже не знам в проекта на rtc дали някой ще иска да билдвам с mingw, или с microchip компилатор, или с arm-none-eabi, се налага да кажа "дайте ми обкръжение, в което да изпълня билда". Т.е. имам примерно makefile, но той иска контейнер, или виртуална машина, в която има настроен верния компилатор и други специфики. Всеки от 50-те проекта/конфигурации, които ползват ртц, дават конкретна стойност, например в проекта "СТМ32-електромер" е написано DOCKER_IMAGE_NAME=gcc-arm-none-eabi-container:1.0, докато в конфигурацията за ПЦ тест е написано DOCKER_IMAGE_NAME=mingw:6.5
При пуш в репото на rtc, TC почва да обикаля връзките и за всяка нова стойност на параметрите (може да са повече от един) прави нова билд и пуска веригата (build chain) да върви нататък, т.е. да се компилира и електромер кода и да се линкне. Ако намери повторение (например, проект СТМ32-водомер със същата стойност на DOCKER_IMAGE_NAME) няма да пусне нов билд на rtc, а ще ползва либ-а от електромера.
Отделно, при правилно закачане ТС получава събития за всички тагове в дадено репо (ртц-то) и пуска билда за всеки - така новия feature branch ще бъде проверен (билднат и тестван) автоматично - няма нужда да се ходи по репота да се преименуват или сменят линкове. Отделно, няма само да съм тествал дали rtc се билдва коректно за един проект, а за всички, които го ползват.
Разбира се, има много екстри - примерно може да се сложи филтър определени бранчове да не се билдват, или да се прави нещо специално - може да искаш само master бранча да се тества и т.н.


Нед Апр 26, 2020 11:49 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 34 мнения ]  Отиди на страница 1, 2, 3  Следваща

Кой е на линия

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


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

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