Просмотр полной версии : [Вопрос] Компилятор плагина под Линукс
Парни, подскажите , пожалуйста, способ и программу компиляции динамической библиотеки .so под Линуксом
Пробую Code::Blocks с gcc/g++, но ему что-то не нравится, и он не говорит что. Пишет мне ошибку:
||error: ld returned 1 exit status|
Может, я что-то делаю не так?
Daniel_Cortez
20.11.2016, 13:51
Пока что ваш вопрос звучит примерно как "у меня какая-то ошибка, сможете угадать, что я делаю не так?" Сомневаюсь, что у нас на форуме есть экстрасенсы.
Нужно больше информации. Выложите хотя бы минимальный проект плагина, на котором можно воспроизвести описанную вами ошибку.
Извиняюсь за дубляж в разделе вопросов по 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. Запостите эти сообщения сюда.
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".
Вот вы и получили ответ на свой вопрос: нужно скомпилировать исходные файлы с ключом -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, и т.д.
Возможно, конечно, я неправильно что-то делал
Странно, но после нескольких попыток пересборки (не меняя настроек) он всё-таки скомпилировался
.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)
Убери extern отсюда:
extern void *pAMXFunctions;
Убери extern отсюда:
extern void *pAMXFunctions;
А его там итак нету
Добавление ситуацию не изменило
Стоп, я не там взялся исправлять
Да, на самом деле, void *pAMXFunctions; уже объявлен в одном из файлов SDK. Убрав спецификатор extern, я получил ошибку о том, соответственно, что процедура уже объявлена, и закомментировав её объявление в заголовочном файле, плагин успешно загрузился
Всем большое спасибо, собралась, наконец, за три дня)
Powered by vBulletin® Version 4.2.0 Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot