From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Wed, 27 Jan 2016 21:04:38 +0300 (MSK) From: Ivan Zakharyaschev To: ALT Linux Team development discussions In-Reply-To: Message-ID: References: User-Agent: Alpine 2.20 (LFD 67 2015-01-07) MIME-Version: 1.0 Content-Type: multipart/mixed; BOUNDARY="1807885841-444754083-1453917878=:1475" Subject: [devel] re-writing GNU C; part1.3.2: how to apply (WIP) X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux Team development discussions List-Id: ALT Linux Team development discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Jan 2016 18:04:38 -0000 Archived-At: List-Archive: List-Post: This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. --1807885841-444754083-1453917878=:1475 Content-Type: text/plain; charset=KOI8-R; format=flowed Content-Transfer-Encoding: 8BIT 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. А в моём скрипте такая разница не предусмотрена оказалась. (Кажется, я сейчас понял, что не сложно переписать это правильно, особенно как в моём упрощённом случае, когда порядок и количество команд заранее предопределено.) *** (Эти два сообщения сохранены как .) Модель реализации такой связки с каналом для команд =================================================== (Скрипты сохранены в .) `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&- 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_out.pipe -- Best regards, Ivan --1807885841-444754083-1453917878=:1475--