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