From: Ivan Zakharyaschev <imz@altlinux.org> To: ALT Linux Team development discussions <devel@lists.altlinux.org> Subject: [devel] re-writing GNU C; part1.3.2: how to apply (WIP) Date: Wed, 27 Jan 2016 21:04:38 +0300 (MSK) Message-ID: <alpine.LFD.2.20.1601272102150.1475@imap.altlinux.org> (raw) In-Reply-To: <alpine.LFD.2.20.1601272033370.1475@imap.altlinux.org> [-- Attachment #1: Type: text/plain, Size: 8073 bytes --] On Wed, 27 Jan 2016, Ivan Zakharyaschev wrote: > Шлю записки о том, как начать применять cuglify/Process в работе с > какой-то "инородной" платформой FOO/Linux (без GCC). Скажем, в работе > Один вариант -- более основательный и ценный для будущего, второй > вариант, который я могу представить (и уже опробовал на практике) -- > проще и позволяет побыстрее увидеть результат компиляции. > (Третий вариант, который я пытаюсь сейчас осуществить и который > достижим побыстрее, чем первый основательный, опишу подробнее в > следующей части сообщения.) Итак, "второй вариант" я осуществил на практике. (С поправкой на то, что Process не понимал расширения .i входного файла.) Теперь хочется, чтобы всё происходило более гладко и незаметно для собирающего под FOO/Linux, при этом давая ему уже реализованные преимущества. И нам не до того, чтобы копаться со сборкой .hs via-С ("первый вариант"). Двигаемся к этой цели. (Это "третий вариант", который где-то между полным "первым" и ручным "вторым" и удобнее с точки зрения автоматизации; берём пример с ccache или скорее distcc): Обращения к x86-машине за результатами вычислений, нужных при сборке -------------------------------------------------------------------- Давайте вставим Process во что-то вроде distcc. Вот как это будет работать: 1. на компилируемом файле исполняется препроцессор 2. результат пропускается через Process на удалённой x86-машине 3. результат принимается обратно на FOO/Linux и скармливается foo-cc Пояснение такой схемы в общем: раз на FOO/Linux какие-то инструменты-преобразователи (наш Process) невозможно запустить, то мы во время сборки на FOO/Linux попросим x86-машину сделать это вычисление за нас. (Заметим, что сборочная система для Sisyphus ориентирована на нативную сборку. И здесь мы действуем с этой стороны, т.е. пропихиваем сборку со стороны FOO/Linux, а не так: > Тут была мысль для удобства доделать Process на предмет вызова > cpp/foo-cc по ssh сразу, вместо локального cpp/gcc, чтобы облегчить > ход действий ) Шаги 1.-3. этой схемы работы надо уточнить/усложнить в связи со следующими соображениями. Формулировка задачи Process как фильтра, работающего с семантикой ----------------------------------------------------------------- Process является такого рода фильтром, целью которого является поддержка задуманной программистом (и мейнтейнером пакета) семантики его C-кода с использованием в качестве backend-а не GCC, а foo-cc. Задуманная семантика может выражаться не только в C-коде (со своими особыми конструкциями вроде nested functions, которые мы переписываем из-за ограничений backend-а), но и в опциях gcc. Опции, работа которых в foo-cc нас не устраивает, мы будем исполнять по возможности сами, а опции для backend-а переписывать (хотя в простом случае просто передаём их без изменений). Это знание о семантике некоторых опций GCC и особенностях их реализации в foo-cc закладывается в Process. Process управляет командами --------------------------- Соответственно, в этой схеме работы на шаге: 1. опции препроцессора контролируются Process 2. -- 3. опции foo-cc контролируются Process Сейчас Process (как и примеры в language-c) устроен так, что он умеет 1. (сам вызывает локальный cpp со всеми релевантными опциями), а 3. не было у них в language-c задумано (ну потому что не было у них цели вызывать cc для завершения анализа исходников). К тому же такой контроль осложняется тем, что Process будет запускаться удалённо, и от него мы должны получить команды для запуска: 1. cpp 2. -- 3. foo-cc Т.е. помимо stdin для .c/.i, stdout для переработанного .i и stderr для warnings, нужны каналы для дачи команд cpp и cc. открытый вопрос: устройство вызова Process из distcc-подобного клиента ====================================================================== Посмотреть устройство distcc (или ccache) на предмет того, как можно было бы его использовать для врезания cugligy/Process (запускаемого на другой машине) в foo-cc/gcc. Связанная с этой темой проблема, которая имеется в моей модельной реализации взаимодействия distcc-подобного клиента и Process (см. ниже) -- это то, что последняя полученная команда (собственно `foo-cc -c`) выполняется в параллельном процессе, хотя как основная по смыслу и последняя должна бы и быть тем, что работает до конца и отдаёт код возврата. Если немного подумать, наверное, можно переустроить скрипт; просто я пока не додумал. (Происходит эта проблема с параллельностью из того, что, во-первых, я писал скрипт как можно проще, чтобы продемонстрировать идею, а во-вторых, сама команда получается по каналу из Process, который мы слушаем параллельно, так, чтобы не блокировать сам вызов Process, т.е. слушатели запускаются до вызова Process и могут получить команду только в то время пока Process работает, и сразу же приступают к выполнению.) Другими словами, одно дело fork-и-exec, а другое -- exec. Первое должно делаться со вспомогательными командами на шагах 1.-2. (их результатов мы дожидаемся и перерабатываем), а команда из шага 3. должна делаться просто exec. А в моём скрипте такая разница не предусмотрена оказалась. (Кажется, я сейчас понял, что не сложно переписать это правильно, особенно как в моём упрощённом случае, когда порядок и количество команд заранее предопределено.) *** (Эти два сообщения сохранены как <http://hub.darcs.net/imz/cuglify/browse/heterogeneous-platform-initial-next-step.md>.) Модель реализации такой связки с каналом для команд =================================================== (Скрипты сохранены в <http://hub.darcs.net/imz/cuglify/>.) `server_dummy.sh` (на месте Process на x86-машине; вызывается, когда нужны результаты его работы): #!/bin/bash set -ex readonly PORT="$1" shift try_send_cmd() { # in a format suitable for xargs: for w in "$@"; do echo "$w"; done | nc 0 "$PORT" } # Connection may (temporarily) fail in any case! # # (In case of local ideal connections, there still is a similar # problem: the listening side may not be listening yet for a short # period of time after it handled the previous connection.) send_cmd() { while ! try_send_cmd "$@"; do :; done } send_cmd a.i send_cmd echo a sed 's:a:b:' exec <&- >&- send_cmd cat a.i Простые helpers (для реакции на стороне клиента на команды от сервера; ради того, чтобы быстро слушать порт дальше после принятия команды -- &): `bg_exec`: #!/bin/sh exec "$@" & `bg_cat_fromOUT_to`: #!/bin/bash exec cat <&101- > "$1" & `bg_exec_toIN`: #!/bin/bash exec "$@" >&100- & `client.sh` (в роли distcc там, где собираем): #!/bin/bash set -ex # Preparation: # The pipe with Process (run on server-side): rm -fv Process_{in,out}.pipe mkfifo Process_{in,out}.pipe # Overall, we were asked (by Makefile etc.): # gcc -c a.c -o a.o # and we pass the args to Process, # because it decides what to do. # The listeners for commands (are run in parallel): { exec 100>Process_in.pipe exec 101<Process_out.pipe # 0. Get the filename (say, a.i) to save the output of Process to: nc -l 9876 | xargs ./bg_cat_fromOUT_to 100>&- exec 101<&- # 1. Instead of running the above single command, # we get the result of (via stdout instead of a.orig.i): # gcc -E a.c [-o a.orig.i] # as asked by: nc -l 9876 | xargs ./bg_exec_toIN exec 100>&- # 2. ...And send it to Process # (or gcc in the case of distcc): # ...(through Process_in.pipe) # which sends the result back # (either a.o in the case of `distcc` # or a.i in the case of Process): # ...(through Process_out.pipe or a.i directly) # 3. And we are asked to run on it (saved as a.i): # gcc -c a.i -o a.o nc -l 9876 | xargs ./bg_exec } & # Running Process (or real gcc in case of distcc): exec ./server_dummy.sh 9876 arg1 arg2 <Process_in.pipe >Process_out.pipe -- Best regards, Ivan
next prev parent reply other threads:[~2016-01-27 18:04 UTC|newest] Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top 2016-01-11 8:48 [devel] re-writing GNU C extensions (part0) Ivan Zakharyaschev 2016-01-11 18:21 ` [devel] re-writing GNU C extensions (part1) Ivan Zakharyaschev 2016-01-12 20:28 ` imz 2016-01-20 10:28 ` imz 2016-01-27 17:59 ` [devel] re-writing GNU C; part1.3.1: how to apply Ivan Zakharyaschev 2016-01-27 18:04 ` Ivan Zakharyaschev [this message] 2016-02-09 18:29 ` [devel] re-writing GNU C; part1.4: .i bug fixed Ivan Zakharyaschev 2016-02-10 10:30 ` Ivan Zakharyaschev
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=alpine.LFD.2.20.1601272102150.1475@imap.altlinux.org \ --to=imz@altlinux.org \ --cc=devel@lists.altlinux.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
ALT Linux Team development discussions This inbox may be cloned and mirrored by anyone: git clone --mirror http://lore.altlinux.org/devel/0 devel/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 devel devel/ http://lore.altlinux.org/devel \ devel@altlinux.org devel@altlinux.ru devel@lists.altlinux.org devel@lists.altlinux.ru devel@linux.iplabs.ru mandrake-russian@linuxteam.iplabs.ru sisyphus@linuxteam.iplabs.ru public-inbox-index devel Example config snippet for mirrors. Newsgroup available over NNTP: nntp://lore.altlinux.org/org.altlinux.lists.devel AGPL code for this site: git clone https://public-inbox.org/public-inbox.git