我正在尝试将一些目标文件包含到我正在构建的共享库中。执行以下命令(为简洁起见,已省略 [ETC] 中的内容):
/usr/bin/c++ -fPIC -std=c++14 -pthread -Iinclude/ext/liveMedia -Iinclude/ext/groupsock [ETC] -g -shared -Wl,-soname,libValkka.so -o lib/libValkka.so CMakeFiles/Valkka.dir/src/avthread.cpp.o CMakeFiles/Valkka.dir/src/opengl.cpp.o [ETC] CMakeFiles/Valkka.dir/src/decoders.cpp.o -lX11 -lGLEW -lGLU -lGL -Wl,--whole-archive lib/libavcodec.a -Wl,--no-whole-archive
/usr/bin/ld: lib/libavcodec.a(h264_cabac.o): relocation R_X86_64_PC32 against symbol 'ff_h264_cabac_tables' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Bad value collect2: error: ld returned 1 exit status
ar x libavcodec.a
readelf --relocs h264_cabac.o | egrep '(GOT|PLT|JU?MP_SLOT)'
00000000175d 003100000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4 000000001926 003100000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
...
objdump -r h264_cabac.o | grep -i "relocation"
最佳答案
TL;博士
添加 -Wl,-Bsymbolic到共享库的 gcc 链接选项。
为什么?
您正在测试 h264_cabac.o 的 PICness和:
readelf --relocs h264_cabac.o | egrep '(GOT|PLT|JU?MP_SLOT)
并得出结论,目标文件是用 -fPIC 编译的如果你得到任何$ git clone https://github.com/FFmpeg/FFmpeg.git
$ cd FFmpeg
$ ./configure --enable-shared
$ make
然后:$ cd libavcodec
$ readelf --relocs h264_cabac.o | egrep '(GOT|PLT|JU?MP_SLOT)'
00000000175d 003100000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000001926 003100000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
00000000259f 003100000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000002f0d 003100000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000003216 003200000004 R_X86_64_PLT32 0000000000000000 av_log - 4
000000003460 00330000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_chroma422_dc_s - 4
000000003afc 003100000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000003fb6 00360000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_i_mb_type_info - 4
000000004031 00370000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_mb_sizes - 4
00000000409a 003800000004 R_X86_64_PLT32 0000000000000000 ff_init_cabac_decoder - 4
000000004248 00390000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_b_mb_type_info - 4
000000004299 003a00000004 R_X86_64_PLT32 0000000000000000 ff_h264_pred_direct_mo - 4
000000004a31 003b00000004 R_X86_64_PLT32 0000000000000000 ff_h264_check_intra4x4 - 4
000000004bd5 003200000004 R_X86_64_PLT32 0000000000000000 av_log - 4
000000004f85 003c0000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_p_mb_type_info - 4
0000000050fd 003d0000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_b_sub_mb_type_ - 4
000000005233 003a00000004 R_X86_64_PLT32 0000000000000000 ff_h264_pred_direct_mo - 4
00000000544a 003200000004 R_X86_64_PLT32 0000000000000000 av_log - 4
000000005bef 003a00000004 R_X86_64_PLT32 0000000000000000 ff_h264_pred_direct_mo - 4
000000006db5 003e00000004 R_X86_64_PLT32 0000000000000000 ff_h264_check_intra_pr - 4
000000006de9 003f0000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_p_sub_mb_type_ - 4
000000007171 003200000004 R_X86_64_PLT32 0000000000000000 av_log - 4
000000008b1b 003e00000004 R_X86_64_PLT32 0000000000000000 ff_h264_check_intra_pr - 4
00000000ad41 004000000009 R_X86_64_GOTPCREL 0000000000000000 ff_h264_chroma_dc_scan - 4
00000000ad84 004000000009 R_X86_64_GOTPCREL 0000000000000000 ff_h264_chroma_dc_scan - 4
00000000b758 003100000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
来自 Ubuntu 16.04 开发包 $ sudo apt-get install libavcodec-dev
$ dpkg -S libavcodec.a
libavcodec-dev:amd64: /usr/lib/x86_64-linux-gnu/libavcodec.a
$ mkdir ~/deleteme
$ cd ~/deleteme
$ ar x /usr/lib/x86_64-linux-gnu/libavcodec.a h264_cabac.o
$ readelf --relocs h264_cabac.o | egrep '(GOT|PLT|JU?MP_SLOT)'
0000000000c7 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
0000000002fa 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
00000000179d 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000001966 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000001b09 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000001d4a 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000001ee5 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
00000000265f 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000002fcd 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
0000000032f6 002f00000004 R_X86_64_PLT32 0000000000000000 av_log - 4
000000003305 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000003bdc 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000003cb5 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
000000004121 00320000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_mb_sizes - 4
000000004187 003300000004 R_X86_64_PLT32 0000000000000000 ff_init_cabac_decoder - 4
000000004381 003400000004 R_X86_64_PLT32 0000000000000000 ff_h264_pred_direct_mo - 4
000000004afe 003500000004 R_X86_64_PLT32 0000000000000000 ff_h264_check_intra4x4 - 4
000000005556 003400000004 R_X86_64_PLT32 0000000000000000 ff_h264_pred_direct_mo - 4
00000000576a 002f00000004 R_X86_64_PLT32 0000000000000000 av_log - 4
000000005acf 003400000004 R_X86_64_PLT32 0000000000000000 ff_h264_pred_direct_mo - 4
000000006e31 002f00000004 R_X86_64_PLT32 0000000000000000 av_log - 4
000000006e58 003600000004 R_X86_64_PLT32 0000000000000000 ff_h264_check_intra_pr - 4
000000009c20 003600000004 R_X86_64_PLT32 0000000000000000 ff_h264_check_intra_pr - 4
00000000b425 002f00000004 R_X86_64_PLT32 0000000000000000 av_log - 4
00000000b5ab 002e00000004 R_X86_64_PLT32 0000000000000000 __stack_chk_fail - 4
结果并不相同,我在第一种方式中获得了 26 次重定位,在第二种方式中获得了 25 次重定位。但是无论哪种方式都有很多 PIC 安全的重定位h264_cabac.o 的两个汇编有 -fPIC ,无论他们有什么其他选择。ff_h264_cabac_tables ,关于您的链接relocation R_X86_64_PC32 against symbol 'ff_h264_cabac_tables' can not be used when making a shared object
不在这些列表中。这意味着这个目标文件 - 来自两个出处 - 包含 PIC 安全和 PIC 不安全的重定位。libavcodec.so成功地?$ readelf --relocs h264_cabac.o | egrep -v '(GOT|PLT|JU?MP_SLOT)'
000000000017 002c00000002 R_X86_64_PC32 0000000000000000 ff_h264_cabac_tables - 4
...
...
好吧,我将省略大约 160 行,但它们都描述了与 PC 相关的类型 R_X86_64_PC32搬迁和提到的唯一符号,折扣部分名称和本地标签,ff_h264_cabac_tables ,关于符号表说:$ readelf -s h264_cabac.o | grep ff_h264_cabac_tables
44: 0000000000000000 0 NOTYPE GLOBAL DEFAULT UND ff_h264_cabac_tables
它是一个全局变量,未在此目标文件中定义。-fPIC没有坏。但是,知道目标文件是用-fPIC不能绝对保证它不包含与 PC 相关的类型R_X86_64_PC32引用未定义的全局符号的重定位。 relocation R_X86_64_PC32 against symbol 'ff_h264_cabac_tables'是R_X86_64_PC32类型重定位采用 32 位 PC 相对寻址模式,relocation R_X86_64_PC32 against symbol 'ff_h264_cabac_tables' can not be used when making a shared object
及其建议:recompile with -fPIC
基于以下假设:罪魁祸首目标文件不是用 -fPIC 编译的.libavcodec.a(h264_cabac.o)编译 -fPIC将保证您的 PIC 安全重定位,前提是编译器h264_cabac.o或者我的任何一个标本。所有这些标本FFmpeg/libavcodec/x86/h264_cabac.c在 FFmpeg 源代码树中。extern 的函数。ff_h264_cabac_tables并以内联方式实现,手工制作-fPIC ,但它没有得到h264_cabac.o只有 PIC 安全的./configure脚本有以下选项:--disable-asm disable all assembly optimizations
其中包括导致 h264_cabac.o 的影响待编译FFmpeg/libavcodec/h264_cabac.c而不是FFmpeg/libavcodec/x86/h264_cabac.c .那么让我们尝试一下:$ cd FFmpeg
$ make clean
$ ./configure --enable-shared --disable-asm
$ make
$ cd libavcodec
$ readelf --relocs h264_cabac.o | grep ff_h264_cabac_tables
00000000000a 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
0000000000ca 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
000000001eb5 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
0000000021c6 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
0000000026fe 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
000000002a17 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
000000002f13 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
00000000324c 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
000000003509 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
00000000362a 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
0000000037d7 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
00000000592b 00300000002a R_X86_64_REX_GOTP 0000000000000000 ff_h264_cabac_tables - 4
现在,所有引用 ff_h264_cabac_tables 的重定位是 PIC 安全的。h264_cabac.o可以链接到共享库中。我们知道ff_h264_cabac_tables在 h264_cabac.o 中未定义,所以我们还需要链接./cabac.o .$ gcc -shared -o libfoo.so h264_cabac.o cabac.o
瞧:$ file libfoo.so
libfoo.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=ed63107b715b357853da94d4a031c0b06c30c5f2, not stripped
您可能仍然会感到有些委屈,但是,如果您必须链接自己的h264_cabac.o和有点失望./configure --enable-shared .R_X86_64_PC32搬迁引用ff_h264_cabac_tables在运行时可能不可行,如果 ff_h264_cabac_tables是动态解决的。不反对类型 R_X86_64_PC32搬迁之类的。这是预防性反对,基于不知道如何ff_h264_cabac_tables最终会得到解决。ff_h264_cabac_tables实际上是在 cabac.o 中定义的然后h264_cabac.o 包含在相同的链接中,就像它们都包含在内libavcodec.so的联动中.我们可以告诉链接器任何全局-Bsymbolic
这将取消其对任何 R_X86_64_PC32 的预防性反对意见。搬迁。R_X86_64_PC32搬迁反对ff_h264_cabac_tables是可行的。如果没有,它会给relocation truncated to fit:.. .否则会成功libavcodec.so在股票 FFmpeg 构建中成功链接。$ cd FFmpeg
$ make clean
$ ./configure --enable-shared
$ make
然后强制重新链接 libavcodec.so :$ rm libavcodec/h264_cabac.o
$ $ make libavcodec/libavcodec.so V=1
gcc -I. -I./ -D_ISOC99_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
-D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -DPIC -DZLIB_CONST -DHAVE_AV_CONFIG_H \
-std=c11 -fomit-frame-pointer -fPIC -pthread -g -Wdeclaration-after-statement \
-Wall -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings \
-Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes \
-Wempty-body -Wno-parentheses -Wno-switch -Wno-format-zero-length -Wno-pointer-sign \
-O3 -fno-math-errno -fno-signed-zeros -fno-tree-vectorize -Werror=format-security \
-Werror=implicit-function-declaration -Werror=missing-prototypes -Werror=return-type \
-Werror=vla -Wformat -fdiagnostics-color=auto -Wno-maybe-uninitialized \
-MMD -MF libavcodec/h264_cabac.d -MT libavcodec/h264_cabac.o -c \
-o libavcodec/h264_cabac.o libavcodec/h264_cabac.c
sed 's/MAJOR/57/' libavcodec/libavcodec.v | cat > libavcodec/libavcodec.ver
gcc -shared -Wl,-soname,libavcodec.so.57 -Wl,-Bsymbolic ... etc. etc. ...
^^^^^^^^^^^^^^
所以不存在汇编编码缺陷。链接手工优化h264_cabac.o在共享库中,您只需要添加 -Wl,-Bsymbolic到 gcc 链接选项。它是$ cd libavcodec/
$ gcc -shared -o libfoo.so h264_cabac.o cabac.o
/usr/bin/ld: h264_cabac.o: relocation R_X86_64_PC32 against symbol `ff_h264_cabac_tables' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
又是你的失败。和:$ gcc -shared -Wl,-Bsymbolic -o libfoo.so h264_cabac.o cabac.o
$ file libfoo.so
libfoo.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=7dc86aeae353c4d92cdb5fa35d169bf019b47eb2, not stripped
成功。
关于c++ - 将对象从 C++ 存档 (.a) 包含到共享库中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46307266/
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我的Gallery模型中有以下查询:media_items.includes(:photo,:video).rank(:position_in_gallery)我的图库模型有_许多媒体项,每个都有一个照片或视频关联。到目前为止,一切正常。它返回所有media_items包括它们的photo或video关联,由media_item的position_in_gallery属性排序。但是我现在需要将此查询返回的照片限制为仅具有is_processing属性的照片,即nil。是否可以进行相同的查询,但条件是返回的照片等同于:.where(photo:'photo.is_processingIS
-if!request.path_info.include?'A'%{:id=>'A'}"Text"-else"Text"“文本”写了两次。我怎样才能只写一次并同时检查path_info是否包含“A”? 最佳答案 有两种方法可以做到这一点。使用部分,或使用content_forblock:如果“文本”较长,或者是一个重要的子树,您可以将其提取到一个部分。这会使您的代码变干一点。在给出的示例中,这似乎有点矫枉过正。在这种情况下更好的方法是使用content_forblock,如下所示:-if!request.path_info.inc
Ocra无法处理需要“tk”的应用程序require'tk'puts'nope'用奥克拉http://github.com/larsch/ocra不起作用(如链接中的一个问题所述)问题:https://github.com/larsch/ocra/issues/29(Ocra是1.9的"new"rubyscript2exe,本质上它用于将rb脚本部署为可执行文件)唯一的问题似乎是缺少tcl的DLL文件我不认为这是一个问题据我所知,问题是缺少tk的DLL文件如果它们是已知的,则可以在执行ocra时将它们包括在内有没有办法知道tk工作所需的DLL依赖项? 最佳答
我正在使用DMOZ的listofurltopics,其中包含一些具有包含下划线的主机名的url。例如:608609TheOuterHeaven610InformationandimagegalleryofMcFarlane'sactionfiguresforTrigun,Akira,TenchiMuyoandotherJapaneseSci-Fianimations.611Top/Arts/Animation/Anime/Collectibles/Models_and_Figures/Action_Figures612虽然此url可以在网络浏览器中使用(或者至少在我的浏览器中可以使用: