GCC链接的几个注意点

库文件依赖顺序

GCC在链接时对依赖库的顺序是敏感的,被依赖的库必须放在后面,比如liba.a依赖libb.a,必须写成liba.a libb.a,否则链接将出错。在库比较多依赖关系比较复杂或者相互依赖或者自己不清楚的情况下,可以使用下面的选项来强制GCC重复查找依赖库:

g++ -o tt tt.o -Xlinker "-(" -lws2_32 -lclsocketd -Xlinker "-)"

强符号和弱符号

在链接中,如果多个目标文件中含有相同名字的全局符号的定义,链接器是怎么进行处理的?这里就涉及到强符号和弱符号的问题,编译器默认函数和初始化了的全局变量为强符号,未初始化的全局变量为弱符号,强符号和弱符号都是针对定义来说的,不是针对符号的引用。链接器会按照如下规则处理重复定义的全局符号:

规则1:不允许强符号被多次定义,否则链接器报符号重定义错误。

规则2:如果一个符号在某个目标文件中是强符号,在其它文件中都是弱符号,那么选择强符号。

规则3:如果弱符号在所有目标文件中都是弱符号,那么选择占用空间最大的一个。

我们可以通过GCC的__atrribute__((weak))来定义任何一个强符号为弱符号,如:

__atrribute__((weak)) weak = 1;

链接时如果未找到某个符号的定义,链接器就会报符号未定义错误,这种被称为强引用。与之对应的还有一种弱引用,如果弱引用的符号未定义,链接器对该引用不报错。我们可以使用GCC中的__attribute__((weakref))这个关键字来声明对一个外部函数的引用为弱引用,如:

__attribute__((weakref)) void foo();

int main()

{

    if (foo) foo();

}

这种弱符号和弱引用对库来说十分有用,比如库中定义的弱符号可以被用户定位的强符号所覆盖,从而使程序使用自定义版本的库函数;或者程序可以对某些扩展功能模块的引用定义为弱引用,如果我们去掉了某些功能模块,那么程序也可以正常链接,只是缺少了相应的功能,这使得程序功能更容易裁剪和组合。

全局符号介入

在动态链接中,链接器按照各个模块之间的依赖关系,对各个共享对象进行装载并且将它们的符号并入到全局符号表时,如果两个不同的模块定义了同一个符号,会出现什么结果呢?这个问题涉及到共享对象全局对象介入,即一个共享对象里面的全局对象会被另一个共享对象的同名全局符号覆盖。Linux下的动态链接器的处理规则是这样的:当一个符号需要被加入全局符号表时,如果相同的符号名已经存在,则后加入的符号被忽略。

共享库版本

Linux使用共享库版本的方法来解决共享库的兼容性问题,它规定共享库的文件命名规则如下:

libname.so.x.y.z

x表示主版本号,主版本号表示库的重大升级,不同主版本号之间是不兼容的。

y表示次版本号,次版本号表示库的增量升级,即新增一些新的接口符号,且保持原来的符号不变。在主版本号相同的情况下,高的此版本号的库向下兼容低的次版本号的库。

z表示发布版本号,发布版本号表示库的一些错误修正、性能改进等,并不添加任何新的接口,也不对接口进行更改。相同主版本号、次版本号的共享库之间完全兼容。

Linux采用一种叫做SO-NAME的命令机制来记录共享库的依赖关系。每个共享库都有一个对应的SO-NAME,这个SO-NAME即共享库的文件名去掉次版本号和发布版本号,保留主版本号。比如一个共享库叫做libfoo.so.2.6.1,那么它的SO-NAME就是libfoo.so.2。系统会为每个共享库在它所在的目录创建一个跟SO-NAME相同的并且指向它的软链接,这个软链接会指向目录中主版本号相同、次版本号和发布版本号最新的共享库。

在编译输出ELF文件时,将被依赖共享库的SO-NAME保存到.dynamic中,这样当动态链接器进行共享库依赖文件查找时,就会根据系统中各种共享目录中的 SO-NAME软链接自动定向到所兼容的最新版本的共享库。

转载于:https://www.cnblogs.com/glacierh/p/4678667.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Linux 系统中,可以使用 GCC 编译器连接 MySQL。这可以通过以下步骤实现: 1. 安装 MySQL 头文件和库文件: 在连接 MySQL 之前,需要安装 MySQL 头文件和库文件。可以使用以下命令来安装这些文件: ``` sudo apt-get install libmysqlclient-dev ``` 2. 编写代码: 需要编写 C/C++ 代码来连接 MySQL。代码中应包含 MySQL 头文件,并使用 MySQL 库函数来连接和操作 MySQL 数据库。 3. 编译代码: 使用 GCC 编译器编译代码。连接 MySQL 时,需要指定 MySQL 库文件的位置。可以使用以下命令编译代码: ``` gcc -o [executable_name] [source_file] -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient ``` 4. 运行程序: 编译完成后,就可以运行程序来连接 MySQL 数据库了。 希望这些信息能帮到你! ### 回答2: 在Linux上使用gcc连接MySQL有以下几个步骤: 1. 安装MySQL开发包:首先需要在Linux系统上安装MySQL的开发包,该开发包包含了使用MySQL的头文件和链接库。可以使用以下命令安装: ```shell sudo apt-get install libmysqlclient-dev ``` 2. 编写代码:编写程序代码时需要包含MySQL的头文件。可以使用以下代码段作为示例: ```c #include <mysql/mysql.h> int main() { MYSQL *conn; conn = mysql_init(NULL); if (!conn) { fprintf(stderr, "Failed to initialize MySQL connection\n"); return 1; } if (!mysql_real_connect(conn, "localhost", "username", "password", NULL, 0, NULL, 0)) { fprintf(stderr, "Failed to connect to MySQL: Error: %s\n", mysql_error(conn)); mysql_close(conn); return 1; } printf("Connected to MySQL successfully\n"); mysql_close(conn); return 0; } ``` 在代码中需要根据实际情况修改`username`和`password`,分别为MySQL的用户名和密码。 3. 编译代码:使用gcc编译器将代码编译成可执行文件。可以使用以下命令编译代码: ```shell gcc -o myprogram myprogram.c `mysql_config --cflags --libs` ``` 这里的`myprogram`是生成的可执行文件名,`myprogram.c`是代码文件名。在编译过程中,需要使用`mysql_config --cflags --libs`命令获取MySQL的编译选项和链接选项。 4. 运行程序:编译成功后,可以直接运行生成的可执行文件,即可连接到MySQL数据库。 通过以上步骤,就可以在Linux中使用gcc连接MySQL数据库了。请注意,在实际使用中,还需要处理连接错误、执行SQL语句等操作,上述代码只是简单的示例。 ### 回答3: 要在Linux中使用GCC连接MySQL,需要进行以下步骤: 1. 首先,确保已经安装了MySQL数据库和MySQL的C语言客户端库。如果没有安装,可以使用包管理器(如apt-get或yum)进行安装。 2. 创建一个新的C语言源文件,例如main.c。 3. 在源文件中包含mysql.h头文件,并使用gcc编译该源文件。命令如下: ``` gcc -o main main.c `mysql_config --cflags --libs` ``` 这将使用mysql_config命令提供的相关选项来链接MySQL的C语言客户端库。 4. 编译成功后,可以运行生成的可执行文件,即可连接MySQL数据库进行操作。 ``` ./main ``` 在源文件中,可以使用MySQL C语言客户端库提供的函数来连接数据库、执行SQL语句、获取查询结果等。 ``` // 示例代码 #include <mysql.h> #include <stdio.h> int main() { MYSQL *conn; MYSQL_RES *res; MYSQL_ROW row; conn = mysql_init(NULL); if (!mysql_real_connect(conn, "localhost", "user", "password", "database", 0, NULL, 0)) { fprintf(stderr, "%s\n", mysql_error(conn)); return 1; } if (mysql_query(conn, "SELECT * FROM table")) { fprintf(stderr, "%s\n", mysql_error(conn)); return 1; } res = mysql_use_result(conn); while ((row = mysql_fetch_row(res)) != NULL) { printf("%s %s\n", row[0], row[1]); } mysql_free_result(res); mysql_close(conn); return 0; } ``` 在这个示例代码中,需要替换连接参数中的"localhost"、"user"、"password"和"database"为实际的数据库服务器地址、用户名、密码和数据库名。 这样,就可以使用GCC来连接MySQL并在Linux中进行数据库操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值