|
|
  |
uClinux (LPC2468) и C++, Проблема сборки исходников |
|
|
|
Jul 26 2016, 05:04
|

Участник

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809

|
Поправил ещё разСталкивался ли кто с проблемой отсутствия в результирующем коде вызова глобальных конструкторов по умолчанию (C++)? Исполняемый файл работает, только нет конструкторов, что очень затрудняет жизнь. Опции сборки: Код # Place -D or -U options here for C++ sources CPPDEFS = -Dlinux CPPDEFS += -D__linux__ CPPDEFS += -Dunix CPPDEFS += -D__uClinux__ CPPDEFS += -DEMBED #CPPDEFS += -pthread
#---------------- Compiler Options C++ ---------------- # -g*: generate debugging information # -O*: optimization level # -f...: tuning, see GCC manual and libc documentation # -Wall...: warning level # -Wa,...: tell GCC to pass this to the assembler. CPPFLAGS = $(CPPDEFS) CPPFLAGS += -O$(OPT) CPPFLAGS += -msoft-float CPPFLAGS += -fomit-frame-pointer CPPFLAGS += -fno-common CPPFLAGS += -fno-builtin #CPPFLAGS += -fpack-struct=1 CPPFLAGS += -Wall
#---------------- Linker Options ---------------- LDFLAGS = -lpthread LDFLAGS += -Wl,-Map=$(TARGET).map LDFLAGS += -Wl,-elf2flt="-r"
Сообщение отредактировал uni - Jul 26 2016, 06:12
--------------------
Россия навсегда!
|
|
|
|
|
Jul 26 2016, 08:58
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Смотрите линкерный скрипт, определена ли секция с конструкторами (название секции надо смотреть, какое используется под ваш тулчейн). И проверить, что из стартапа (basiccrt.S или что-то в этом роде) вызывается функция __libc_init_array() до вызова main. Эта функция осуществляет в том числе вызов конструкторов глобальных объектов. Вызывает она их из таблицы указателей, которые лежат в вышеупомянутой секции. Кстати, внутри этой функции можно и посмотреть, куда тулчейн эти указатели складывает - в какой объект, а затем уже найти в какую секцию кладётся этот объект. Например, тулчейн arm-none-eabi кладёт конструкторы в секцию .init_array, соответствующий фрагмент линкерного скрипта выглядит так: CODE .text : { __init_array_start = .; KEEP(SORT(*)(.init_array)) // eabi uses .init_array for static constructor lists __init_array_end = .; А внутри __libc_init_array() есть код: CODE count = __init_array_end - __init_array_start; for (i = 0; i < count; i++) __init_array_start[i] (); Вот, собственно, и весь механизм. Судя по симптомам у вас просто нет вызова __libc_init_array (возможно, стартап неподходящий - например, от сишных проектов, либо поддержка С++ не включена) - всё работает, не падает, только нет вызовов конструкторов. Если бы, например, вызов __libc_init_array() был, но не была определена секция с массивом указателей на конструкторы, то программа на старте бы падала. Возможно, что у вас там нет ни того, ни другого.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jul 26 2016, 10:54
|

Участник

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809

|
Да, я тоже подумал, что компоновщик не прилинковал нечто, где есть инициализация и вызов конструкторов и деструкторов. Мой тулчейн мне достался от человеков, которые писали на C и я его не собирал. Видимо, поддержка C++ включена была не полностью. Я находил примерно похожий код и даже варианты инструкций из интернетов для ручного включения необходимого кода, но это всё нужно допиливать для применения у меня. Оказалось очень не просто и пока забросил это дело. У меня похоже не только глобальные, но и динамические объекты не инициализируются. Приходится как на паскале вызывать методы Create() и Destroy(), созданные вручную.
--------------------
Россия навсегда!
|
|
|
|
|
Jul 26 2016, 11:49
|

Участник

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809

|
Не знаю как это сделать. У нас своя разработанная плата и uClinux, заточенный под неё лет 7 назад. Вспоминать автору как собрать виртуалку с окружением некогда. А я хотел бы кое-что добавить  шаблоны там, вектора... пишу как на C почти. Программа получилась большая (многопоточная) и велосипедов очень много, включая вот обёрточный код типа Create/Destroy. Там ещё много побочных эффектов, что приводит к дублированию кода. Хорошо хоть перегрузка методов работает.
--------------------
Россия навсегда!
|
|
|
|
|
Aug 1 2016, 04:58
|

Участник

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809

|
Вроде немного разобрался при помощи описания отсюда. Не подскажите, где находится скрипт компоновщика? Я заставил собираться с учётом crti, crt1, crtbegin и crtend, но их порядок не верный. Последние два вставляю я, а вот первые - компоновщик. Не могу понять где. Код .init 0x00000000 0x10 *(.init) .init 0x00000000 0x4 /home/user/uclinux/uClibc/lib/crti.o 0x00000000 _init .init 0x00000004 0x4 /usr/local/lib/gcc/arm-linux/4.2.1/soft-float/crtbegin.o .init 0x00000008 0x4 /usr/local/lib/gcc/arm-linux/4.2.1/soft-float/crtend.o .init 0x0000000c 0x4 /home/user/uclinux/uClibc/lib/crtn.o
.plt *(.plt)
.text 0x00000000 0x184cc *(.text .stub) .text 0x00000000 0x2c /home/user/uclinux/uClibc/lib/crt1.o 0x00000000 _start .text 0x0000002c 0x0 /home/user/uclinux/uClibc/lib/crti.o .text 0x0000002c 0xa0 /usr/local/lib/gcc/arm-linux/4.2.1/soft-float/crtbegin.o .text 0x000000cc 0x218 obj/Logger.o 0x000000e4 _ZN7CLoggerC1Ev 0x000000cc _ZN7CLoggerD1Ev 0x00000124 _ZN7CLogger3LogEPKcz 0x000000d8 _ZN7CLoggerD2Ev 0x000000f0 _ZN7CLoggerC2Ev 0x00000260 _ZN7CLogger7DestroyEv 0x000000fc _ZN7CLogger6UnLockEv 0x00000274 _ZN7CLogger6CreateEv 0x00000110 _ZN7CLogger4LockEv .text 0x000002e4 0x110 obj/main.o 0x000002e4 __cxa_pure_virtual 0x00000348 main .text 0x000003f4 0x3c /usr/local/lib/gcc/arm-linux/4.2.1/soft-float/crtend.o
Сообщение отредактировал uni - Aug 1 2016, 05:01
--------------------
Россия навсегда!
|
|
|
|
|
Aug 2 2016, 05:47
|

Участник

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809

|
Короче, победил я это дело. Теперь почти функциональный C++ получился. Шаблоны заработали, вызов конструкторов, деструкторов, наследование, а вот с остальным всё очень нестабильно. Оказывается ключ оптимизации очень сильно влияет на появление SIGSEGV. С одним ключом он есть, с другим нет при запуске. В общем, видимо сборка старенькая, еле дышит наладом, нужно очень аккуратно использовать функционал C++. Итак, добавил ключики: Код CPPFLAGS += -fno-exceptions LDFLAGS += -lstdc++ В Makefile Код CRTBEGIN_OBJ:=$(shell $(CC) $(CPPFLAGS) -print-file-name=crtbegin.o) CRTEND_OBJ:=$(shell $(CC) $(CPPFLAGS) -print-file-name=crtend.o)
$(CC) $(CPPFLAGS) $(CRTBEGIN_OBJ) $(OBJECTS) $(CRTEND_OBJ) $(LDFLAGS) -o $(TARGET) И обязательно играемся с Код # Optimization level, can be [0, 1, 2, 3, s]. # 0 = turn off optimization. s = optimize for size. OPT = 2 Возможно нужно было ещё crt1.o, crti.o и crtn ручками вставить в нужном порядке, но я забыл ключ компоновщика, чтобы их автоматом не включать. Да... какое поле возможностей сразу открылось. Жаль STL нету (пока). У uClibc вроде есть там какой-то урезанный вариант или это отдельно идёт, посмотрим потом.
--------------------
Россия навсегда!
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|