linux链接编译详解

为什么要包含头文件而不是.c文件

测试代码:

代码如下:

m.c文件:
#include"t.c"
int main()
{
test();
return 0;
}

编译:


代码如下:

gcc m.c -o m -Wall

In file included from m.c:1:0:
t.c: 在函数‘test'中:
t.c:3:2: 警告: 隐式声明函数‘putchar' [-Wimplicit-function-declaration]
编译通过,只有一个警告,生成了可执行文件m,运行它正常,输出一空格。

修改下t.c 文件:

代码如下:

#include<stdio.h>
void test()
{
       printf("test\n");
}

编译后执行

输出:    test

从这可看出,包含.c文件进去对程序并没造成什么影响,反而比包含.h文件来得直接方便,这里主要考虑到大型项目中,各文件直接的联系,如A.c文件中包好M.c文件,B.c 文件中包含M.c文件,而A.c文件又包含B.c文件,那么编译时就会报错,函数名重定义了。
#include<>与#include""的区别:

对于用角括号包含的头文件,gcc 首先查找-I选项指定的目录,然后查找系统的头文件目录(通常是/usr/include,在我的系统上还包括/usr/lib/gcc/i486-linux-gnu/4.3.2/include);而对于用引号包含的头文件,gcc 首先查找包含头文件的.c文件所在的目录,然后查找-I选项指定的目录,最后再查找系统的头文件目录。

静态库

代码如下:

/* stack.c */
char stack[512];
int top = -1;

代码如下:

/* push.c */
extern char stack[512];
extern int top;
void push(char c)
{
stack[++top] = c;
}

代码如下:

/* pop.c */
extern char stack[512];
extern int top;
char pop(void)
{
return stack[top--];
}

代码如下:

/* is_empty.c */
extern int top;
int is_empty(void)
{
return top == -1;
}

代码如下:

/* stack.h */
#ifndef STACK_H
#define STACK_H
extern void push(char);
extern char pop(void);
extern int is_empty(void);
#endif

代码如下:

/* main.c */
#include <stdio.h>
#include "stack.h"
int main(void)
{
   push('a');
   char c = pop();
   printf("%c\n",c);
   return 0;
}

将如上5个.c文件和一个.h文件放在同目录下,在当前目录下新建一Makefile文件,使用Makefile是编译。

代码如下:

main:libstack.a main.o
       gcc -o main main.o -L. -lstack
libstack.a: stack.o push.o pop.o is_empty.o
       ar rs libstack.a  stack.o push.o pop.o is_empty.o
stack.o:
       gcc -o stack.o -c stack.c
push.o
       gcc -o push.o -c push.c
pop.o:
       gcc -o pop.o -c pop.c
is_empty:
       gcc -o is_empty.o -c is_empty.c
main.o:
       gcc -o main.o -c main.c

编译后执行./main
显示:a

反编译指令: 查看反编译后程序


代码如下:

objdump -d main

(0)

相关推荐

  • linux动态链接库使用方法分享

    1.前言 在实际开发过程中,各个模块之间会涉及到一些通用的功能,比如读写文件,查找.排序.为了减少代码的冗余,提高代码的质量,可以将这些通用的部分提取出来,做出公共的模块库.通过动态链接库可以实现多个模块之间共享公共的函数.之前看<程序员的自我修养>中讲到程序的链接和装入过程,这些玩意都是底层的,对于理解程序的编译过程有好处.http://www.ibm.com/developerworks/cn/linux/l-dynlink/博文介绍了程序的链接和装入过程.本文重点在于应用,如何编写和使用

  • Python在Windows和在Linux下调用动态链接库的教程

    Linux系统下调用动态库(.so) 1.linuxany.c代码如下: #include "stdio.h" void display(char* msg){ printf("%s\n",msg); } int add(int a,int b){ return a+b; } 2.编译c代码,最后生成Python可执行的.so文件 (1)gcc -c linuxany.c,将生成一个linuxany.o文件 (2)gcc -shared linuxany.c -o

  • 什么是Linux软链接和Linux硬链接

    Linux链接分两种,一种被称为硬链接(Hard Link),另一种被称为软链接(Symbolic Link).默认情况下,ln命令产生硬链接. 一.[硬链接]-->指通过索引节点来进行连接.在Linux的文件系统中,保存在磁盘分区中的文件不管是什么类型都给它分配一个编号,称为索引节点号(Inode Index).在Linux中,多个文件名指向同一索引节点是存在的.一般这种连接就是硬连接.硬连接的作用是允许一个文件拥有多个有效路径名,这样用户 就可以建立硬连接到重要文件,以防止"误删&qu

  • 解决Linux程序编译链接动态库版本的相关问题

    前言 不同版本的动态库可能会不兼容,如果程序在编译时指定动态库是某个低版本,运行是用的一个高版本,可能会导致无法运行.Linux上对动态库的命名采用libxxx.so.a.b.c的格式,其中a代表大版本号,b代表小版本号,c代表更小的版本号,我们以Linux自带的cp程序为例,通过ldd查看其依赖的动态库 $ ldd /bin/cp linux-vdso.so.1 => (0x00007ffff59df000) libselinux.so.1 => /lib64/libselinux.so.1

  • Linux链接命令的实例详解

    Linux链接命令的实例详解 一 语法 ln -s [源文件] [目标文件] 命令英文含义:link 功能描述:生成链接文件 选项:-s 创建软链接 二 硬链接特征 原文件和硬链接文件删除其中任何一个都没问题. 三 硬链接实战 [root@localhost ~]# cd test [root@localhost test]# ls bcd [root@localhost test]# ln bcd abc.hard [root@localhost test]# ll total 0 -rw-r

  • linux删除无效链接文件脚本分享

    Linux终端下执行,用于删除无效的链接文件. 复制代码 代码如下: #!/bin/sh usage(){    echo "RemoveBroken 0.1, a shell script to remove broken link files."    echo "License: MIT, (c) chenzhiqiang"    echo "Usage:"    echo "  $0 --help           print

  • Linux 硬链接和软链接详细介绍

    Linux中的硬链接和软链接 软链接和硬链接 命令ln ln是创建链接的命令: 创建硬链接:ln file link 创建软链接:ln -s file link 硬链接 硬链接(hard link)是Unix系统最早的创建链接的方式. 默认情况下每个文件都有一个硬链接,创建硬链接时,实际上是创建了附加的入口,当且仅当指向文件的所有硬链接都被删除之后文件才被真正删除,即数据块被清理. 为一个文件创建硬链接,类似于拷贝一个文件,但是这个新的拷贝和原先的版本是同步更新的. 这是因为Linux文件系统中

  • linux链接编译详解

    为什么要包含头文件而不是.c文件 测试代码: 复制代码 代码如下: m.c文件:#include"t.c"int main(){test();return 0;} 编译: 复制代码 代码如下: gcc m.c -o m -Wall In file included from m.c:1:0:t.c: 在函数'test'中:t.c:3:2: 警告: 隐式声明函数'putchar' [-Wimplicit-function-declaration]编译通过,只有一个警告,生成了可执行文件m

  • Linux操作系统内核编译详解

    内核简介 内核,是一个操作系统的核心.它负责管理系统的进程.内存.设备驱动程序.文件和网络系统,决定着系统的性能和稳定性. Linux的一个重要的特点就是其源代码的公开性,所有的内核源程序都可以在/usr/src/linux下找到,大部分应用软件也都是遵循GPL而设计的,你都可以获取相应的源程序代码.全世界任何一个软件工程师都可以将自己认为优秀的代码加入到其中,由此引发的一个明显的好处就是Linux修补漏洞的快速以及对最新软件技术的利用.而Linux的内核则是这些特点的最直接的代表. 

  • 基于使用paramiko执行远程linux主机命令(详解)

    paramiko是python的SSH库,可用来连接远程linux主机,然后执行linux命令或者通过SFTP传输文件. 关于使用paramiko执行远程主机命令可以找到很多参考资料了,本文在此基础上做一些封装,便于扩展与编写脚本. 下面直接给出代码: # coding: utf-8 import paramiko import re from time import sleep # 定义一个类,表示一台远端linux主机 class Linux(object): # 通过IP, 用户名,密码,

  • linux lsof命令详解及实例

    linux lsof命令详解 简介 lsof(list open files)是一个列出当前系统打开文件的工具.在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以如传输控制协议 (TCP) 和用户数据报协议 (UDP) 套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口.因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过

  • Linux中多线程详解及简单实例

    Linux中多线程详解及简单实例 1.概念 进程:运行中的程序. 线程:一个程序中的多个执行路径.更准确的定义是:线程是一个进程内部的一个控制序列. 2.为什么要有线程? 用fork调用进程代价太高,需要让一个进程同时做多件事情,线程就非常有用. 3.线程的优点和缺点. 优点: (1)有时,让程序看起来是在同时做两件事是非常有用的. 比如在编辑文档时,还能统计文档里的单词个数. (2)一个混杂着输入.计算.输出的程序,利用线程可以将这3个部 分分成3个线程来执行,从而改变程序执行的性能. (3)

  • 基于编译虚拟机jvm—openjdk的编译详解

    java只所以被推广,实际上很大原因是因为本身是跨平台的,很大作用是因为虚拟机的关系. 一般情况下开发人员不需要关注虚拟机内部实现就可以日常开发了,但是有时候涉及到性能的时候就需要了解虚拟机的实现机制了. 那么今天写的内容更多的是关于编译一套自己的虚拟机,为日后了解虚拟机底层原理铺铺路. 编译虚拟机可能会遇到很多坑,也很花费时间.也因大家的环境的差异,可能遇到的问题都不一致. 我只能说把自己遇到的问题都列出来,权当抛砖引玉了. 1首先我们应该下载openjdk的源码,这个openjdk实际上是有

  • Linux curl命令详解

    在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具. 语法: # curl [option] [url] 常见参数: -A/--user-agent <string> 设置用户代理发送给服务器 -b/--cookie <name=string/file> cookie字符串或文件读取位置 -c/--cookie-jar <file> 操作

  • linux epoll机制详解

    在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序.在linux新的内核中,有了一种替换它的机制,就是epoll. select()和poll() IO多路复用模型 select的缺点: 1.单个进程能够监视的文件描述符的数量存在最大限制,通常是1024,当然可以更改数量,但由于select采用轮询的方式扫描文件描述符,文件描述符数量越多,性能越差:(在linux内核头文件中,有这样的定义:#define __FD_SE

  • Linux文件服务器实战详解(匿名用户)

    一.进程与线程 二.vsftp服务器 1.文件传输协议(file transfer protocol,FTP) 基于该协议ftp客户端和服务端实现文件共享,上传下载文件 FTP基于TCP协议生成一个虚拟的连接,用于控制ftp连接信息.同时再生成一个TCP连接用于FTP数据传输    2.ftp传输模式 3.FTP安装配置 a.yum方式安装 b.源码便宜安装 1)yum install -y vsftpd* 2)vsftpd安装后的配置文件路径,启动vsftpd服务以及查看进程是否启动 rpm

  • Linux正则表达式特性详解及BRE与ERE的异同点

    Linux正则表达式(Regular Expression)主要遵从POSIX BRE或者POSIX ERE标准.什么是POSIX呢,POSIX Portable Operating System Interface 可移植操作系统接口ERE是BRE的扩展版本,具体更强的处理能力,并增加了一些元字符(metacharactor). BRE主要的能力集有: 1) 普通字符(Literal text),如a,b,c等 2)非打印字符,包括TAB,回车,换行,回车换行(WINDOWS) 3)任意字符.

随机推荐