From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Message-ID: <45CF7B69.10802@altlinux.org> Date: Sun, 11 Feb 2007 23:24:09 +0300 From: Mikhail Yakshin User-Agent: Thunderbird 1.5.0.8 (X11/20061205) MIME-Version: 1.0 To: ALT Devel discussion list References: <45CE2167.5040900@altlinux.org> <20070210202323.GB11298@basalt.office.altlinux.org> In-Reply-To: <20070210202323.GB11298@basalt.office.altlinux.org> X-Enigmail-Version: 0.94.1.0 Content-Type: text/plain; charset=KOI8-R Content-Transfer-Encoding: 8bit Subject: Re: [devel] erlang: asking for a hint, possibly with --as-needed X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.9rc1 Precedence: list Reply-To: ALT Devel discussion list List-Id: ALT Devel discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Feb 2007 20:24:46 -0000 Archived-At: List-Archive: List-Post: Dmitry V. Levin wrote: > On Sat, Feb 10, 2007 at 10:47:51PM +0300, Mikhail Yakshin wrote: >> Я тут взялся глобально перелопачивать Erlang > > Значит, всеобщее счастье не за горами. :) Я, пожалуй, не так сильно оптимистичен... >> 2. Эрланг - это довольно объемный пакет, собирается где-то по 30-40 >> минут на сборку. > > На каких мощностях? Тот пакет, который сейчас в Сизифе, собирается раза в > 2 быстрее. Видимо, на сборочных серверах и полностью в tmpfs. Какой смысл сравнивать? >> Сборочное окружение субъективно мною характеризуется >> как "невменяемое": масса хаков вокруг autoconf на тему поддержки >> совместимости с win32, вывернутая наизнанку схема генерации >> Makefile <-> Makefile.in, > > Это как? Из Makefile формируются Makefile.in? Все Makefile, как правило, не генерящиеся. В них записано по 3 строчки вроде: include $(ERL_TOP)/make/target.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk include $(ERL_TOP)/make/otp_subdir.mk Через несколько уровней вызовов этих мейкфайлов из $(ERL_TOP)/make/, которые там что-то у себя внутри детектят, дефайнят и в зависимости от этого принимают какие-то решения, в итоге каким-то образом управление передается в Makefile.in, лежащий в той же директории, тоже не генерящийся. Масла в огонь подливает то, что по сути там не 1 проект, а под сотню разных проектов, вложенных друг в друга. В некоторых местах иерархии есть свой корень, свой собственный configure и там целое отдельное приложение, библиотека или статический object >> 3. Проблемы в #10657 побеждены посредством -fno-stack-protector, как в >> Ubuntu. > > На первом этапе это логичное решение, но потом придётся найти что-то > получше. Чем дальше я копаюсь с erlang - тем больше убеждаюсь в том, что это такое нечто, которое проще как-то собрать, забыть и не трогать, пока не сломается что-то критичное. По хорошему - там надо бы начинать с полной перестройки всей системы сборки, его раскладывания файлов (которое абсолютно не соответствует идеологии FHS) и т.п. На Erlang, насколько я понял, есть целых 2 приложения для простых смертных в этом мире: ejabberd (xmpp-сервер) и yaws (http-сервер). Остальное - огромная куча какого-то проприетарного и очень специфичного софта для телефонии имени самого Ericson'а и т.п. >> 4. Сама сборка пестрит большим количеством warning'ов об undefined >> symbol в verify-elf (потому что там масса .so-шек, подгружаются >> виртуальной машиной на лету, как плагины) и одним TEXTREL'ом в районе >> сборки с openssl - оно у нас там уже давно стоит на relaxed. > > Во что превращается этот TEXTREL на x86-64? Пока еще не добрался. >> 5. Есть проблема со сборкой erl_interface - это некий компонент erlang >> (интерфейс к C), без которого он работать теоретически может, но >> ejabberd без него не соберется. >> >> Я подозреваю, что проблема в --as-needed и порядке линковки. На других >> системах (Fedora, BSD, Debian), люди говорят, что все собирается. Кусок >> лога: >> >> gcc -pipe -Wall -O2 -march=i586 -mtune=i686 -fno-stack-protector -Wall >> -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations >> -Wnested-externs -Winline -fno-strict-aliasing -I. -I../include >> -Iconnect -Iencode -Idecode -Imisc -Iepmd -Iregistry -Ii686-pc-linux-gnu >> -Ilegacy -o >> /home/greycat/RPM/BUILD/otp_src_R11B-3/lib/erl_interface/bin/i686-pc-linux-gnu/erl_call >> prog/erl_call.c prog/erl_start.c \ >> >> -L/home/greycat/RPM/BUILD/otp_src_R11B-3/lib/erl_interface/obj/i686-pc-linux-gnu >> -lei -lrt -lresolv -lnsl >> /tmp/.private/greycat/ccawXslX.o: In function `main': >> erl_call.c:(.text+0x1994): undefined reference to `__erl_errno' >> /home/greycat/RPM/BUILD/otp_src_R11B-3/lib/erl_interface/obj/i686-pc-linux-gnu/libei.a(ei_connect.o): >> In function `ei_do_receive_msg': >> ei_connect.c:(.text+0x2d6): undefined reference to `__erl_errno' >> ei_connect.c:(.text+0x319): undefined reference to `__erl_errno' >> ei_connect.c:(.text+0x331): undefined reference to `__erl_errno' > > Так и есть, libei.a не слинковано с тем, что содержит определение > символа __erl_errno. > >> Подскажите, что тут можно проверить и куда смотреть? > > Посмотреть в лог сборки libei.a -- скорее всего там неправильный порядок > линкуемых библиотек или даже просто нет нужной линкуемой библиотеки. Понятно, спасибо. libei.a собирается вполне обычным способом из следующих objects в таком порядке: > ei_connect.o ei_resolve.o eirecv.o send.o send_exit.o send_reg.o decode_atom.o decode_big.o decode_bignum.o decode_binary.o decode_boolean.o decode_char.o decode_double.o decode_fun.o decode_intlist.o decode_list_header.o decode_long.o decode_pid.o decode_port.o decode_ref.o decode_skip.o decode_string.o decode_trace.o decode_tuple_header.o decode_ulong.o decode_version.o decode_longlong.o decode_ulonglong.o encode_atom.o encode_bignum.o encode_binary.o encode_boolean.o encode_char.o encode_double.o encode_fun.o encode_list_header.o encode_long.o encode_pid.o encode_port.o encode_ref.o encode_string.o encode_trace.o encode_tuple_header.o encode_ulong.o encode_version.o encode_longlong.o encode_ulonglong.o epmd_port.o epmd_publish.o epmd_unpublish.o ei_decode_term.o ei_format.o ei_locking.o ei_malloc.o ei_portio.o ei_printterm.o > ei_pthreads.o ei_trace.o ei_x_encode.o eimd5.o get_type.o show_msg.o ei_compat.o hash_dohash.o hash_foreach.o hash_freetab.o hash_insert.o hash_isprime.o hash_lookup.o hash_newtab.o hash_remove.o hash_resize.o hash_rlookup.o reg_close.o reg_delete.o reg_dirty.o reg_dump.o reg_free.o reg_get.o reg_getf.o reg_geti.o reg_getp.o reg_gets.o reg_make.o reg_open.o reg_purge.o reg_resize.o reg_restore.o reg_set.o reg_setf.o reg_seti.o reg_setp.o reg_sets.o reg_stat.o reg_tabstat.o Значком ">" я отметил интересующие нас сейчас objects. Определяться __erl_errno должна по идее в ei_pthreads.o, а используется в ei_connect.o. Только здесь какая-то ерунда получается: если посмотреть в ei.h, то там эта переменная определена как: #if defined(_REENTRANT) || defined(VXWORKS) || defined(__WIN32__) /* 'erl_errno' as a function return value */ volatile int* __erl_errno_place(void) __attribute__ ((__const__)); #define erl_errno (*__erl_errno_place ()) #else /* !_REENTRANT && !VXWORKS && !__WIN32__ */ extern volatile int __erl_errno; #define erl_errno __erl_errno #endif /* !_REENTRANT && !VXWORKS && !__WIN32__ */ Насколько я понял - _REENTRANT - это какой-то флаг-характеристика системы. Не знаю, должен он быть установлен он у нас или нет и за что отвечает (гугл однозначного ответа на этот вопрос не дает), но, в данном случае, насколько я проверил - не установлен. В итоге у нас есть простое определение переменной и просто алиас на нее: extern volatile int __erl_errno; #define erl_errno __erl_errno В ei_pthreads.c же, где по идее и должно быть реальное объявление (без extern) этой переменной, есть 2 варианта ее определения: 1. volatile __declspec(thread) int __erl_errno = 0; 2. static volatile int __erl_errno; Вариант 1 засунут под ifdef __WIN32__, вариант 2 - под ifdef VXWORKS. У нас, очевидно, ни один из них. В итоге что получается, когда есть extern, но нет реально объявленной переменной? К коду ei_connect.c претензий нет - там все достаточно чисто - используется именно erl_errno, запрос к __erl_errno получается именно из-за дефайна. Видимо, на всех тех машинах, где Erlang собирается под Linux/BSD, стоит этот _REENTRANT => нет такого понятия, как __erl_errno вообще? Есть какие-то мысли, как это правильно исправить? Все упирается, видимо, в то, что такое дефайн _REENTRANT, почему у нас его нет и что сломается от того, если я его определю? Плюс, после того, как разберемся с этим вопросом, ei_pthreads.o и ei_connect.o в порядке линковки надо поменять местами, я правильно понимаю? -- WBR, Mikhail Yakshin AKA GreyCat ALT Linux [http://www.altlinux.ru] [xmpp:greycat@altlinux.org]