PDA

Просмотр полной версии : [Вопрос] Компилятор плагина под Линукс



Edwin
20.11.2016, 12:49
Парни, подскажите , пожалуйста, способ и программу компиляции динамической библиотеки .so под Линуксом
Пробую Code::Blocks с gcc/g++, но ему что-то не нравится, и он не говорит что. Пишет мне ошибку:

||error: ld returned 1 exit status|
Может, я что-то делаю не так?

Daniel_Cortez
20.11.2016, 13:51
Пока что ваш вопрос звучит примерно как "у меня какая-то ошибка, сможете угадать, что я делаю не так?" Сомневаюсь, что у нас на форуме есть экстрасенсы.
Нужно больше информации. Выложите хотя бы минимальный проект плагина, на котором можно воспроизвести описанную вами ошибку.

Edwin
20.11.2016, 14:05
Извиняюсь за дубляж в разделе вопросов по pawn, просто мне довольно к спеху

Дело в том, что я и сам не знаю, какая у меня ошибка, компилятор со мной этим не делится
Код на данный момент выглядит примерно так:

#include "edlg.h"




cell AMX_NATIVE_CALL FNC1(AMX *amx, cell *params)
{
/*

*/
return true;
}

PLUGIN_EXPORT unsigned int PLUGIN_CALL Supports()
{
return SUPPORTS_VERSION | SUPPORTS_AMX_NATIVES;
}

PLUGIN_EXPORT bool PLUGIN_CALL Load(void **ppData)
{
pAMXFunctions = ppData[PLUGIN_DATA_AMX_EXPORTS];
logprintf = (logprintf_t) ppData[PLUGIN_DATA_LOGPRINTF];

logprintf("Success");
return true;
}

PLUGIN_EXPORT void PLUGIN_CALL Unload()
{
logprintf(" * unloaded.");
}

AMX_NATIVE_INFO PluginNatives[] =
{
{"plug_func1", FNC1},
{0, 0}
};

PLUGIN_EXPORT int PLUGIN_CALL AmxLoad( AMX *amx )
{
return amx_Register(amx, PluginNatives, -1);
}


PLUGIN_EXPORT int PLUGIN_CALL AmxUnload( AMX *amx )
{
return AMX_ERR_NONE;
}



// edlg.h

#include "SDK/amx/amx.h"
#include "SDK/plugincommon.h"



typedef void(*logprintf_t)(char* format, ...);
extern void *pAMXFunctions;
logprintf_t logprintf;

#define PLUGIN_FUNCTION cell AMX_NATIVE_CALL


static char *pcCreateAndFillStringFromCell(AMX *amx, cell params)
{
char *szDest;
int nLen;
cell *pString;
amx_GetAddr(amx, params, &pString);
amx_StrLen(pString, &nLen);
szDest = new char[nLen + 1];
amx_GetString(szDest, pString, 0, UNLIMITED);
return szDest;
}

Daniel_Cortez
20.11.2016, 14:34
Выложите хотя бы минимальный проект плагина
Когда я говорил "проект", я имел в виду именно весь проект, и не обязательно в том виде, как у вас сейчас, можно вырезать весь основной функционал плагина - главное, чтобы воспроизводилась та ошибка. Именно проект, а не пару исходных файлов, которые по сути здесь бесполезны, т.к. в них всё равно нет никаких синтаксических ошибок. Вполне возможно, что вы что-то напортачили в параметрах компиляции или ещё каких-нибудь настройках проекта.

Ещё могу посоветовать в нижней части окна Code::Blocks переключиться с вкладки "Build log" на "Build messages" - обычно там оседает большая часть сообщений от компилятора и линковщика, без фильтрации, как в Build log. Запостите эти сообщения сюда.

Edwin
20.11.2016, 15:13
Build log:


-------------- Build: Debug in eDialog (compiler: GNU GCC Compiler)---------------

g++ -Wall -fexceptions -g -m64 -c "/home/edwin/Рабочий стол/CodeBlocks Projects/eDialog/main.cpp" -o obj/Debug/main.o
g++ -shared obj/Debug/main.o -o bin/Debug/libeDialog.so -m64
/usr/bin/ld: obj/Debug/main.o: перемещение R_X86_64_32 для `.rodata' не может использоваться при создании разделяемого объекта; перекомпилируйте с -fPIC
obj/Debug/main.o: error adding symbols: Некорректное значение
collect2: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
1 error(s), 0 warning(s) (0 minute(s), 0 second(s))


Build Messages:

||=== Build: Debug in eDialog (compiler: GNU GCC Compiler) ===|
||error: ld returned 1 exit status|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|



- - - Добавлено - - -

Кстати, возможно, имеет значение то, что у меня 64-разрядная х86-совместимая архитектура Линукс

Daniel_Cortez
20.11.2016, 15:32
/usr/bin/ld: obj/Debug/main.o: перемещение R_X86_64_32 для `.rodata' не может использоваться при создании разделяемого объекта; перекомпилируйте с -fPIC
Вот вы и получили ответ на свой вопрос: нужно скомпилировать исходные файлы с ключом -fPIC.
В строке меню (в самом верху окна) выберите "Project" => "Build options...", в открывшемся окне в дереве конфигурации (слева) нажмите на пункт с именем вашего проекта, переключитесь на вкладку "Other compiler options" и добавьте туда строку "-fPIC".


Кстати, возможно, имеет значение то, что у меня 64-разрядная х86-совместимая архитектура Линукс
Не совсем, но близко. Значение имеют ключи компиляции -m32 и -m64. Если указать -m64 (как у вас), то плагин скомпилируется под 64-разрядную архитектуру и сервер не сможет загрузить его. Найдите у себя в параметрах компилятора -m64 и замените на -m32. Выше я написал, как это сделать, только вместо "Other compiler options" нужно смотреть вкладку "Compiler flags".

Edwin
20.11.2016, 15:48
Вот вы и получили ответ на свой вопрос: нужно скомпилировать исходные файлы с ключом -fPIC.
В строке меню (в самом верху окна) выберите "Project" => "Build options...", в открывшемся окне в дереве конфигурации (слева) нажмите на пункт с именем вашего проекта, переключитесь на вкладку "Other compiler options" и добавьте туда строку "-fPIC".

К сожалению, это не помогло



-------------- Build: Debug in eDialog (compiler: GNU GCC Compiler)---------------

g++ -shared obj/Debug/main.o -o bin/Debug/libeDialog.so
/usr/bin/ld: obj/Debug/main.o: перемещение R_X86_64_32 для `.rodata' не может использоваться при создании разделяемого объекта; перекомпилируйте с -fPIC
obj/Debug/main.o: error adding symbols: Некорректное значение
collect2: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
1 error(s), 0 warning(s) (0 minute(s), 0 second(s))




||=== Build: Debug in eDialog (compiler: GNU GCC Compiler) ===|
||error: ld returned 1 exit status|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|



http://storage7.static.itmages.ru/i/16/1120/h_1479642686_7111149_a401a06823.png


Пару раз я пытался скомпилировать это терминалом с ключом -fPIC, и тогда он ругался на вообще внутренние функции SDK, типа amx_Push, и т.д.
Возможно, конечно, я неправильно что-то делал

Edwin
20.11.2016, 17:34
Странно, но после нескольких попыток пересборки (не меняя настроек) он всё-таки скомпилировался
.so-шник получился, но вот работает он почему-то криво:


// архитектура 32
[16:28:53] Loading plugin: eDialog32.so
[16:28:53] Failed (plugins/eDialog32.so: undefined symbol: pAMXFunctions)

// архитектура 64
[16:30:42] Loading plugin: eDialog64.so
[16:30:42] Failed (plugins/eDialog64.so: wrong ELF class: ELFCLASS64)

ziggi
20.11.2016, 18:29
Убери extern отсюда:

extern void *pAMXFunctions;

Edwin
20.11.2016, 20:28
Убери extern отсюда:

extern void *pAMXFunctions;

А его там итак нету
Добавление ситуацию не изменило

Edwin
20.11.2016, 22:24
Стоп, я не там взялся исправлять
Да, на самом деле, void *pAMXFunctions; уже объявлен в одном из файлов SDK. Убрав спецификатор extern, я получил ошибку о том, соответственно, что процедура уже объявлена, и закомментировав её объявление в заголовочном файле, плагин успешно загрузился
Всем большое спасибо, собралась, наконец, за три дня)