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

Posted

技术标签:

【中文标题】使用静态库链接、编译和运行 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 程序的主要内容,如果未能解决你的问题,请参考以下文章

关于动态库和静态库的问题。

gcc 编译使用动态链接库和静态链接库

嵌入式 Linux C语言——静态库函数和动态库函数

VS2008如何设置才能使库函数静态链接

gcc编译工具生成动态库和静态库之一----介绍

什么叫静态库和动态库