使用静态库链接、编译和运行 c 程序

     2023-02-22     214

关键词:

【中文标题】使用静态库链接、编译和运行 c 程序【英文标题】:linking, compiling and running a c program with a static library 【发布时间】:2017-02-26 00:10:00 【问题描述】:

我是 C 开发新手。

A我在 CLion 中构建了一个库(静态)

图书馆.h

#ifndef MYLIB_LIBRARY_H
#define MYLIB_LIBRARY_H

int add(int a, int b);
int sub(int a, int b);

#endif

library.c

#include "library.h"
#include <stdio.h>

int add(int a, int b) 
    return a + b;


int sub(int a, int b) 
    return a - b;

CMakeLists.txt

cmake_minimum_required(VERSION 3.6)
project(MyLib)

set(CMAKE_C_STANDARD 99)

set(SOURCE_FILES library.c library.h)
add_library(MyLib $SOURCE_FILES)


B.创建名为App的C可执行项目并将libMyLib.a复制到App的lib目录中。

ma​​in.c

#include <stdio.h>
#include "library.h" // error

int main() 
    printf("Hello, World!\n", add(1, 2)); // error
    return 0;

CMakeLists.txt 项目 App 和链接器的指定文件夹。

cmake_minimum_required(VERSION 3.6)
project(App)

set(CMAKE_C_STANDARD 99)

set(SOURCE_FILES main.c)
link_directories($PROJECT_SOURCE_DIR/lib)
add_executable(App $SOURCE_FILES)

问题。如何使用静态库使我的程序工作?

【问题讨论】:

【参考方案1】:

为了让您的示例正常工作,我必须更改几件事:

    在App目录下创建include目录。 将library.h 放入此包含目录中。

    修改项目CMakeLists.txt文件:

    cmake_minimum_required(VERSION 3.6)
    project(App)
    
    set(CMAKE_C_STANDARD 99)
    set(SOURCE_FILES main.c)
    # get libMyLib.a
    find_library(MY_LIB
        NAMES libMyLib.a
        PATHS $PROJECT_SOURCE_DIR/lib)
    # get library.h
    include_directories($PROJECT_SOURCE_DIR/include)
    
    add_executable(App $SOURCE_FILES)
    # link App with libMyLib.a
    target_link_libraries(App $MY_LIB)
    

【讨论】:

谢谢,它成功了。我还有一个问题,分发库的约定是什么。人们对第 3 方库的期望如何,看来我会将 .a.h 文件一起分发。我还应该将libMyLib.alibrary.h 都放在包含文件夹中吗? 有什么建议吗? 我没有任何分发库的经验,但是,我认为惯例是为.a.so 文件提供lib/ 目录,并为.h 文件提供一个包含目录。您还可以考虑为库添加文档和测试。这是使用 cmake 的 jsoncpp 库 repo 的链接:github.com/open-source-parsers/jsoncpp。它们实际上提供了构建库所需的源文件和头文件,最终用户是使用 cmake/make 构建它的人。【参考方案2】:

这一行:

printf("Hello, World!\n", add(1, 2)); // error

在编译时产生错误,而不是链接时

原因是 printf() 函数被作为第一个参数(格式字符串)Hello, World!\n 和第二个参数传递:add(1,2) 但是,格式字符串中的结果没有格式说明符致电add()

编译器会输出消息:

warning: too many arguments for format [-Wformat-extra-args]

在纠正编译问题之前没有理由查看 Cmakelists.txt 文件

【讨论】:

感谢最终我在另一个关于 cmake 的答案之后修复了它,我想知道分发 3rd 方 c 库时的目录结构是什么,以及将它们放在你的项目中的约定是什么?跨度> 最简单的方法是将库放在(您的偏好)目录中,然后将链接放在链接器通常会看到的位置,例如/usr/lib/ 从外观的角度来看,我的库项目在我的 .a 文件名前加上了 lib,我手动重命名但编译器在链接时抱怨。我该如何配置来创建一个我喜欢的名字? @User794691,链接器有自己的规则和语法。你喜欢什么并不重要,重要的是链接器喜欢什么。

如何编译c/fortran动态/静态链接库

...就是libc里面的函数。如果有了启动函数(main),main里面使用了printf,就可以通过静态链接技术,从libc中提取出printf所在的文件加入到可执行文件中,如果printf还需要其它函数,就继续搜索并加入列表,直到形成一个闭包。这... 查看详情

c中的动态库与静态库

...复制到程序文件的适当位置,最终生成可执行文件。使用静态链接库生成的文件通常体积较大,但运行时不再依赖库文件,可以拷贝到别的设备上运行。在Linux中静态链接库文件的后缀名通常用.a表示;在Windows系... 查看详情

8静态函数库设计

...库  2、动态链接库函数库 -存放位置Linux应用程序使用的主要函数库均存放于/lib,/usr/lib目录下,其中采用*.so.*方式命名的是动态函数库,而以*.a方式命令的是静态函数库。静态链接库-特点1、程序所要用到的库函数代码在... 查看详情

windows中lib和dll的区别与使用

...xe即可,不需要dll文件)共有两种链接方式:1、动态链接使用动态链接库,允许可执行模块(.dll文件或.exe文件)仅包含在运行时定位DLL函数的可执行代码所需的信息。2、静态链接使用静态链接库,链接器从静态链接库LIB获取所... 查看详情

链接库函数

...赖库。 编译调用库函数的C代码时,需要链接库比如使用math.h中函数的代码编译时gccabc.c-oapp-lm//链接时可以用-lxxx来指示链接器去 查看详情

c语言学习笔记--动态库和静态库的使用

1.C语言中的链接器 (1)每个C语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件。 (2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正确的衔接... 查看详情

c/c++编译问题,静态库,动态库。

现在在一个文件夹下面有动态库libtest.so,libalex.so,有一个静态库libtest.a,我想编译main.c链接动态库libalex.so和静态库libalex.a,怎么做?试过,不行的有:1.g++main.c-L./-lalex-static-ltest(这样static是作用全局的,全用静态库)2.g++main.c-L./-lalex... 查看详情

为啥 C 程序会在运行时针对 C++ 库编译和链接 C 编译器然后 SIGILL?

】为啥C程序会在运行时针对C++库编译和链接C编译器然后SIGILL?【英文标题】:WhywouldaCprogramcompileandlinkwithaCcompileragainstC++librariesthenSIGILLatruntime?为什么C程序会在运行时针对C++库编译和链接C编译器然后SIGILL?【发布时间】:2016-01-... 查看详情

c++中lib和dll的区别,生成以及使用详解

...行文件中包含了库代码的一份完整拷贝;缺点就是被多次使用就会有多份冗余拷贝。即静态库中的指令都全部被直接包含在最终生成的EXE文件中了。在vs中新建生成静态库的工程,编译生成成功后,只产生一个.lib文件动态库:动... 查看详情

什么叫静态库和动态库

两者区别:一,静态库的使用需要:1包含一个对应的头文件告知编译器lib文件里面的具体内容2设置lib文件允许编译器去查找已经编译好的二进制代码二,动态库的使用:程序运行时需要加载动态库,对动态库有依赖性,需要手... 查看详情

静态库和共享库(代码片段)

...而是程序在运行时由系统动态加载到内存中供程序调用。使用动态库的优点是系统只需载入一次动态库,不同的程序可以得到内存中相同的动态库的副本,因此节省了很多内存。静态库静态库.a结尾命名格式:lib 查看详情

静态函数库的制作和使用

...库是多组经过验证的常用函数的集合,编写C语言程序时使用库函数,既可以提高程序运行效率,又可以提高编程质量,使用方法如#include和#include。根据使用库函数时,函数库加载时机的差异,将函数库分为静态函数库和动态函... 查看详情

静态链接库和动态链接库(代码片段)

...静态链接库staticlinklibrary。共有两种链接方式:动态链接使用动态链接库,允许可执行模块(.dll文件或.exe文件)仅包 查看详情

为啥我无法链接到使用动态并行和可分离编译的 CUDA 静态库?

】为啥我无法链接到使用动态并行和可分离编译的CUDA静态库?【英文标题】:Whycan\'tIlinktomyCUDAstaticlibrarythatusesDynamicParallelismandSeparableCompilation?为什么我无法链接到使用动态并行和可分离编译的CUDA静态库?【发布时间】:2021-12-0... 查看详情

编译链接实战(16)静态库vs动态库

...后将PC指针指向entry就可以运行了,什么场景下会这样使用呢?简单的应用程序,不依赖于其他模块依赖于其他模块,其他模块以静态库的方式链接到应用程序优点:程序是一个完整的可执行单元,不需要... 查看详情

c中的动态库与静态库

...复制到程序文件的适当位置,最终生成可执行文件。使用静态链接库生成的文件通常体积较大,但运行时不再依赖库文件,可以拷贝到别的设备上运行。在Linux中静态链接库文件的后缀名通常用.a表示;在 查看详情

gcc编译过程与动态链接库和静态链接库(代码片段)

...二进制形式,可以被操作系统载入内存执行。库有两种:静态库(.a、.lib)和动态库(.so、.dll)。windows上对应的是.lib.dlllinux上对应的是.a.so在这里先介绍下Linux下的gcc编译的几个选项g++-chellospeak.cpp会将hellospeak.cpp选项-c用来告诉... 查看详情

linux动态链接和静态链接简析

参考技术Alinux动态链接和静态链接简析1.生成静态链接库gcc-ch.c-oh.oarcqslibh.ah.o//ar是生成库的命令,cqs是参数,libh.a是生成的静态链接库须以lib开头,h是库名,a表示是静态链接库,h.o是刚才生成目标文件2.生成动态链接库www.zhishiwu.co... 查看详情