简单程序的编译链接三种方法(编译多个源文件,静态链接库、动态链接库)

一个程序简单的程序如下:

1 hello.h

#ifndef HELLO_H
#define HELLO_H

void hello(const char *name);

#endif

2 hello.c

#include <stdio.h>
#include <stdlib.h>

void hello(const char *name)
{
printf("hello %s\n",name);
}

3 main.c

#include <stdio.h>
#include <stdlib.h>

void hello(const char *name)
{
printf("hello %s\n",name);
}

方法一:对每个源文件进行编译生成目标文件,再有目标文件生成可执行的文件:

  第一步:gcc -c hello.c

      gcc -c main.c

      这时生成了.o的目标文件,ls可以看到hello.o main.o

  第二步:gcc -o jia hello.o main.o

      此时生成可执行文件jia

  执行:./jia

      显示:hello jiayudong

方法二:通过静态链接库

  先生成静态链接库:(静态链接库和动态链接库都是有目标文件组成,所以先要生成目标文件)

   第一步:把hello函数生成为静态链接库:

        gcc -c hello.c                                    //生成hello.o的目标文件

        ar rcs libmyhello.a hello.o               //生成libmyhello.a的静态链接库

     第二步:通过静态链接库生成可执行的文件

        gcc -o jia main.c -static -L. -lmyhello   //生成可执行的文件jia

注意:   1)创建静态链接库的命令是ar,参数是rcs,静态库的命名都是以lib+库名+.a

    2)当链接静态库时,需要的命令参数是 -static -L. -l库名 ,gcc在链接时,会在静态库前面追加lib,在库名后面追加.a,然后去找对应的静态

      链接库,所以在gcc命令中,只写库名myhello。如若需要链接libmyhello.a,则只需要写-lmyhello。

    3)静态链接库在编译链接完成后,若删除,已经编译链接好的文件是不受影响的。因而在链接的时候,库文件的函数已经被链接到执行文件中了。

      比如:删除静态库:libmyhello.a    rm libmyhello.a

        再次执行./jia   显示:hello jiayudong!

方法三:通过动态链接库链接

    第一步:生成动态链接库:

        gcc -c hello.c                //生成目标文件hello.o

        gcc -shared -fPIC -o libmyhello.so hello.o     //生成动态链接库 libmyhello.so

    第二步:链接动态库生成执行文件:

        gcc -o jia main.c -L. -lmyhello                //生成jia

执行jia:./jia   出现错误提示:  

        ./jia: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

      错误提示为:找不到动态链接库。原因是程序在运行时,才会去链接动态链接库(静态链接库在生成程序时,就已经调用),而动态链接库  

            若不在gcc中明确指定,默认会到/usr/lib或者/lib中去寻找。

      解决方案一:把libmyhello.so拷比到/usr/lib或者/lib下

      解决方案二:在LD_LIBRARY_PATH路径中加入libmyhello.so所在的路径。若在libmyhello.so的当前目录下,则export LD_LIBRARY_PATH=$(pwd);  

            若不在当前目录下:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/jiayudong/programme/pratice

      解决方案三:在root权限下,执行ldcongfig 目录名

            该命令的意思是:让该目录下的动态链接库被系统共享。实质是:在缓存文件/etc/ld.so.cache中追加进指定目录下的共享库,并重建

            /etc/ld.so.cache文件。

      注意:当删除动态链接库时,程序是不能运行的。

简单程序的编译链接三种方法(编译多个源文件,静态链接库、动态链接库)

时间: 2024-10-12 15:12:28

简单程序的编译链接三种方法(编译多个源文件,静态链接库、动态链接库)的相关文章

小程序的组件通讯三种方法==子向父传值

小程序的组件通讯三种方法 ============================ ================================ 子向父传值 第一步:小程序子向父传值在父组件定义方法 第二步:小程序子向父传值第二部在使用子组件的标签上在父的wxml文件中把方法传递给子组件 第三步:小程序子向父传值第三步在子组件的js文件中调用this·triggerEvent触发方法同时传递参数给父组件 第四步:第四步在第一步定义好的方法内部通过e·detail来接收子组件传递回来的参数 原

第二天 命令行编译的三种方法

先进入Start Command Prompt with Ruby ,在编辑器中创建好 scss 文件 进行命令操作: 第一种方法   单个文件编译: 1 .在命令行输入 cd (1)如果默认文件就在 C盘 就直接进行命令操作 Start Command Prompt with Ruby: 编辑器: (2)如过默认文件不在 C盘 就要先进入到文件所在的盘内,在进行命令操作    2 .在命令行输入 文件路径 以及  sass css/one.scss:css/one.css Start Comm

Android程序完全退出的三种方法

作者: Android开发网原创 时间: 2010-06-10 很多网友可能发现自己的Android程序有很多Activity,比如说主窗口A,调用了子窗口B,在B中如何关闭整个Android应用程序呢? 这里Android123给大家三种比较简单的方法实现. 首先要说明在B中直接使用finish(),接下来手机显示的还是主窗口A,所以一起来看看Android开发网是如何实现的吧. 1. Dalvik VM的本地方法 android.os.Process.killProcess(android.

PHP和HTML代码混合编译的三种方法

第一种是在HTML中加PHP. 大段大段的html代码中,在各个需要执行php的地方<?php .... ?> 比如 line7-9: 1 <head> 2 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 3 <meta http-equiv="Content-Language" content="zh-

Android程序全然退出的三种方法

1. Dalvik VM的本地方法 android.os.Process.killProcess(android.os.Process.myPid())    //获取PID,眼下获取自己的也仅仅有该API,否则从/proc中自己的枚举其它进程吧,只是要说明的是,结束其它进程不一定有权限,不然就乱套了. System.exit(0);   //常规java.c#的标准退出法,返回值为0代表正常退出 2. 任务管理器方法 首先要说明该方法执行在Android 1.5 API Level为3以上才干

微信小程序使用函数的三种方法

使用来自不同页面的函数 函数写在util.js页面 function formatTime(date) { var year = date.getFullYear() var month = date.getMonth() + 1 var day = date.getDate() var hour = date.getHours() var minute = date.getMinutes() var second = date.getSeconds() return [year, month,

【转】delphi程序只允许运行一个实例的三种方法:

一.        创建互斥对象 在工程project1.dpr中创建互斥对象 Program project1 Uses Windows,Form, FrmMain in 'FrmMain.pas' {MainForm}; {$R *.res} var hAppMutex: THandle; //声明互斥变量 begin hAppMutex := CreateMutex(nil, false,’projectname’); //创建互斥对象projectname工程名称 if ( (hAppM

Win10 IoT C#开发 1.5 - 创建基于XAML的UI程序 及 应用的三种部署方法

Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我们讲了Raspberry安装Win10 IoT系统及搭建Visual Studio 2015开发环境的方法(http://www.cnblogs.com/cloudtech/p/5562120.html) , 这次我们来看如何将开发好Win10 IoT程序部署到Raspberry的环境上. 分别使用

让程序只运行一个实例(Delphi篇)(三种方法,其中使用全局原子的方法比较有意思)

Windows 下一个典型的特征就是多任务,我们可以同时打开多个窗口进行操作,也可以同时运行程序的多个实例,比如可以打开许多个资源管理器进行文件的移动复制操作.但有时出于某种考虑(比如安全性),我们要做出一些限制,让程序只能够运行一个实例.在Delphi编程中,笔者总结出了以下几种方法: 一. 查找窗口法 这是最为简单的一种方法.在程序运行前用FindWindow函数查找具有相同窗口类名和标题的窗口,如果找到了,就说明已经存在一个实例.在项目源文件的初始化部分添加以下代码: [delphi] v