文章目录
  1. 1. 预备知识
  2. 2. 封成库文件
  3. 3. 多文件编译实例
  4. 4. Linux驱动
    1. 4.1. 声明报错
  5. 5. 格式不正确
  6. 6. 程序在目标机运行错误
  7. 7. g++ -I./inlcude -L./lib first.cpp -lboost_thread -lboost_system -o example -Wl,-rpath,/usr/local/lib
  8. 8. g++ -Ilibboost_thread.so.1.59.0 -L./usr/local/lib/ first.cpp -lboost_thread -lboost_system -o example -Wl,-rpath,/usr/local/lib

被关在牢笼中的究竟是James还是Mary

Linux编译日常备忘。

预备知识

[g++编译参数]

g++编译参数

[gcc编译参数]
gcc编译参数

  • 查看程序含有什么动态函式库
    ldd命令用于判断某个可执行的 binary 档案含有什么动态函式库

    1
    2
    3
    4
    5
    --version  打印ldd的版本号
    -v --verbose  打印所有信息,例如包括符号的版本信息
    -d --data-relocs  执行符号重部署,并报告缺少的目标对象(只对ELF格式适用)
    -r --function-relocs  对目标对象和函数执行重新部署,并报告缺少的目标对象和函数(只对ELF格式适用)
    --help 用法信息

  • nm查看静态库有哪些模块

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [13:37:47][root@localhost liaoxi]# nm libgpio.a        
    [13:37:47]00000000 b base
    [13:37:47]00000000 t inb
    [13:37:47]0000006e T init_gpio
    [13:37:47]0000001d t inl
    [13:37:47]00000039 t outb
    [13:37:47]00000057 t outl
    [13:37:47] U printf
    [13:37:47] U puts
    [13:37:47]00000999 T read_gpio
    [13:37:47]000000a5 T read_pca9534_register
    [13:37:47]000002e1 T write_gpio
  • 查看程序返回值

    1
    # echo $?

显示上一个执行的命令(或程序)的返回值,这个值通常在0~255之间,0表示一切正常。


封成库文件

参考博文

  • 静态连接库
  1. 将类.cpp跟头文件.h生成.so文件

    1
    g++ RS232.h RS232-gx_v4_Flag.cpp -fPIC -shared -o libRS232.so
  2. g++编译
    g++ libRS232.so main.cpp -o run

  3. 将生成的run文件和.so文件拷贝到目标机
    将.so文件拷贝到/ust/lib下

    1
    cp  libRS232.so  /usr/lib/

g++ Self_IO.h Self_IO.c -fPIC -shared -o libSELF_IO.so

多文件编译实例

  1. 功能函数
    add.cpp

    1
    2
    3
    4
    5
    int add(int a, int b)
    {

    return a + b;

    }
  2. 头文件
    function.h

    1
    2
    3
    4
    5
    #include<iostream>
    using std::cout;
    using std::endl;

    int add(int a, int b);
  3. 调用的主函数

main.cpp

1
2
3
4
5
6
7
8
9
#include"function.h"


int main()
{


cout << add(1, 2);

}

  1. 编译
    1
    # g++ main.cpp add.cpp -o add.out

Linux驱动

声明报错

  1. 1
    /root/mini_linux_module/first_linux_driver.c:6: error: expected declaration specifiers or '...' before string constant

解决方法
错误源码:

1
6 MODULE_LINCESE("Dual BSD/GPL");  //GPL:声明开源;        Dual BSD:没有版本限制

正确应该为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18



# webbench-1.5

OS: Ubuntu 14.04.2 LTS \n \l
gcc:gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
```make
root@ubuntu:~/webbench-1.5# make
cc -Wall -ggdb -W -O -c -o webbench.o webbench.c
webbench.c: In function ‘alarm_handler’:
webbench.c:77:31: warning: unused parameter ‘signal’ [-Wunused-parameter]
static void alarm_handler(int signal)
^
cc -Wall -ggdb -W -O -o webbench webbench.o
ctags *.c
/bin/sh: 1: ctags: not found
make: [tags] Error 127 (ignored)

没有ctags命令

解决办法:安装ctages

1
root@ubuntu:~/webbench-1.5# apt-get install ctags

  1. C++中函数名不能带 “-”吗?
    解答:不行;C++命名只能是大小写英文字母、下划线或数字;

  2. main定义不对
    g++编译报错:

    1
    2
    3
    4
    root@ACER:/home/takethat/workspace/gx_WSL# g++ RS232-gx.cpp -o RS232_run
    RS232-gx.cpp:36:15: error:::main’ must return ‘int’
    void main(void)
    ^

解决:
将void main()改为int main()就行了。原因:
C++98中定义了如下两种main函数的定义方式:

1
2
3
  int main( )

  int main(int argc, char *argv[])

  1. 数组非法赋值
    g++编译报错:

    1
    2
    RS232-gx.cpp:42:5: error: assigning to an array from an initializer list
    data={0x21,0x60,0x90,0x90,0x81,0x83,0xA8,0xB3,0xC0};

    data是数组名,是首地址;
    正确的写法

    1
    unsigned char data[9] = { 0x21,0x60,0x90,0x90,0x81,0x83,0xA8,0xB3,0xC0 };
  1. 类函数调非法调用
    1
    2
    3
    RS232-gx.cpp:69:21: error: statement cannot resolve address of overloaded function
    operatorser.out_door;
    ^

正确写法:

1
operatorser.out_door();

  1. 语法错误
    1
    error: expected constructor, destructor, or type conversion before ‘=’ token

原因:
C++中,全局域只能声明,初始化变量,不能对变量进行赋值,运算,调用函数等操作,谨记

  1. 类作用域问题

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    oot@ACER:/home/takethat/workspace/gx_WSL# gcc RS232-gx.cpp -o RS232_run
    RS232-gx.cpp:27:15: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
    char *uart3 = "/dev/ttys3"; //串口位置
    ^
    /tmp/ccffAwXc.o: In function `main':
    RS232-gx.cpp:(.text+0x10): undefined reference to `Rs232::open_com_init_opt()'

    RS232-gx.cpp:(.text+0x1c): undefined reference to `Rs232::in_door()'
    RS232-gx.cpp:(.text+0x28): undefined reference to `Rs232::out_door()'

    /tmp/ccffAwXc.o: In function `__static_initialization_and_destruction_0(int, int)':
    RS232-gx.cpp:(.text+0x58a): undefined reference to `std::ios_base::Init::Init()'

    RS232-gx.cpp:(.text+0x599): undefined reference to `std::ios_base::Init::~Init()'
    collect2: error: ld returned 1 exit status

    解决:
    原因:在类外部定义时,成员函数名前要多加一个类名;如果不加编译器就会认为该函数不是类的成员函数

    • 字符常量要加const
      1
      2
      3
      4
       root@ubuntu:~/gx# g++ RS232-gx.cpp -o RS232_RUN
      RS232-gx.cpp:27: warning: deprecated conversion from string constant tochar*’
      /usr/lib/gcc/x86_64-linux-gnu/4.4.7/../../../x86_64-linux-gnu/crt1.o: In function `_start':
      (.text+0x20): undefined reference to `main

const

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15



10. operator是C++关键字不能作为函数名!!
>vi下关键字是黄色








# 数组报错
unsigned char报错

RS232-gx_v4_Flag.cpp: In member function ‘void Rs232::register_68()’:
RS232-gx_v4_Flag.cpp:113:33: error: conflicting declaration ‘unsigned char register68_data [0]’
unsigned char register68_data[0]=0;
^
RS232-gx_v4_Flag.cpp:95:17: note: previous declaration as ‘unsigned char register68_data [48]’
unsigned char register68_data[48];

1
错误原因

unsigned char register68_data[48];

unsigned char register68_data[0]=0;
unsigned char register68_data1=15;
unsigned char register68_data[2] = 10;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
这是错误的,赋值的时候不需要在写``unsigned char``




# 编译线程程序报错

```Linux
[root@localhost test_]# gcc threadl1.c
/tmp/cceEaXN0.o: In function `main':
threadl1.c:(.text+0x22): undefined reference to `pthread_create'
threadl1.c:(.text+0x68): undefined reference to `pthread_join'
threadl1.c:(.text+0xae): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status

解决办法:要链接线程库

1
gcc -pthread -o a threadl1.c

线程有一套完整的与其相关的函数库调用,在程序头文要包含pthread.h并且在编译程序的时候要用选项-pthread

格式不正确

  1. 注释不完整
1
thread1--.c:42:1: error: unterminated comment

解决办法:
将错误的那行注释写完;
不只写 /*

程序在目标机运行错误

Segmentation fault (core dumped)一般是对内存操作不当造成的,常见的有:
(1)数组超出范围。

(2)修改了只读内存。

(3)还有本例也是修改了只读内存。

  • ulimit -c unlimited 调试错误的core
    1.
1
2
3
4
5
6
7
8
9
ulimit -c unlimited  
```
个命令的时候主要是为了产生core文件,就是程序运行发行段错误时的文件



注意如果执行`ulimit -c unlimited`没有生成`core`文件则先检查

**``2.``**然后再执行gdb调试core文件找出具体错误

gdb RS232_RUN core

1
2
3
4
5
>格式为:``gdb   程序名  core文件``


**``3.``**在gdb中执行``bt``调出列出调用栈
>bt(backtrace)

root@ubuntu:~/gx# gdb RS232_RUN core
GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type “show copying”
and “show warranty” for details.
This GDB was configured as “x86_64-linux-gnu”.
For bug reporting instructions, please see:
http://bugs.launchpad.net/gdb-linaro/
Reading symbols from /root/gx/RS232_RUN…(no debugging symbols found)…done.
[New LWP 3277]

warning: Can’t read pathname for load map: Input/output error.
Core was generated by `./RS232_RUN’.
Program terminated with signal 11, Segmentation fault.

#0 0x0000000000400a92 in Rs232::in_door() ()
(gdb) bt //列出调用栈

#0 0x0000000000400a92 in Rs232::in_door() ()

#1 0x0000000000400a64 in main ()
(gdb)

1
 


# linux下编译`boost::thread`程序

正确链接库

g++ -I./inlcude -L./lib first.cpp -lboost_thread -lboost_system -o example -Wl,-rpath,/usr/local/lib

1
2

运行正确

g++ -Ilibboost_thread.so.1.59.0 -L./usr/local/lib/ first.cpp -lboost_thread -lboost_system -o example -Wl,-rpath,/usr/local/lib

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15




>gcc编译链接动态库时,很有可能编译通过,但是执行时,找不到动态链接库,那是因为-L选项指定的路径只在编译时有效,编译出来的可执行文件不知道-L选项后面的值,通过``-Wl,rpath=<your_lib_dir>``,或```-Wl,-rpath,<your_lib_dir>```使得execute记住链接库的位置





+ `ulimit -c ulimited` 报错

```linux
[root@localhost Test]# ulimit -c ulimited
-bash: ulimit: ulimited: invalid number

1
[root@localhost EquipmentControl_CD10A]# make -f makefile_debug -j2
g++ -g -w -D linux -std=c++11 -D __LINUX__ -c CReader_Control.cpp
CReader_Control.cpp: 在成员函数‘int CReader_Control::initReader(int)’中:
CReader_Control.cpp:817:97: 错误:对‘IReaderImpl::startReaderAFC(stInitReaderInfo_CD*, CReader_Control::initReader(int)::CD_stRCodeInfo*)’的调用没有匹配的函数
CReader_Control.cpp:817:97: 附注:备选是:
In file included from CReader_Control.h:12:0,
                 from CReader_Control.cpp:1:
../../../EquipmentImpl/IReaderImpl.h:48:14: 附注:virtual int IReaderImpl::startReaderAFC(void*, CD_stRCodeInfo*)
../../../EquipmentImpl/IReaderImpl.h:48:14: 附注:  no known conversion for argument 2 from ‘CReader_Control::initReader(int)::CD_stRCodeInfo*’ to ‘CD_stRCodeInfo*’
make: *** [CReader_Control.o] 错误 1
[root@localhost EquipmentControl_CD10A]# make -f makefile_debug clean

  • 段错误之#0 0x00000001 in ?? ()
    发现错误的使用了共享库编译选项,编译出来的成库了,错误的编译命令g++ -g -w -D linux -std=c++11 -D __LINUX__ -lmcheck -shared -fPIC -o a.out main_demo.cpp -lboost_container -lboost_thread -lboost_system -Wl,-rpath,./

正确的命令

1
g++ -g -w -D linux -std=c++11 -D __LINUX__  -o a.out  main_demo.cpp CEquThread.cpp -lboost_container -lboost_thread -lboost_system -Wl,-rpath,./

  • g++编译报错 未定义的引用
1
2
3
4
5
6
7
[root@localhost cecequthread]# g++ -g -w -D linux -std=c++11 -D __LINUX__  -o a.out  main_demo.cpp  -lboost_container -lboost_thread -lboost_system -Wl,-rpath,./
/tmp/ccZJXWEQ.o:在函数‘_ZN5boost11make_sharedI10CEquThreadIRFvPvEKP4testiEEENS_6detail15sp_if_not_arrayIT_E4typeEDpOT0_’中:
/usr/local/include/boost/smart_ptr/make_shared_object.hpp:254:对‘CEquThread::CEquThread(void (*)(void*), void*, int)’未定义的引用
/tmp/ccZJXWEQ.o:在函数‘boost::detail::sp_ms_deleter<CEquThread>::destroy()’中:
/usr/local/include/boost/smart_ptr/make_shared_object.hpp:57:对‘CEquThread::~CEquThread()’未定义的引用
collect2: 错误:ld 返回 1
[root@localhost cecequthrea

报错原因:
出现这种情况的原因,主要是C/C++编译为obj文件的时候并不需要函数的具体实现,只要有函数的原型即可。但是在链接为可执行文件的时候就必须要具体的实现了。

编译的时候加上响应的.cpp文件即可

正确的编译命令:

1
[root@localhost cecequthread]# g++ -g -w -D linux -std=c++11 -D __LINUX__  -o a.out  main_demo.cpp  CEquThread.cpp -lboost_container -lboost_thread -lboost_system -Wl,-rpath,./

  • 报错:g++: 错误:当输入来自标准输入设备时,需要 -E 或 -x
    编译指令加了-但是没有加参数‘’
  • 动态库=> not found

编译命令:

1
# g++ -ldl -lboost_container -lboost_thread -lboost_system  test_gate.cpp

正确编译命令:

1
# g++ -ldl -lboost_container -lboost_thread -lboost_system -Wl,-rpath,./ test_gate.cpp

运行时动态库:not found 及介绍-linux的-Wl,-rpath命令

  • GDG调试报错

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [root@localhost SOFTWARE_PACKAGE_DEBUG]# gdb ./AGM_Client core.7544.1527411160
    GNU gdb Red Hat Linux (6.6-8.fc7rh)
    Copyright (C) 2006 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB. Type "show warranty" for details.
    This GDB was configured as "i386-redhat-linux-gnu"...
    Dwarf Error: wrong version in compilation unit header (is 4, should be 2) [in module /home/AGM_CD/SOFTWARE_PACKAGE_DEBUG/AGM_Client]
    /home/AGM_CD/SOFTWARE_PACKAGE_DEBUG/core.7544.1527411160: No such file or directory.

  • cannot allocate an object of abstract type

    1
    2
    error: cannot allocate an object of abstract typetest1
    return new test1;

错误:无法分配对象的抽象类型

原因:在基类中声明的虚函数,没有在继承类中继承、实现。

解决:将基类中声明的虚函数在继承类中继承实现,就可以new一个派生类了。

文章目录
  1. 1. 预备知识
  2. 2. 封成库文件
  3. 3. 多文件编译实例
  4. 4. Linux驱动
    1. 4.1. 声明报错
  5. 5. 格式不正确
  6. 6. 程序在目标机运行错误
  7. 7. g++ -I./inlcude -L./lib first.cpp -lboost_thread -lboost_system -o example -Wl,-rpath,/usr/local/lib
  8. 8. g++ -Ilibboost_thread.so.1.59.0 -L./usr/local/lib/ first.cpp -lboost_thread -lboost_system -o example -Wl,-rpath,/usr/local/lib