我试图在我的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
重新编译它,但我不知道怎么做。任何帮助表示赞赏。
答案 0 :(得分:59)
简而言之,错误意味着无法使用静态库与动态库进行链接。 正确的方法是将libavcodec编译成.so而不是.a,因此您尝试构建的另一个.so库将很好地链接。
最简单的方法是在--enable-shared
个选项中添加./configure
。
甚至你可能会尝试禁用共享(或静态)库...你选择适合你的东西!
答案 1 :(得分:14)
您可以尝试使用以下方式全局添加标记: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),它解决了问题。
参考: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;