• make编译出错Relocations in generic ELF (EM: 62)


    参考:编译出错Relocations in generic ELF (EM: 62)

    • main.o: Relocations in generic ELF (EM: 62)
      错误信息是:
      在这里插入图片描述
    • 通过查看文件 main.o, 发现ELF 64bit , x86-64,在嵌入式中应该用ARM架构,不是x86
      在这里插入图片描述
    • 解决1:删除main.o 再次 make -j 4
      但是又出现了,其他.o文件,也出现同一的情况
    • 解决2:make clean 再次 make -j 4
      但是又出现了,main.o文件,main.o: Relocations in generic ELF (EM: 62)
    • 解决3:连续执行5次make clean,再次 make -j 4
      问题解决:
      在这里插入图片描述

    其实是因为在别人电脑拿到代码,Makefile编译路径不一样,导致的

    qmake -o Makefile xxxx.pro
    
    • 1

    如果是特殊路径的qmake,可以打开Makefile,开头有写Makefile生产方法
    在这里插入图片描述

    我的执行,
    /opt/rk3288/qt-new/bin/qmake -o Makefile Safbox_GUI.pro
    就重新生成Makefile了
    
    • 1
    • 2
    • 3

    需要换成你的编译链qmake所在位置

    • 使用whereis qmake 就找到了
      在这里插入图片描述

    1. 预编译 — > 编译 — > 汇编 — > 链接
    1、预编译:预处理器对c程序进行一些预处理工作,例如对宏定义的变量进行替换;
        1)将所有的#define删除,并展开所有的宏定义;
        2)处理所有的预编译指令,例如:#if,#elif,#else,#endif;
        3)处理#include预编译指令,将被包含的文件插入到预编译指令的位置;
        4)添加行号信息文件名信息,便于调试;
        5)删除所有的注释:// /**/;
        6)保留所有的#pragma编译指令,因为在编写程序的时候,我们经常要用到#pragma指令来 设定编译器的状态
                                                                        或者是指示编译器完成一些特定的动作;
        最后生成.i文件;
        总的来说,包括(1)去注释 (2)宏替换 (3)头文件展开 (4)条件编译
        
    2、编译:编译器将c语言程序翻译成汇编语言程序;
        1)扫描,语法分析,语义分析,源代码优化,目标代码生成,目标代码优化;
        2)生成汇编代码;
        3)汇总符号;
        4)生成.s文件;
        
    3、汇编:汇编语言通过汇编器编译成可重定位目标程序.o,与之相反称为反汇编;
        1)根据汇编指令和特定平台,把汇编指令翻译成二进制形式;
        2)合并各个section,合并符号表;
        3)生成.o文件;
        
    4、链接:将目标文件和所需的库函数用链接器进行链接,常见的链接器有Unix;
        1)合并各个.obj文件的section,合并符号表,进行符号解析;
        2)符号地址重定位;
        3)生成可执行文件;
    
    预处理:    gcc -E project.c -o project.i //宏展开,宏替换 
    编译:    gcc -S project.i -o project.s //将目标文件编译成汇编文件
    汇编:    gcc -c project.s -o project.o //汇编成二进制文件
    链接:    gcc project.o -o project  //加载库文件,生成可执行文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    注意:
    头文件不参与编译

    1. 简单说⼏个你使⽤过的⼆进制⼯具集

    gcc g++ gdb
    链接器 :ld [将.o文件链接生成一个.elf文件]
    目标拷贝/格式化工具 : objcopy [将elf文件转换生成bin的文件]
    反汇编工具 : objdump [将elf文件反汇编生成dis的反汇编文件]
    查看文件符号表 : nm [查看elf文件的符号表]
    查看二进制文件各个段的大小 :size [查看elf文件中各个段的大小]
    获取 elf 文件信息的 :readelf [读取elf文件的信息]
    压缩文件体积 : strip
    根据地址信息定位错误的信息的详细位置信息 :addr2line

    3.库有两种:静态库(.a.lib)和动态库(.so.dll

    所谓静态、动态是指链接
    参考:静态库和动态库的区别



    参考:C/C++内存分布

    1、malloc/free和new/delete的区别

    • 共同点:

    都是从堆上申请空间,并且需要用户手动释放

    • 不同点:
    1. malloc和free是函数,new和delete是操作符

    2. malloc申请的空间不会初始化,new可以初始化

    3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可

    4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

    5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常

    6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

    2、如何一次在堆上申请4G的内存

    对于32位的栈来说虚拟地址空间有2个G的空间大小

    对于64位的栈来说虚拟地址空间的空间大小是非常大的

    示例:

    // 将程序编译成x64的进程,运行下面的程序
    #include 
    using namespace std;
    int main()
    {
    	void* p = new char[0xfffffffful];
    	cout << "new:" << p << endl;
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1G = 2^30 Bytes
    ul:为无符号长整型
    0xffff ffff = 4294967295
    (4294967295+1) / 2^30 = 4 G

    0x7FFFFFFF = 2147483647
    (2147483647+1) / 2^30 = 2 G

    • 平台vs2019x32:
      在这里插入图片描述

    • 平台vs2019x64:
      在这里插入图片描述

  • 相关阅读:
    【Spring Boot 集成应用】Spring Boot Admin的集成配置使用
    Springboot 项目读取yaml的配置文件信息给静态方法使用,以及通过配置 ResourceBundle 类读取config.properties
    项目实战 | Excel导出(三)——Excel导出样式
    众望所归,FoxPro之后,可视化编程再现新突破,国产力作
    Day8 尚硅谷JUC——JUC概述
    欧莱雅SAP系统成功合并
    分类预测 | MATLAB实现基于BiGRU-AdaBoost双向门控循环单元结合AdaBoost多输入分类预测
    页面滚动到指定位置——js中scrollIntoView()的用法
    C++&qt Day9
    Maven打包知识点
  • 原文地址:https://blog.csdn.net/qq_47355554/article/details/128073543