2016-06-26 5 views
0

マックOSX上で失敗したが、リンクは次のエラーで失敗しました:PostgreSQLの外部C関数のリンクは、私が<code>clang</code>と<code>gcc</code>の両方で<code>OSX 10.11</code>に外部<code>PostgreSQL</code>機能を構築しようとしている

c++ -I/usr/local/Cellar/postgresql/9.5.3/include/server -fpic -c ./main.c

c++ -shared -o ttt.dylib main.o 
Undefined symbols for architecture x86_64: 
    "_deconstruct_array", referenced from: 
    _psql_nearest in main.o 
    "_elog_finish", referenced from: 
    _psql_nearest in main.o 
    "_elog_start", referenced from: 
    _psql_nearest in main.o 
    "_get_typlenbyvalalign", referenced from: 
    _psql_nearest in main.o 
    "_pfree", referenced from: 
    _psql_nearest in main.o 
    "_pg_detoast_datum", referenced from: 
    _psql_nearest in main.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

ライブラリをPostgreSQLライブラリの一部とリンクする必要があるようです。これらのライブラリは何ですか?

main.cpp: 

extern "C" { 
    #include <postgres.h> 
    #include <fmgr.h> 
    #include <utils/array.h> 
    #include <utils/lsyscache.h> 
    #include <catalog/pg_type.h> 

    #ifdef PG_MODULE_MAGIC 
     PG_MODULE_MAGIC; 
    #endif 

    PG_FUNCTION_INFO_V1(psql_nearest); 
    Datum psql_nearest(PG_FUNCTION_ARGS) { 
     if(PG_ARGISNULL(0) || PG_ARGISNULL(1)) { 
      elog(ERROR, "DOC2VEC: NULL INPUT DATA"); 
      PG_RETURN_NULL(); 
     } 

     ArrayType *_docVector = PG_GETARG_ARRAYTYPE_P(0); 
     Oid elTypeVals = ARR_ELEMTYPE(_docVector); 
     if (elTypeVals != FLOAT4OID) { 
      elog(ERROR, "DOC2VEC: INVALID INPUT DATA TYPE"); 
      PG_RETURN_NULL(); 
     } 

     int16 typeLenVals = 0; 
     bool typeByValVals = false; 
     char typeAlignVals = char(0); 
     get_typlenbyvalalign(elTypeVals, &typeLenVals, &typeByValVals, &typeAlignVals); 

     Datum *inputVals; 
     bool *nullVals; 
     int nVals; 
     deconstruct_array(_docVector, elTypeVals, typeLenVals, typeByValVals, typeAlignVals, &inputVals, &nullVals, &nVals); 

     pfree(inputVals); 
     pfree(nullVals); 

     PG_RETURN_NULL(); 
    } 
} 
+0

あなたの編集はソースコードファイルを 'main.c'から' main.cpp'に変更しましたが、一番上の 'cc'コマンドはまだ' main.c'を持っています。それは 'main.cpp'でもなければなりません。あるいは 'extern" C "の部分を説明するために名前を変更しましたが、実際のファイル名は' main.c'です。それは混乱するだろう。 – Evert

+0

とりわけ、 'pgcommon'とのリンクを試みてください。 'pgfreeはそこに住んでいる '。 – Evert

+0

はい、私は 'のextern "C"'セクションが必要なのか理由を説明するために、 'C++'に 'main.cpp'と' cc'に 'main.c'を変更しました。私はpgcommonにはDYN-libにはありません気付い 'pgcommon'、' pgtypes'、 'pgport'と' libpq' –

答えて

1

PostgreSQL開発者のおかげとの互換性のためのC++ファイルで使用され、彼らは私にLinuxの違いや外部関数のOSXリンクを説明しました。 -sharedの代わりに-bundle -bundle_loader /path/to/postgres, が必要です。他のリンカーフラグもあります。 また、PostgreSQLは、OSXの場合でも、ロード可能モジュールのファイル拡張子が.soであると想定しています。

通常、 の代わりにPGXSを使用して拡張機能を構築することをお勧めします。 またはcontrib/ ソースツリーの拡張機能からベビーベッドを利用できます。

0

あなたはリンクに必要がある場合は、Postgresのライブラリが置かれているパス(-Iコンパイラフラグのリンカに相当)にリンカを指すように-Lフラグが必要になります。ライブラリーを実際にリンクするためのフラグ(各ライブラリーごとに1つ); -lフラグ。ライブラリ名にはlibという接頭辞がなく、拡張子はありません。あなたのケースでは

は、

-L/usr/local/Cellar/postgresql/9.5.3/lib -lpostgresの線に沿って何かを(そのディレクトリ内のライブラリファイルのさまざまあります。で開始する-lpgを試みる
あなたのエラーメッセージに_pfreeへの参照もpgcommonをリンクすることをお勧めします。 、。 )


nm libpgcommon.aを使用したときに、少なくとも)あなたはより多くのビットを読むことをお勧めしますpgreeの実装が含まれています一般的にコンパイルとリンク。 -Iフラグでコンパイルするには正しいことがありますが、リンクする段階で奇妙なことに間違いがあります。 makeとMakefilesについて学ぶことは便利です。
.cファイルの場合は、extern "C" {の部分も分かりません。これは明らかにC専用ファイルです。 extern "C"は通常C.

+0

ありがとうございますが、Linux上ではこのPostgreSQLの外部C関数をリンクするライブラリは必要ありません。 –

+0

私は十分な経験を持っています。私の質問は、PostgreSQLの外部C関数をうまくリンクするためにOSXで必要なライブラリです。 psql_nearest関数の中でC++コードを使うので、extern "C"セクションが必要です。 –

+0

その場合、少しの検索でライブラリを見つけることができます。ファイルが標準の場所にあるため、Linuxではリンカーパスフラグは必要ありません。ただし、postgresライブラリにリンクするには '-l'フラグも必要です。あなたがそれを必要としないなら、怪物(または非標準の設定)があります。標準的な数学ライブラリでさえLinux上で '-lm'が必要です。 – Evert

関連する問題

 関連する問題