如何使用-fPIC重新编译

时间:2012-12-11 01:23:16

标签: c++ gcc compilation ffmpeg fpic

我试图在我的ARM Ubuntu机器上重新安装我的ffmpeg,跟随此guide。不幸的是,当我编译一个使用这个lib的程序时,我得到以下失败:

/usr/bin/ld: /usr/local/lib/libavcodec.a(amrnbdec.o): relocation R_ARM_MOVW_ABS_NC against `a local symbol' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libavcodec.a: could not read symbols: Bad value
collect2: ld returned 1 exit status

现在我想用编译器建议的-fPIC重新编译它,但我不知道怎么做。任何帮助表示赞赏。

8 个答案:

答案 0 :(得分:59)

简而言之,错误意味着无法使用静态库与动态库进行链接。 正确的方法是将libavcodec编译成.so而不是.a,因此您尝试构建的另一个.so库将很好地链接。

最简单的方法是在--enable-shared个选项中添加./configure。 甚至你可能会尝试禁用共享(或静态)库...你选择适合你的东西!

答案 1 :(得分:14)

查看this page.

您可以尝试使用以下方式全局添加标记:export CXXFLAGS="$CXXFLAGS -fPIC"

答案 2 :(得分:6)

在配置步骤之后,您可能有一个makefile。在这个makefile里面寻找CFLAGS(或类似的)。 puf -fPIC结束并再次运行make。换句话说-fPIC是一个编译器选项,必须在某处传递给编译器。

答案 3 :(得分:1)

我在尝试在Centos 7上安装Dashcast时遇到了同样的问题。此修复程序是在x264 Makefile中每个CFLAGS的末尾添加-fPIC。然后,我必须同时为x264和ffmpeg运行make distclean,然后重新构建。

答案 4 :(得分:1)

在为Android x86_64目标平台(使用Android NDK铛)构建FFMPEG静态库(例如libavcodec.a)时遇到了这个问题。与我的库进行静态链接时,尽管所有的FFMPEG C->目标文件(* .o)都使用-fPIC编译选项进行了编译,但还是出现了问题:

x86_64/libavcodec.a(h264_qpel_10bit.o): 
requires dynamic R_X86_64_PC32 reloc against 'ff_pw_1023' 
which may overflow at runtime; recompile with -fPIC

仅对于libavcodec.a和libswscale.a出现此问题。

此问题的根源是 FFMPEG具有针对x86 *平台的汇编程序优化,例如报告的问题原因在 libavcodec / h264_qpel_10bit.asm -> h264_qpel_10bit.o中。

在生成X86-64位静态库(例如libavcodec.a)时,它看起来像汇编文件(例如libavcodec / h264_qpel_10bit.asm)。使用某些x86(32位)汇编器命令,这些命令与x86-静态链接时不兼容64位目标库,因为它们不支持所需的重定位类型。

可能的解决方案

  1. 在不进行汇编程序优化的情况下编译所有ffmpeg文件(对于ffmpeg,这是配置选项:--disable-asm)
  2. 产生动态库(例如libavcodec.so)并动态链接到最终库中

我选择了1),它解决了问题。

参考:https://tecnocode.co.uk/2014/10/01/dynamic-relocs-runtime-overflows-and-fpic/

答案 5 :(得分:1)

如果您正在构建共享库但需要与静态 libavcodec 链接,请添加链接器标志:

import express from 'express';
import dotenv from 'dotenv';
import colors from 'colors';
import cors from 'cors';
import connectDB from './config/db.js';
import productRoutes from './routes/productRoutes.js';
import path from 'path';
import twilio from 'twilio';
const VoiceResponse = twilio.twiml.VoiceResponse;
// import { CompositionInstance } from 'twilio/lib/rest/video/v1/composition';
import { Server } from 'socket.io';

dotenv.config();

connectDB();

const app = express();
app.use(cors());

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.set('view engine', 'pug');
// app.set('views', path.join(__dirname, 'views'));
app.set('views', path.join(path.resolve(), 'views'));

app.use('/api/products', productRoutes);

app.get('/', (req, res) => {
  res.send('API is running');
});

app.post('/twilioCallback', async (req, res, next) => {
  const status = req.body.StatusCallbackEvent;
  io.emit('status-update', status);
  return res.status(200).send(status);
});

const PORT = process.env.PORT || 5000;

const server = app.listen(
  PORT,
  console.log(`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`.yellow.bold)
);

const io = new Server(server);

io.on('connection', (socket) => {
  console.log('Socket connected!');
});

如果是 cmake:

import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { Row, Col, Image, ListGroup, Card, Button } from 'react-bootstrap';
import Rating from '../components/Rating';
import io from 'socket.io-client';
import axios from 'axios';

const ProductScreen = ({ match }) => {
  const [product, setProduct] = useState({});

  const socket = io({ transports: ['websocket', 'polling'] });
  socket.on('status-update', function (call) {
    const stext = document.getElementById('statusText');
    stext.innerText = call;
    // let statusUpdate;

    // switch (status) {
    //   case 'composition-request':
    //     statusUpdate = 'Sent request for composition. ✉️';
    //     break;

    //   default:
    //     statusUpdate = status;
    //     break;
    // };
  });

  useEffect(() => {
    console.log('about to fetch product');
    const fetchProduct = async () => {
      console.log('Below is the id param waht the fuck is it?');
      console.log(match.params.id);
      const { data } = await axios.get(`http://localhost:5000/api/products/${match.params.id}`);

      setProduct(data);
    };
    fetchProduct();
  }, [match]);

  return (
    <>
      <Link className='btn btn-light my-3' to='/'>
        Go Back
      </Link>
      <Row>
        <Col md={6}>
          <Image src={product.image} alt={product.name} fluid />
        </Col>
        <Col md={3}>
          <ListGroup variant='flush'>
            <ListGroup.Item>
              <h3>{product.name}</h3>
            </ListGroup.Item>
            <ListGroup.Item>
              <Rating value={product.rating} text={`${product.numReviews} reviews`} />
            </ListGroup.Item>
            <ListGroup.Item>Price : {product.price}</ListGroup.Item>
            <ListGroup.Item>Description : {product.description}</ListGroup.Item>
          </ListGroup>
        </Col>
        <Col md={4}>
          <Card>
            <ListGroup variant='flush'>
              <ListGroup.Item>
                <Row>
                  <Col>Price: </Col>
                  <Col>
                    <strong>${product.price}</strong>
                  </Col>
                </Row>
              </ListGroup.Item>
            </ListGroup>
            <ListGroup variant='flush'>
              <ListGroup.Item>
                <Row>
                  <Col>Status: </Col>
                  <Col>{product.countInStock > 0 ? 'In Stock' : 'Out of Stock'}</Col>
                </Row>
              </ListGroup.Item>
              <ListGroup.Item>
                <Button
                  //   onClick={addToCartHandler}
                  className='btn-block w-100'
                  type='button'
                  disabled={product.countInStock === 0}
                >
                  Add To Cart
                </Button>
              </ListGroup.Item>
              <ListGroup.Item>
                <Row>
                  <Col>Copy Status: </Col>
                  <Col>
                    <product id='statusText'>null</product>
                  </Col>
                </Row>
              </ListGroup.Item>
            </ListGroup>
          </Card>
        </Col>
      </Row>
    </>
  );
};

export default ProductScreen;

答案 6 :(得分:0)

除了这里的好答案,特别是罗伯特·卢霍的答案。

我想说的是,我一直在故意尝试静态编译ffmpeg版本。所有必需的依赖项以及迄今为止需要满足的其他条件,我都完成了静态编译。

当我为ffmpeg进程运行./configure时,我没有注意到--enable-shared在命令行中。删除它并运行./configure才可以正确编译(ffmpeg二进制文件全部56 mbs)。还要检查一下您是否打算静态编译

答案 7 :(得分:-1)

在编译之前确保&#34; rules.mk&#34;文件在Makefile中正确包含或通过以下方式明确包含:

&#34; source rules.mk&#34;