вс, 19 авг. 2018 г. в 13:56, TalGloz <glozmantal@xxxxxxxxx>: > > Hello, > > *I have this code for my C extension function. > * > > xtern "C" { // C Headers must be inside exter "C" { } block. > #include <postgres.h> > #include <fmgr.h> > #include <utils/builtins.h> > #include <catalog/pg_type.h> > #include <utils/rel.h> > #include <utils/array.h> > #include <stdlib.h> > #include <stdint.h> > > PG_MODULE_MAGIC; > } > > // CPP Header must be outside extern "C" { } block. > #include <string> > #include <vector> > #include <iostream> > #include <fstream> > #include <sstream> > #include <iterator> // For the ostream_iterator > > // External projects c++ libraries compiled and linked on running 'make'. > #include <seal/seal.h> > #include <thread> > #include <cppcodec/base64_rfc4648.hpp> > > std::stringstream dec(std::string st){ > > // Decode the base64 string into a stringstream > auto decodeBase64 = cppcodec::base64_rfc4648::decode(st); > std::stringstream decodeBase64SS; > std::move(decodeBase64.begin(), decodeBase64.end(), > std::ostream_iterator<unsigned char>(decodeBase64SS)); > > return decodeBase64SS; > } > > std::string enc(std::string st){ > > // Create a vector to hold the raw data > std::vector<uint8_t> encodeStream; > > // Push all the characters from the raw data string into the vector > for (auto &ch : st){ > encodeStream.push_back((unsigned char&&)(ch)); > } > > // Encode the vector as base64 string > std::string encodeBase64 = > cppcodec::base64_rfc4648::encode(encodeStream); > encodeStream.clear(); > return encodeBase64; > > } > > std::string seal_diff_operation(std::string decodedLocalEncParamTmp, > std::string decodedLocalTmp1, std::string decodedLocalTmp2){ > > std::stringstream decodedLocalEncParam; > decodedLocalEncParam.str(decodedLocalEncParamTmp); > std::stringstream decodedLocalT1; > decodedLocalT1.str(decodedLocalTmp1); > std::stringstream decodedLocalT2; > decodedLocalT2.str(decodedLocalTmp2); > > // Execute seal library operations > // Load the ecryption parameters > seal::EncryptionParameters IntegerEncryptorParms; > IntegerEncryptorParms.load(decodedLocalEncParam); > // Set Context and evaluator objects > seal::SEALContext context(IntegerEncryptorParms); > seal::Evaluator evaluator(context); > // Set the Encoder parameters > seal::IntegerEncoder encoder(context.plain_modulus()); > > // Create Ciphertexts and load Chipertext information into them > seal::Ciphertext number1Encoded; > seal::Ciphertext number2Encoded; > seal::Ciphertext diffEncodedResult; > number1Encoded.load(decodedLocalT1); > number2Encoded.load(decodedLocalT2); > > // Do the diff operation on the Ciphertexts and prepare the result > for output > evaluator.sub(number1Encoded, number2Encoded, diffEncodedResult); > std::stringstream encResult; > diffEncodedResult.save(encResult); > > std::string output = enc(encResult.str()); > return output; > > } > > extern "C" { // Usage of CPP functions in the module must be inside extern > "C" { } block. > Datum seal_diff_cpp(PG_FUNCTION_ARGS){ > > // Get the inputs > text *t1 = PG_GETARG_TEXT_PP(0); > text *t2 = PG_GETARG_TEXT_PP(1); > text *encParam = PG_GETARG_TEXT_PP(2); > std::string localT1; > std::string localT2; > std::string localEncParam; > localT1 = text_to_cstring(t1); > localT2 = text_to_cstring(t2); > localEncParam = text_to_cstring(encParam); > > // Decode the parameters > std::stringstream decodedLocalT1 = dec(localT1); > std::stringstream decodedLocalT2 = dec(localT2); > std::stringstream decodedLocalEncParam = dec(localEncParam); > > // Encode the parameters > std::string encodedLocalT1 = enc(decodedLocalT1.str()); > std::string encodedLocalT2 = enc(decodedLocalT2.str()); > std::string outputParam = > seal_diff_operation(decodedLocalEncParam.str(), decodedLocalT1.str(), > decodedLocalT2.str()); > > // Return the result > PG_RETURN_TEXT_P(cstring_to_text_with_len(localT1.c_str(), > localT1.size())); > }; > > PG_FUNCTION_INFO_V1(seal_diff_cpp); > } > > > *And I use this Makefile to create the seal_diff_cpp.so file: > * > > MODULES = seal_diff_cpp > > PG_CONFIG = /usr/pgsql-10/bin/pg_config > PGXS = $(shell $(PG_CONFIG) --pgxs) > INCLUDEDIR = $(shell $(PG_CONFIG) --includedir-server) > INCLUDE_SEAL = /usr/local/include/seal > INCLUDE_SEAL_LIB = /usr/local/lib > INCLUDE_CPPCODEC = /usr/local/include/cppcodec > CXX = g++ > CXXFLAGS = -std=c++17 -fPIC -Wall -Iinclude -Werror -g -O0 -pthread \ > -I$(INCLUDEDIR) -I$(INCLUDE_SEAL) -I$(INCLUDE_CPPCODEC) > LDFLAGS = -L$(INCLUDE_SEAL_LIB) -llibseal.a -lpthread > include $(PGXS) > seal_diff_cpp.so: seal_diff_cpp.o > $(CXX) -Wl,--no-undefined -shared -o seal_diff_cpp.so > seal_diff_cpp.o $(LDFLAGS) > > seal_diff_cpp.o: seal_diff_cpp.cpp > $(CXX) $(CXXFLAGS) -o seal_diff_cpp.o -c seal_diff_cpp.cpp > > *But when I run the make command I get those linker errors > * > > g++ -std=c++17 -fPIC -Wall -Iinclude -Werror -g -O0 -pthread > -I/usr/pgsql-10/include/server -I"/usr/local/include" -o seal_diff_cpp.o -c > seal_diff_cpp.cpp > g++ -Wl,--no-undefined -shared -o seal_diff_cpp.so seal_diff_cpp.o > -L/usr/pgsql-10/lib -L/usr/lib64 -Wl,--as-needed > -Wl,-rpath,'/usr/pgsql-10/lib',--enable-new-dtags > seal_diff_cpp.o: In function > `seal_diff_operation(std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> >, > std::__cxx11::basic_string<char, std::char_traits<char>, > std::allocator<char> >, std::__cxx11::basic_string<char, > std::char_traits<char>, std::allocator<char> >)': > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:72: > undefined reference to `seal::EncryptionParameters::EncryptionParameters()' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:73: > undefined reference to `seal::EncryptionParameters::load(std::istream&)' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:75: > undefined reference to > `seal::SEALContext::SEALContext(seal::EncryptionParameters const&)' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:76: > undefined reference to `seal::Evaluator::Evaluator(seal::SEALContext > const&)' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:78: > undefined reference to > `seal::IntegerEncoder::IntegerEncoder(seal::SmallModulus const&, unsigned > long)' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:84: > undefined reference to `seal::Ciphertext::load(std::istream&)' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:85: > undefined reference to `seal::Ciphertext::load(std::istream&)' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:90: > undefined reference to `seal::Ciphertext::save(std::ostream&) const' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:78: > undefined reference to `seal::IntegerEncoder::~IntegerEncoder()' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:78: > undefined reference to `seal::IntegerEncoder::~IntegerEncoder()' > seal_diff_cpp.o: In function `seal_diff_cpp': > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:106: > undefined reference to `pg_detoast_datum_packed' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:107: > undefined reference to `pg_detoast_datum_packed' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:108: > undefined reference to `pg_detoast_datum_packed' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:112: > undefined reference to `text_to_cstring' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:113: > undefined reference to `text_to_cstring' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:114: > undefined reference to `text_to_cstring' > /etc/opt/pgsql_c_functions/CPP/seal_extension/seal_diff_cpp.cpp:130: > undefined reference to `cstring_to_text_with_len' > seal_diff_cpp.o: In function > `seal::EncryptionParameters::~EncryptionParameters()': > /usr/local/include/seal/encryptionparams.h:48: undefined reference to > `seal::BigPoly::~BigPoly()' > seal_diff_cpp.o: In function `seal::Evaluator::sub(seal::Ciphertext const&, > seal::Ciphertext const&, seal::Ciphertext&)': > /usr/local/include/seal/evaluator.h:205: undefined reference to > `seal::Ciphertext::operator=(seal::Ciphertext const&)' > /usr/local/include/seal/evaluator.h:206: undefined reference to > `seal::Evaluator::sub(seal::Ciphertext&, seal::Ciphertext const&)' > seal_diff_cpp.o: In function `seal::SEALContext::~SEALContext()': > /usr/local/include/seal/context.h:116: undefined reference to > `seal::BigUInt::~BigUInt()' > collect2: error: ld returned 1 exit status > make: *** [Makefile:16: seal_diff_cpp.so] Error 1 > > I can't figure what am I doing wrong? The SEAL library is an external > library installed to /usr/local/include/seal and its libseal.a into > /usr/local/lib/. I was told by the SEAL library creators (Cryptography > Research Group at Microsoft), that all I need is the installd header files > in /usr/local/include/seal and the libseal.a in /usr/local/lib/ so I don't > understand why the linker can't link those functions. You didn't link against libseal upon building seal_diff_cpp.so, but you must -- I don't see something like -lseal in the g++ command string. Try to replace "-llibseal.a" with "-lseal" in LDFLAGS = -L$(INCLUDE_SEAL_LIB) -llibseal.a -lpthread