静态库生成及使用

calc.h

#ifndef __MY_LIB_H__

#define __MY_LIB_H__

int add(int a, int b);

#endif

calc.c

#include "calc.h"

#include <stdio.h>

int sum(int i, int j)
{
    return (i+j);
}

编译:

gcc -c calc.c -o calc.o

ar -cr libcalc.a calc.o

gcc -o main main.c ./libcalc.a

动态库生成及使用

show.h

#ifndef __SHOW_H__
#define __SHOW_H__

void show(int i, char* name);

#endif

show.c

#include "show.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void show(int i, char* name)
{
    printf("%s=%d\n", name, i);

}

编译:

gcc -fPIC -Wall -c show.c -o show.o

gcc -shared -o libshow.so show.o

gcc -o main main.c ./libshow.so

主函数:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "../inc/calc.h"
#include "../inc/show.h"     //可替换makefile的 -I参数添加路径inc

int main(void)
{
    int s;
    int i = 1;
    int j = 2;
    s = sum(i,j);
    printf ("%d\n", s);
    show(s,"sum");
    return 0;
}

注意:

因为gcc 或者g++时编译会在前者加lib、后者添加.a或者.so,所以有了另一种主函数写法

cd /etc

编辑 ld.so.conf

sudo vim ld.so.conf

加入 libshow.so 的路径  /lib

保存之后 再执行如下命令 ldconfig

gcc -o main main.c  -L. ./lshow -I../inc

或者指定lib路径

gcc -o main.o -c main.c -Wall -I../inc
gcc -o ../bin/main main.o -L../lib -lshow -lcalc

Makefile模板

#-------------------------配置区域-----------------------

#DIR指的是.o文件和.c文件所在的目录
DIR=

#BIN指的是最终生成的目标对象名(包括路径),它可以是可执行程序、动态链接库或静态链接库
BIN=$(DIR)/

#SHARE特指链接生成动态链接库对象时的编译选项
SHARE=--share

#CFLAG即compile flag,表示在编译时所加入的选项参数
#参数包括  
#-Wall  : 编译后显示所有警告信息
#-g     : 编译时加入调试信息,以便之后可以用gdb调试
#-fPIC  : 编译动态链接库时加入的选项
#-I./inc: -I选项指定从哪个目录寻找头文件,在这指定之后,在源文件中包含头文件就可以使用<>,这里./inc即为指定的目录
CFLAG=

#LFLAG即library flag,表示链接生成可执行程序时所要链接的所有库的选项参数
#-L./lib : -L指示动态/静态链接库所在的目录,这里./lib即所在的目录
#-l      : -l指示动态/静态链接库的名字,注意: 这里的库名字并不包括前缀(lib)和后缀(.a或.so)
#$(SHARE) : 取SHARE变量对应的动态链接库链接选项--share
LFLAG=

#CC即编译链接命令gcc -o 用于编译或者链接动态库以及可执行程序
CC=gcc -o

#AR即ar -cr ,ar -cr是专门链接生成静态库的命令
#-c : 即create,创建静态库
#-r : 即replace,当静态库改变时,替代原有静态库
AR=ar -cr

#最终用的是哪个链接命令
#链接生成动态库和可执行程序用CC
#链接生成静态库用AR
CO=$(CC)

#-------------------------以下为通用不变区域-----------------------

#SRC指的是指定目录下的所有.c文件名,OBJ指的是指定目录下的所有.o文件名
SRC=$(wildcard $(DIR)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))

#链接命令
all:$(BIN)
$(BIN):$(OBJ)
    $(CO) $@ $^ $(LFLAG)

#编译命令
$(DIR)/%.o:$(DIR)/%.c
    $(CC) $@ -c $< $(CFLAG)

#清除无用文件
.PHONY:clean
clean:
    rm $(OBJ) $(BIN)

$@ --目标文件,$^ --所有的依赖文件,$< --第一个依赖文件

.PHONY :是一个伪目标,可以防止在Makefile中定义的只执行命令的目标和工作目录下的实际文件出现名字冲突,另一种是提交执行makefile时的效率。

wildcard : 扩展通配符

notdir : 去除路径

patsubst :替换通配符

-I../inc :通用头文件 

整个项目工程都包括什么?

一个工程目录下一般有7个目录,一个联合编译Makefile文件:

<1>、bin目录:一般存放可执行程序

<2>、etc目录:存放配置文件

<3>、lib目录 :存放所有的库文件,包括动态库和静态库

<4>、inc目录:存放所有的公共头文件,一般是动态库和静态库对应的头文件

<5>、src目录:存放项目源码文件和编译它的Makefile文件

<6>、static目录:存放静态库源文件和编译它的Makefile文件

<7>、dynamic目录:存放动态库源文件和编译它的Makefile文件

为src、static、dynamic目录下的源文件编写不同的Makefile文件

为static目录,即静态链接库源代码目录。在此目录下要生成静态链接库文件libstatic_test.a

#------------------------------配置区域----------------------------

DIR=.

#静态库名以lib为前缀,.a为后缀
BIN=../lib/libcalc.a

SHARE=--share

CFLAG=

LFLAG=

CC=gcc -o

AR=ar -cr

#编译静态库用ar -cr命令
CO=$(AR)
#-------------------------以下为通用不变区域-----------------------

SRC=$(wildcard $(DIR)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))
#$(info $(OBJ))

all:$(BIN)
$(BIN):$(OBJ)
    $(CO) $@ $^ $(LFLAG)

$(DIR)/%.o:$(DIR)/%.c
    $(CC) $@ -c $< $(CFLAG)

.PHONY:clean
clean:
    rm $(OBJ) $(BIN)

为dynamic目录,即动态链接库源代码目录,在此目录下生成动态链接库 libshow.so

#------------------------------配置区域----------------------------

DIR=.

#动态库名以lib为前缀,以.so为后缀
BIN=../lib/libshow.so

SHARE=--share

#动态链接库编译时需要-fPIC选项
CFLAG=-fPIC

#链接动态库需要--share选项
LFLAG=$(SHARE)

CC=gcc -o

AR=ar -cr

#编译动态链接库用gcc -o命令
CO=$(CC)
#-------------------------以下为通用不变区域-----------------------

SRC=$(wildcard $(DIR)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))

all:$(BIN)
$(BIN):$(OBJ)
    $(CO) $@ $^ $(LFLAG)

$(DIR)/%.o:$(DIR)/%.c
    $(CC) $@ -c $< $(CFLAG)

.PHONY:clean
clean:
    rm $(OBJ) $(BIN)

为src目录,即工程源代码目录。在此目录下要通过链接动态链接库libshow.so和静态库libcalc.a 来生成可执行文件main

#-------------------------配置区域-----------------------

#源码所在的目录
DIR=.

#在源码所在目录下生成可执行文件main
BIN=../bin/main

SHARE=--share

#显示所有编译警告,并指示公共头文件(静态库和动态库的头文件)所在目录
CFLAG= -Wall -I../inc

#在../lib目录中链接两个外部库文件
LFLAG=-L../lib -lshow -lcalc

CC=gcc -o

AR=ar -cr

#使用gcc -o 链接命令
CO=$(CC)

#-------------------------以下为通用不变区域-----------------------

#SRC指的是指定目录下的所有.c文件名,OBJ指的是指定目录下的所有.o文件名
SRC=$(wildcard $(DIR)/*.c)
OBJ=$(patsubst %.c, %.o, $(SRC))

#链接命令
all:$(BIN)
$(BIN):$(OBJ)
    $(CO) $@ $^ $(LFLAG)

#编译命令
$(DIR)/%.o:$(DIR)/%.c
    $(CC) $@ -c $< $(CFLAG)

#清除无用文件
.PHONY:clean
clean:
    rm $(OBJ) $(BIN)

本程序tree

编写联合编译Makefile文件

.PHONY:test
test:
    make -C ./dynamic
    #make -C:进入指定的目录下执行make命令
    make -C ./static
    #将静态、动态库文件拷贝到lib目录下
    #cp ./static/libstatic_test.a  ./lib
    #cp ./dynamic/libdynamic_test.so  ./lib
    
    make -C ./src

.PHONY:install
install:
    #为lib目录下的动态链接库文件在/usr/lib目录下创建软连接,这里使用的必须是绝对路径
    sudo ln -s /mnt/test/lib/libshow.so  /usr/lib/libshow.so 
    #将最后生成的可执行文件main拷贝到./bin目录下
    #mv ./src/main ./bin

.PHONY:clean
clean:
    make clean -C ./dynamic
    #make clean -C: 进入指定目录下执行make clean命令
    make clean -C ./static
    make clean -C ./src

最后得出:

Makefile、多Makefile编译静态库、动态库、SRC实例总结相关推荐

  1. linux centos 编译Lua5.2.0 静态库 动态库

    一 lua下载 lua5.2.0下载地址 :http://download.csdn.net/download/yzf279533105/10109818 二 笔者这里linux环境为centos6. ...

  2. [动态库]动态库生成和使用以及Makefile编写

    转自:https://www.cnblogs.com/ljtknowns/p/5647793.html 文件目录结构如下 1 dynamiclibapp.c 2 Makefile 3 comm/inc ...

  3. C/C++ 跨平台交叉编译、静态库/动态库编译、MinGW、Cygwin、CodeBlocks使用原理及链接参数选项

    0. 引言 UNIX是一个注册商标,是要满足一大堆条件并且支付可观费用才能够被授权使用的一个操作系统.linux是unix的克隆版本,是由其创始人Linus和诸多世界知名的黑客手工打造的一个操作系统. ...

  4. 编译c语言动态库,使用gcc、g++编译C/C++源程序,静态库和动态库创建方式

    后缀为.c的,gcc把它当作是C程序,而g++当作是c++程序: 后缀为.cpp的,两者都会认为是c++程序. 注意,虽然c++是c的超集,但是两者对语法的要求是有区别的. 编译阶段,g++会调用gc ...

  5. 【Android NDK 开发】Visual Studio 2019 使用 CMake 开发 JNI 动态库 ( 动态库编译配置 | JNI 头文件导入 | JNI 方法命名规范 )

    文章目录 I . JNI 与 NDK 区别 II . Visual Studio 编译动态库 III. 配置 导入 jni.h 头文件 IV . IntelliJ IDEA Community Edi ...

  6. Linux-(C/C++)生成并使用静态库/动态库

    静态库/动态库概要 在Windows下静态库的后缀为:.lib.动态库后缀为:.dll:而在Linux下静态库的后缀为:.a.动态库的后缀为:.so. 那么什么是静态库呢? 首先我们来看看程序编译的大 ...

  7. NDK01-打包静态库 动态库在mk和cmake环境配置使用

    动态库和静态库 动态库: libxxx.so 运行的时候,才会去加载,加载一次就在内存中存在副本,其他地方使用就都是公用的.使用场景就是 高德百度sdk对外开房 静态库: libxxx.a 编译期把静 ...

  8. XCode 创建:静态库 动态库 Framework

    目录 使用 XCode 创建 .a 格式的静态库 使用 XCode 创建 .framework 格式的静态库 使用 XCode 创建 .dylib 格式的动态库 使用 XCode 创建 .framew ...

  9. Linux学习---静态库 动态库

    今天我们主要来说说Linux系统下基于动态库(.so)和静态(.a)的程序那些猫腻.在这之前,我们需要了解一下源代码到可执行程序之间到底发生了什么神奇而美妙的事情. 在Linux操作系统中,普遍使用E ...

  10. 软件库Library之静态库\动态库和静态加载\动态加载

    软件库Library之静态库\动态库和静态加载\动态加载 动态库之导入库 https://blog.csdn.net/wallaceli1981/article/details/5740718 * 动 ...

最新文章

  1. 【Linux 内核 内存管理】虚拟地址空间布局架构 ② ( 用户虚拟地址空间组成 | 内存描述符 mm_struct 结构体源码 )
  2. python中的字符串是什么,一文秒懂Python中的字符串
  3. python包括哪些部分_python基础知识部分练习大全
  4. 代码实现【mini版】——给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url?
  5. layui结合springboot上传图片
  6. 电脑任务栏跑到右边去了_电脑没有声音怎么解决 电脑没有声音解决方法【详解】...
  7. postgis 导出 栅格_postgis常见的空间数据的导入导出
  8. 水印生成器第2版[原图质量水印可自定义设置]
  9. c 结构体 函数 指针
  10. C++ (MFC)将字符串保存到指定目录下的文本中
  11. ASCII码对照表(包括十六进制、十进制和字符)
  12. 一个完整的机器学习模型的流程
  13. sdk manger
  14. 汇编指令学习(AND,OR,XOR,NOT)
  15. Eureka解密(1)------ 注册实例服务发现理解
  16. Hyperledger Avalon启动笔记
  17. Pt100转RS-485,热电阻温度Modbus数据采集模块 WJ125
  18. 自己动手写操作系统0
  19. 虚拟同步机(VSG)matlab/simulink控制仿真
  20. windows 远程桌面连接 用户账户限制

热门文章

  1. cola,一个做consensus clustering的R包
  2. Python中Text函数常用增删改查阅用法实例汇总
  3. c语言编程调试找不到路径,VScode 调试C/C++时出现无法打开“X”: 找不到文件(file:///XXXX) 的解决办法...
  4. 需要vmwareinstalldisk上的文件vmnet_手机上一键就能进行PDF与其他文件的相互转换,果然厉害到不行...
  5. ios html 禁止下拉,ios禁止页面下拉
  6. vue-router路由安装与使用
  7. linux vps 可视化监控,CentOS 7安装Grafana 4及结合Zabbix3.2实现可视化监控图形
  8. Qt工作笔记-moveToThread的基本使用以及让线程安全退出
  9. C++工作笔记-对static_cast的进一步认识(强制转换改变内存,并且删除存在的问题)
  10. 史上最详细的Linux网卡ifcfg,史上最详细的Linux网卡ifcfg-eth0配置详解