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. Thanks a lot, Tal -- Sent from: http://www.postgresql-archive.org/PostgreSQL-general-f1843780.html