创建共享对象时无法使用针对“.rodata.str1.1”构建 UDF mysql:relocation R_X86_64_32 时出错;使用 -fPIC 重新编译

error building UDF mysql:relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC

我正在尝试使用 rake 构建一个 UDF 库:

task :compile do
    system("gcc -L/usr/local/lib -lgmp -lpaillier `mysql_config --cflags` -c -fPIC #{FILE}.c")
    system("ar -x /usr/local/lib/libpaillier.a")
    system("gcc -shared *.o -L/usr/lib/x86_64-linux-gnu/ -lgmp -o #{LIBFILE}")
    system("sudo mv #{LIBFILE} /usr/lib/mysql/plugin/")
end

但我收到此错误:

/usr/bin/ld: paillier.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
paillier.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status

这里:

gcc -L/usr/local/lib -lgmp -lpaillier `mysql_config --cflags` -c -fPIC #{FILE}.c

您正在编译一个 object 文件,其名称将是 #{FILE}.o 的值 - 假设它是 aa.o - 你正在用 Position-Independent 代码编译它 (-fPIC)。您的 linker 标志:

-L/usr/local/lib -lgmp -lpaillier

在这里没有任何用处,因为没有 linking 被忽略。

这里:

ar -x /usr/local/lib/libpaillier.a

您正在从静态库 /usr/local/lib/libpaillier.a 中提取所有 object 文件。实际上只有 库中有一个 object 个文件,paillier.o

这里:

gcc -shared *.o -L/usr/lib/x86_64-linux-gnu/ -lgmp -o #{LIBFILE}

您正在构建一个共享库,其名称将是 #{LIBFILE} 的值 - 假设它是 libfoo.so - linking object 文件 aa.o, paillier.o, 加上 libgmp.

正在使用 libfoo.so 将 object 文件 paillier.olibpaillier.a 提取到 link 与 not 提取它并简单地 linking 没有什么不同 libpaillier.a 本身,即与:

没有什么不同
gcc -shared #{FILE}.o -L/usr/local/lib -lpaillier -L/usr/lib/x86_64-linux-gnu/ -lgmp -o #{LIBFILE}

以及 linkage 库路径:

-L/usr/local/lib -L/usr/lib/x86_64-linux-gnu/

是多余的,因为这两个路径都是您系统上的默认 linker 搜索路径。

但是必须完全从 PIC object 代码 构建共享库。 aa.o 已编译 -fPIC,第一步。但是,paillier.o 并非如此。所以 linkage 失败了 linker 建议您 paillier.o 必须用 -fPIC.

重新编译

那么做:-

删除现有的 /usr/local/lib/libpaillier.a/usr/local/include/paillier.h

返回您的 libpaillier 源目录(您第一次构建它的地方)。

清理它:

$ make clean

重新配置 autotools 构建系统以编译 PIC 代码:

$ ./configure CFLAGS=-fPIC [and whatever other options you used before]

重建:

$ make

重新安装:

$ sudo make install

现在你又有了 header /usr/local/include/paillier.h 和 一个静态库 /usr/local/lib/libpaillier.a 但这次 库中的paillier.o是PIC码。

然后你可以构建你的插件:

task :compile do
    system("gcc `mysql_config --cflags` -c -fPIC #{FILE}.c")
    system("gcc -shared #{FILE}.o -lpaillier -lgmp -o #{LIBFILE}")
    system("sudo mv #{LIBFILE} /usr/lib/mysql/plugin/")
end