PDA

Просмотр полной версии : [10772] [psql] Fix compile on Linux


narma
07.09.2010, 10:02
Исправления не совсем тривиальные, готов к обсуждению.

Источник:
dcabb22276501fc09fbbd4d4b6fc825315472e98
3e9a717de4124b2f32f923b3f23ab46ec21bb547
0078c5db1be2305e4d60da6a3cdbd1b37a6e19ad
b5ecd0c9030b8f3bcff9cd31239334bec89daf6a
в narma/mangos.

narma
08.09.2010, 09:27
Без патча:

../../../../src/shared/Database/QueryResultPostgre.cpp: В функции-члене ‘Field::DataTypes QueryResultPostgre::ConvertNativeType(Oid) const’:
../../../../src/shared/Database/QueryResultPostgre.cpp:84:14: ошибка: нет декларации ‘BPCHAROID’ в этой области видимости
../../../../src/shared/Database/QueryResultPostgre.cpp:85:14: ошибка: нет декларации ‘CIDOID’ в этой области видимости
../../../../src/shared/Database/QueryResultPostgre.cpp:86:14: ошибка: нет декларации ‘CIDROID’ в этой области видимости\
...


А всё потому, что:

#ifdef WIN32
#define FD_SETSIZE 1024
#include <winsock2.h>
#include <postgre/libpq-fe.h>
#include <postgre/pg_type.h>
#else
#include <libpq-fe.h>
//#include <pg_type.h>
#endif


в линуксе ( фриибсд? ) <pg_type.h> находиться либо в server/pg_type.h либо server/catalog/pg_type.h. Просто так его не подключишь.

narma
08.09.2010, 09:37
Теперь о самом патче:

diff --git a/configure.ac b/configure.ac
index 931543f..cd00bcc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -124,10 +124,45 @@ AC_ARG_WITH(mysql,
AC_MSG_CHECKING(whether to build/link POSTGRESQL)
if test "x$DO_POSTGRESQL" = "xyes"; then
DO_MYSQL=no
-POSTGRE_INCLUDES="-I/usr/include/postgresql $POSTGRE_INCLUDES"
-POSTGRE_LIBS="-L/usr/lib/postresql -lpq -lz -lpthread -lcrypt -lnsl -lm -lpthread -L/usr/lib $OPENSSL_LIBS $POSTGRE_LIBS "
+POSTGRE_INC_DIR="`pg_config --includedir`"
+POSTGRE_INCLUDES="-I${POSTGRE_INC_DIR} -I\$(top_builddir)/src/shared/Database $POSTGRE_INCLUDES"
+POSTGRE_LIBS="-L`pg_config --libdir` -lpq -lz -lpthread -lcrypt -lnsl -lm -lpthread -L/usr/lib $OPENSSL_LIBS $POSTGRE_LIBS "
CXXFLAGS="-DDO_POSTGRESQL $CXXFLAGS"

Include и Lib директорию получаем из pg_config и добавляем $(top_builddir)/src/shared/Database для видимости pg_type.h, потом объясню зачем.


+AC_CHECK_FILE("${POSTGRE_INC_DIR}/catalog/pg_type.h",[PGTYPE="${POSTGRE_INC_DIR}/catalog/pg_type.h"],
+ [AC_CHECK_FILE("${POSTGRE_INC_DIR}/server/catalog/pg_type.h", [PGTYPE="${POSTGRE_INC_DIR}/server/catalog/pg_type.h"],
+ [AC_MSG_ERROR(can't find pg_type.h under ${POSTGRE_INC_DIR})]
+ )]
+)

Ищем тот самый pg_type.h


+AC_MSG_NOTICE([Checking for postgresql libs is thread-safe])
+LIBS="$LIBS $POSTGRE_LIBS"
+CXXFLAGS="$CXXFLAGS $POSTGRE_INCLUDES"
+AC_RUN_IFELSE(
+ [
+ AC_LANG_SOURCE(
+ [[
+ #include <libpq-fe.h>
+
+ int main() {
+ return !PQisthreadsafe();
+ }
+ ]])
+ ],
+ [
+ AC_MSG_NOTICE([ok])
+ ],
+ [
+ AC_MSG_ERROR([postgre libs is not thread-safe, check your postgresql installation and /etc/ld.config*])
+ ])

Проверяем что используемые библиотеки будут thread-safe. Мангос делает тоже самое, так что лучше сразу узнать об этом.


+AC_CONFIG_COMMANDS_PRE([
+pg_type_content="`awk '/#define .+OID/ {np2=2; np3=3; print "#define "$np2" "$np3}' $PGTYPE`"
+AC_SUBST(pg_type_content)
+AC_CONFIG_FILES([src/shared/Database/pg_type.h])
+])
fi
+AC_MSG_RESULT($DO_POSTGRESQL)

Получаем из pg_type.h все OID'ы и вставляем их в наш src/shared/Database/pg_type.h. Выше мы добавили путь до него в MANGOS_INCLUDE - без этого не компилялся скриптдев.


diff --git a/src/shared/Database/Makefile.am b/src/shared/Database/Makefile.am
index 311ce93..dfc9f2f 100644
--- a/src/shared/Database/Makefile.am
+++ b/src/shared/Database/Makefile.am
@@ -55,3 +55,7 @@ libmangosdatabase_a_SOURCES = \
SqlDelayThread.h \
SqlOperations.cpp \
SqlOperations.h
+
+EXTRA_DIST = \
+ pg_type.h
+
diff --git a/src/shared/Database/QueryResultPostgre.h b/src/shared/Database/QueryResultPostgre.h
index 420b685..4db93fa 100644
--- a/src/shared/Database/QueryResultPostgre.h
+++ b/src/shared/Database/QueryResultPostgre.h
@@ -25,8 +25,8 @@
#include <postgre/libpq-fe.h>
#include <postgre/pg_type.h>
#else
+#include "pg_type.h"
#include <libpq-fe.h>
-//#include <pg_type.h>
#endif

class QueryResultPostgre : public QueryResult
diff --git a/src/shared/Database/pg_type.h.in b/src/shared/Database/pg_type.h.in
new file mode 100644
index 0000000..83017e2
--- /dev/null
+++ b/src/shared/Database/pg_type.h.in
@@ -0,0 +1,4 @@
+#if !defined(PG_TYPE_H)
+#define PG_TYPE_H
+@pg_type_content@
+#endif


Тут вроде и так всё понятно, вот вообщем-то это весь патч для успешной компиляции, далее исправления для postgresql.


diff --git a/src/realmd/RealmList.cpp b/src/realmd/RealmList.cpp
index 1e34b05..b05b804 100644
--- a/src/realmd/RealmList.cpp
+++ b/src/realmd/RealmList.cpp
@@ -93,7 +93,7 @@ void RealmList::UpdateRealm( uint32 ID, const std::string& name, const std::stri
realm.allowedSecurityLevel = allowedSecurityLevel;
realm.populationLevel = popu;

- Tokens tokens = StrSplit(builds, " ");
+ Tokens tokens = StrSplit(builds ? builds : "", " ");
Tokens::iterator iter;

for (iter = tokens.begin(); iter != tokens.end(); ++iter)

Если база девственно чиста builds == 0x0, и в этом месте сегфолтиться, видимо с mysql builds будет равен "\0".

diff --git a/src/shared/Database/DatabasePostgre.cpp
b/src/shared/Database/DatabasePostgre.cpp
index 7eb2584..5f2b4d2 100644
--- a/src/shared/Database/DatabasePostgre.cpp
+++ b/src/shared/Database/DatabasePostgre.cpp
@@ -95,6 +95,7 @@ bool DatabasePostgre::Initialize(const char *infoString)
sLog.outError( "Could not connect to Postgre database at %s: %s",
host.c_str(), PQerrorMessage(mPGconn));
PQfinish(mPGconn);
+ mPGconn = NULL;
return false;
}
else

Если коннект к базе не удался то PQfinish мы делаем тут, и ещё раз в деструкторе если mPGconn не NULL -- segfault с double-free.

narma
09.09.2010, 09:45
Мейнтейнеры, прошу обратить внимание на тему. На главной getmangos заявлена поддержка MySQL и PostgreSQL, но компиляция с поддержкой последнего под линукс невозможна. Я считаю это серьёзной недоработкой, несмотря на то, что много чаще используют MySQL.

Автор изменений я, так что если есть спорные, вызывающие сомнения моменты\куски кода - спрашивайте. Если будет необходимость подправить патч или разобраться в детали которую я пропустил я этим также займусь.

Dereka
10.09.2010, 22:10
компиляция невозможно, во многом из за pg_type.h
хидер вообще не из libpg :/ там по моему этих констант нету(
может есть какой то другой способ для
QueryResultPostgre::ConvertNativeType ?

Vladimir
11.09.2010, 14:21
Можно ли сделать без создания pg_type.h в проекте.
Передавать путь к нему из configure может быть...

narma
11.09.2010, 18:24
компиляция невозможно, во многом из за pg_type.h
хидер вообще не из libpg :/ там по моему этих констант нету(
может есть какой то другой способ для
QueryResultPostgre::ConvertNativeType ?
Если речь про debian-based дистрибутивы, то есть в пакете libpq-dev (http://packages.debian.org/sid/i386/libpq-dev/filelist). Интересно, в Windows он сразу видимо есть ?

QueryResultPostgre::ConvertNativeType - не знаю, много где к OID привязывают :)

http://www.postgresql.org/docs/8.4/interactive/xfunc-c.html#XFUNC-C-TYPE-TABLE вот интересная дока, но насколько я понял это требует написания функций для psql вида:

CREATE FUNCTION add_one(double precision) RETURNS double precision
AS 'DIRECTORY/funcs', 'add_one_float8'
LANGUAGE C STRICT;


Текущий конвертор работает, нужны только OID'ы.
Я пробовал подключить напрямую pg_type.h, в итоге:

/usr/include/postgresql-9.0/server/catalog/pg_type.h:37:1: ошибка: expected ‘)’ before ‘,’ token
/usr/include/postgresql-9.0/server/catalog/pg_type.h:214:3: предупреждение: data definition has no type or storage class
/usr/include/postgresql-9.0/server/catalog/pg_type.h:221:26: ошибка: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token

Поэтому ищу его и выдираю OID'ы.

Можно ли сделать без создания pg_type.h в проекте.
Передавать путь к нему из configure может быть...
В том-то и дело, список OID'ов либо можно захардкодить у себя ( что в принципе многие и делают, видимо редко меняются), либо вытащить и положить куда-нибудь.
Ну и pg_type.h должен быть либо в INCLUDE_PATH либо его содержимое должно быть внутри QueryResultPostgre.h ( если он больше нигде не используется - если идти в этом направлении это надо проверить ).

narma
11.09.2010, 18:35
Залил новый патч, теперь совсем всё кошерно ( или нет ?).

1) возможность указать с помощью --with-postgresql
конкретную инсталяцию postgresql ( у меня на машинке допустим 8.4 и 9.0)
2) теперь CXXFLAGS и LDFLAGS восстанавливаются в прежние значения,
после проверки библиотек Postgresql и установки их значений для этого.
3) дополнительные проверки на библиотеку и заголовочный файл.
4) косметические правки.

Vladimir
11.09.2010, 18:45
В том-то и дело, список OID'ов либо можно захардкодить у себя ( что в принципе многие и делают, видимо редко меняются), либо вытащить и положить куда-нибудь.
Ну и pg_type.h должен быть либо в INCLUDE_PATH либо его содержимое должно быть внутри QueryResultPostgre.h ( если он больше нигде не используется - если идти в этом направлении это надо проверить ).
вы-ж содержание pg_type.h от куда-то берете, так почему не передавать к файлу путь вместо содежимого. Мне просто ненравится еще один левый файл в shared

narma
11.09.2010, 19:00
вы-ж содержание pg_type.h от куда-то берете, так почему не передавать к файлу путь вместо содежимого. Мне просто ненравится еще один левый файл в shared

Мне самому не нравится. Только я не понял что вы имеете ввиду, куда передавать путь ? К INCLUDE_PATH ? Дык, я же писал, если напрямую его подключать, то вылезает:

/usr/include/postgresql-9.0/server/catalog/pg_type.h:37:1: ошибка: expected ‘)’ before ‘,’ token
/usr/include/postgresql-9.0/server/catalog/pg_type.h:214:3: предупреждение: data definition has no type or storage class
/usr/include/postgresql-9.0/server/catalog/pg_type.h:221:26: ошибка: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token


Сам файл находиться /usr/include/postgresql/server/catalog/pg_type.h ( в 8.4 и выше )либо в /usr/include/postgresql/catalog/pg_type.h ( в 7-ой версии).

narma
11.09.2010, 19:13
Собственно про два выхода ( которые я вижу) из ситуации я уже написал:
1) Без нового файла:
*) Хардкодим OID'ы в QueryResultPostgre.h
*) Вытаскиваем OID'ы и пихаем туда же.
Однако QueryResultPostgre.h превратиться в QueryResultPostgre.h.in и компиляция под Windows наркывается медным тазом, или нет ?

2) С новым файлом:
*) Хардкодим OID'ы в какой-нибудь новый хидер ( местоположение ещё можно поменять )
*) Вытаскиваем в какой-нибудь новый хидер ( мой патч работает так ). -

Новый файл должен быть в MANGOS_INCLUDE.

Плюсы если хардкодить: зависимостей меньше, хитрого кода в configure.ac меньше.
Минусы, понятно, хардкод есть хардкод.

narma
11.09.2010, 23:20
Теперь патч работает и на FreeBSD, проверял на 8.0-STABLE.

diff по сравнению с последним патчем:

1) Ищем pg_type.h в `pg_config --pkgincludedir`
так как это более правильный способ вместо --includedir.
В линуксе пути совпадают, во FreeBSD нет.

2) Заменил вручную прописанные LIBS для POSTGRES на `pg_config --libs`
( они реально нужны ? в ванильном мангосе по крайней мере есть)
В FreeBSD -lnsl, который там был, нету, так как это часть glibc.

3) Заменил LDFLAGS и CXXFLAGS на LIBS и CPPFLAGS.
CPPFLAGS используется для CC и CXX компиляторов ( в отличии от CXXFLAGS), а на FreeBSD используется CC для AC_CHECK_HEADER. ( теперь же флаги будут передаваться хоть для CC хоть для CXX )

4) небольшой фикс: Показываем результат "no" для несработавшей проверки на thread-safe для PostgreSQL библиотек.

Vladimir
11.09.2010, 23:36
Гр... вы можете засунуть путь или полное имя файла в define
#include разрешает использовать define-ы в себе

narma
11.09.2010, 23:57
Гр... вы можете засунуть путь или полное имя файла в define
#include разрешает использовать define-ы в себе

Опять не могу понять о чем речь, не улавливаю ваш контекст. Какой путь ? Какого файла ? В какой #define ? Каким образом мы избавимся от необходимости создавать дополнительный файл ? Растолкуйте пожалуйста.

Vladimir
12.09.2010, 00:09
Сам файл находиться /usr/include/postgresql/server/catalog/pg_type.h ( в 8.4 и выше )либо в /usr/include/postgresql/catalog/pg_type.h ( в 7-ой версии).
Это что не пути? разве их при обнаружении нельзя засунуть в define а потом использовать
#include PG_TYPE_H_PATH

narma
12.09.2010, 00:14
Гр.. ага :)
Если их подключать схватим это: ( третий раз пишу )

/usr/include/postgresql-9.0/server/catalog/pg_type.h:37:1: ошибка: expected ‘)’ before ‘,’ token
/usr/include/postgresql-9.0/server/catalog/pg_type.h:214:3: предупреждение: data definition has no type or storage class
/usr/include/postgresql-9.0/server/catalog/pg_type.h:221:26: ошибка: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token


Я оттуда ( из pg_type.h в /usr/include/postgresq.... )выдергиваю только OID'и и создаю файл pg_type.h в проекте из pg_type.h.in. Надо было мне их назвать по другому, чтобы не было путаницы.

narma
12.09.2010, 00:21
На вскидку, кто чего придумывает на эту же тему.
драйвера питона для постгрес:
pg8000: хардкодит OID'ы у себя в проекте
psycopg2: И хардкодит и вытаскивает из /usr/include/postgresql* таким же способом.

Vladimir
12.09.2010, 01:51
теперь понял... при таком геморое проще прохардкодить с коментарием...

narma
12.09.2010, 05:18
Вариант с хардкодом, задефайнил только используемые OID'ы. Проверил конфигурирование в FreeBSD и Linux, компиляцию в Linux ( в FreeBSD с tbb проблемы какие-то ).

Так-же проверил используемые OID'ы в версиях PostgreSQL 7.4, 8.4, 9.0_beta_4 - везде совпадают.

SeT
22.11.2010, 00:16
ap...

Vladimir
22.11.2010, 01:05
PosgreSQL часть В [10772] спасибо :)

+ Tokens tokens = StrSplit(builds ? builds : "", " ");
Вместо добавления хаков исправил в [10773] другим способом.