使用 CMake 编写 Windows 静态库
最近有一个多个 .h .cc .cpp 编译成静态库的需求,故记录下过程
静态库不同于动态库,它不需要 main 入口,只要各个源文件与头文件能对应,也就是源文件和头文件引用的头文件能够找到函数的符号文件,即可编译成功
新手教程参考:
因为只需要用到部分源文件,故单独列出,我的 CMakeLists 写法:
cmake_minimum_required(VERSION 3.12)
project(MyLibrary) # 设置编译选项
set(CMAKE_GENERATOR_PLATFORM x86) set(SOURCES
cuteui/base/base64.cc
cuteui/base/md5.cc
cuteui/base/sha1_portable.cc
cuteui/base/counter.cc
cuteui/base/windows_version.cc
cuteui/base/at_exit.cc
cuteui/base/debug/alias.cc
cuteui/base/debug/debugger.cc
cuteui/base/debug/debugger_win.cc
cuteui/base/debug/stack_trace.cc
cuteui/base/debug/stack_trace_win.cc
cuteui/base/win/event_trace_provider.cc
cuteui/base/lock.cc
cuteui/base/lock_impl_win.cc
cuteui/base/event.cc
cuteui/base/callback.cc
cuteui/base/lazy_instance.cc
cuteui/base/memory/singleton.cc
cuteui/base/threading/platform_thread.cc
cuteui/base/rand_util.cc
cuteui/base/rand_util_win.cc
cuteui/base/vlog.cc
cuteui/base/logging.cc
cuteui/base/logging_win.cc
cuteui/base/json/values.cc
cuteui/base/json/values_op.cc
cuteui/base/json/json_reader.cc
cuteui/base/json/json_writer.cc
cuteui/base/json/string_escape.cc
cuteui/base/file/file.cc
cuteui/base/file/filedata.cc
cuteui/base/file/file_path.cc
cuteui/base/file/file_path_constants.cc
cuteui/base/string/string_util.cc
cuteui/base/string/stringprintf.cc
cuteui/base/string/string_number_conversions.cc
cuteui/base/string/utf_string_conversion_utils.cc
cuteui/base/string/string_piece.cc
cuteui/base/string/utf_string_conversions.cc
cuteui/base/string/string_split.cc
cuteui/base/operation/fileselect.cc
cuteui/base/operation/threadpool.cc
cuteui/base/third_party/dmg_fp/dtoa.cc
cuteui/base/third_party/dmg_fp/g_fmt.cc
cuteui/base/third_party/icu/icu_utf.cc
cuteui/base/third_party/modp_b64/modp_b64.cc
common/bbiconv.cc
common/Buffer.cpp
common/properties.cpp
common/strconv.cpp
common/string_easy_conv.cc
common/Urlcode.cpp
common/wiseint.cc
) # Add a library with the above sources
add_library(${PROJECT_NAME} STATIC ${SOURCES}) # 添加头文件搜索路径
include_directories(common cuteui)
在 windows 上 cmake 后会出现 .sln 文件,打开后,项目默认为 x64,并且很多配置都是默认值,直接编译的话会出现很多错误,可以按照自己的需求来手动配置
可能 CMakeLists 里能设置这些选项,我目前还不太会,所以就在项目中手动配置的
编译过程中会遇到很多奇怪的错误,不过都能解决,这边总结一下:
- 出现头文件找不到的情况,可能是存在目录路径的问题,建议加上相对路径
- 明明这个函数有声明,却显示未声明,可能是需要添加预处理器定义,比如我遇到找不到 rand_s 的情况,最后加上 _CRT_RAND_S 解决的(在 C/C++->Preprocessor->Preprocessor Definitions 中添加)
- 可能出现 sdk 中的函数冲突的问题,这个问题经常出现,可以添加一个 stdafx.h 通用头文件,在该头文件添加 winsock2.h 和 windows.h
- 某些函数找不到声明,需要仔细找到该函数的声明文件的位置,使用全局搜索(比如 notepad++ 的文件查找)一般能找到,在项目配置中添加头文件路径即可
- 编译静态库有 debug 和 release 之分,建议两种都编译一下
一些文章参考:
更新:
上面的 CMakeLists.txt 只是简单的将源文件加入VS 工程中,并没有设置 VS 的编译参数,比如设置预处理定义,设置 Unicode 字节,多线程编译等等
cmake_minimum_required(VERSION 3.12)
# STREQUAL 比较函数
if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Windows")
# 创建 win32 工程
# 以 x86 工程架构构建
set(CMAKE_GENERATOR_PLATFORM Win32)
set(CMAKE_GENERATOR_TOOLSET "host=x86" CACHE STRING "Platform Toolset" FORCE)
endif()
project(FrLibrary) if (WIN32 OR CMAKE_SYSTEM_NAME STREQUAL "Windows")
# 不构建 ZEROCHECK 工程
set(CMAKE_SUPPRESS_REGENERATION true)
# 以 MFC 标志构建
set(CMAKE_MFC_FLAG 1)
# 只构建 Debug 和 Release,/Zi 参数表示生成 pdb 文件
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd /Zi")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /Zi")
# 添加预处理定义参数
add_compile_definitions(_CRT_RAND_S NOMINMAX)
# 以 Unicode 字节构建
add_definitions(-D_UNICODE)
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
# Linux-specific configuration
endif() # 设置宏路径
set(BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cuteui/base)
set(COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/common) set(SOURCES
${BASE_DIR}/base64.cc
${BASE_DIR}/md5.cc
${BASE_DIR}/sha1_portable.cc
${BASE_DIR}/counter.cc
${BASE_DIR}/windows_version.cc
${BASE_DIR}/at_exit.cc
${BASE_DIR}/debug/alias.cc
${BASE_DIR}/debug/debugger.cc
${BASE_DIR}/debug/debugger_win.cc
${BASE_DIR}/debug/stack_trace.cc
${BASE_DIR}/debug/stack_trace_win.cc
${BASE_DIR}/win/event_trace_provider.cc
${BASE_DIR}/lock.cc
${BASE_DIR}/lock_impl_win.cc
${BASE_DIR}/event.cc
${BASE_DIR}/callback.cc
${BASE_DIR}/lazy_instance.cc
${BASE_DIR}/memory/singleton.cc
${BASE_DIR}/threading/platform_thread.cc
${BASE_DIR}/rand_util.cc
${BASE_DIR}/rand_util_win.cc
${BASE_DIR}/vlog.cc
${BASE_DIR}/logging.cc
${BASE_DIR}/logging_win.cc
${BASE_DIR}/json/values.cc
${BASE_DIR}/json/values_op.cc
${BASE_DIR}/json/json_reader.cc
${BASE_DIR}/json/json_writer.cc
${BASE_DIR}/json/string_escape.cc
${BASE_DIR}/file/file.cc
${BASE_DIR}/file/filedata.cc
${BASE_DIR}/file/file_path.cc
${BASE_DIR}/file/file_path_constants.cc
${BASE_DIR}/string/string_util.cc
${BASE_DIR}/string/stringprintf.cc
${BASE_DIR}/string/string_number_conversions.cc
${BASE_DIR}/string/utf_string_conversion_utils.cc
${BASE_DIR}/string/string_piece.cc
${BASE_DIR}/string/utf_string_conversions.cc
${BASE_DIR}/string/string_split.cc
${BASE_DIR}/operation/fileselect_win.cc
${BASE_DIR}/operation/threadpool.cc
${BASE_DIR}/third_party/dmg_fp/dtoa.cc
${BASE_DIR}/third_party/dmg_fp/g_fmt.cc
${BASE_DIR}/third_party/icu/icu_utf.cc
${BASE_DIR}/third_party/modp_b64/modp_b64.cc
${COMMON_DIR}/bbiconv.cc
${COMMON_DIR}/Buffer.cpp
${COMMON_DIR}/properties.cpp
${COMMON_DIR}/strconv.cpp
${COMMON_DIR}/string_easy_conv.cc
${COMMON_DIR}/Urlcode.cpp
${COMMON_DIR}/wiseint.cc
) # 如果是以 Debug 方式构建,输出的文件末尾加 'd'
if(NOT CMAKE_DEBUG_POSTFIX)
set(CMAKE_DEBUG_POSTFIX d)
endif() # 添加头文件
include_directories(${CMAKE_CURRENT_SOURCE_DIR} common cuteui) # 输出 lib 静态库
add_library(${PROJECT_NAME} STATIC ${SOURCES})
参考:
- PLATFORM_ID vs. WIN32 vs. CMAKE_SYSTEM_NAME
- https://github.com/elephantrobotics/myCobotCpp/blob/release/CMakeLists.txt
使用 CMake 编写 Windows 静态库的更多相关文章
- 使用CMake编译跨平台静态库
在开始介绍如何使用CMake编译跨平台的静态库之前,先讲讲我在没有使用CMake之前所趟过的坑.因为很多开源的程序,比如png,都是自带编译脚本的.我们可以使用下列脚本来进行编译: . / con ...
- c++调用自己编写的静态库(通过eclipse)
转:https://blog.csdn.net/hao5335156/article/details/80282829 参考:https://blog.csdn.net/u012707739/arti ...
- (转)HelloWorld CMake CMake中构建静态库与动态库及其使用
继续完善Hello World,建立它的共享库, 包括静态库和动态库. 本节的任务: 1,建立一个静态库和动态库,提供HelloFunc函数供其他程序编程使用,HelloFunc 向终端输出Hello ...
- cmake 强制链接静态库
add_executable(main main.cpp) target_link_libraries(main ${CMAKE_SOURCE_DIR}/libbingitup.a) 静态库和动态库共 ...
- Windows静态库和动态库的创建和使用
偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件.然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DL ...
- windows静态库的使用
最近在学Zeromq(像框架一样的一个socket library)的使用,里面有关于库的使用问题.今天就来复习下静态库的使用: 使用静态库是重用代码的一种绝佳方式.您不必在自己创建的每个程序中重新实 ...
- Windows静态库和动态库的创建和使用(VS2005)
偶们在实际的编程开发中,经常会遇到运行时无法找到某个DLL文件或者链接时无法找到某个LIB文件.然后,我们就开始乱GOOGLE一下,然后将VS2005的设置改变一下,或许就Ok了,我们将别人开发的DL ...
- opencv+ linux + cmake 生成 opencv静态库
您可以省去如下步骤,直接下载我编译好的: http://download.csdn.net/detail/u011258240/9710331 一.编译opencv2.4 不带contrib 1. ...
- Windows静态库和动态库区别
个人建议:能使用静态库的就不要使用动态库,能使用隐式调用的就不要用显示调用. 注意: (1)动态库中的.lib文件叫做导入库,对于导入库而言,其实际的执行代码位于动态库中,导入库只包含了地址符 ...
- makefile编写---.a静态库的生成和调用
#.SUFFIXES: .c .o Cc =gcc #OSA=/data/users/osa IncDir=-I. -I./ Debug = -g Cflags = -c $(DEBUG) Libs ...
随机推荐
- [转帖]docker使用buildx构建多平台(x86,arm64)构架镜像
https://blog.csdn.net/atzqtzq/article/details/128583331 配置文件激活buildx docker目前使用版本为Server Version: 20 ...
- [转帖]官网:Nacos的授权验证
https://nacos.io/zh-cn/docs/v2/guide/user/auth.html 注意 Nacos是一个内部微服务组件,需要在可信的内部网络中运行,不可暴露在公网环境,防止带来安 ...
- OpenEuler2203安装Redislabs的简单记录
OpenEuler2203安装Redislabs的简单记录 背景 操作系统国产化的需求下 想着都转型到openEuler上面来. 应用和容器都没什么问题了,现在考虑一下一些企业软件 最近一直在想研究一 ...
- [转贴]手把手教你 GitLab 的安装及使用
https://www.jianshu.com/p/b04356e014fa 前言 新入职公司,发现公司还在使用落后生产工具 svn,由于重度使用过 svn 和 git ,知道这两个工具之间的差异,已 ...
- 【笔记】学到几个 golang 代码小技巧
作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢! cnblogs博客 zhihu Github 公众号:一本正经的瞎扯 从这篇文章学到:10个令人惊叹的Go语言技巧,让你的代码更 ...
- 【K哥爬虫普法】辛苦钱被中间商抽走八成,还因此锒铛入狱
我国目前并未出台专门针对网络爬虫技术的法律规范,但在司法实践中,相关判决已屡见不鲜,K 哥特设了"K哥爬虫普法"专栏,本栏目通过对真实案例的分析,旨在提高广大爬虫工程师的法律意识, ...
- 【JS 逆向百例】XHR 断点调试,Steam 登录逆向
声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 逆向目标 目标:Steam ...
- Qt "有效且启用的储存库"问题
传送门 : https://www.cnblogs.com/SaveDictator/p/8532664.html 看就完了, 反正我好了 https://mirrors.tuna.tsinghua. ...
- ShardingSphere
目录 1.ShardingSphere分表与分库分表 2.ShardingSphere分库分表查询 3.自定义分片算法实现range查询 4.SPI扩展机制概述 5.stand通过SPI实现range ...
- GaussDB(for MySQL)剪枝功能,让查询性能提升70倍!
作者,祝青平,华为云数据库内核高级工程师.擅长数据库优化器内核研发,9年数据库内核研发经验,参与多个TP以及AP数据库的研发工作. 近日,华为云数据库社区下面有这样一条用户提问留言:请问,如何通过My ...