使用Amalgamate将C/C++项目合并成一个.h/.c[pp]文件
简述
C/C++开源库一般是一堆的头文件和源文件,做到声明和实现分离,减小单个模块大小,这在设计上是很好的,但是用起来稍显麻烦。在网上看到有好心人推荐了一个开源工具Amalgamate,专门用来对C/C++的头文件和源文件进行合并用的,于是尝试了一下。
编译过sqlite源码的应该知道,sqlite3源码包有一个是指包含sqlite3.h、sqlite3_ext.h、sqlite.c等为数不多几个代码文件的(也有分开的),嵌入到项目中非常方便。这就是用Amalgamate进行合并的。
下载并编译Amalgamate
下载很简单,这里就不细述了
git clone https://github.com/vinniefalco/Amalgamate.git
编译也很简单,直接使用VS打开Amalgamate\Builds\VisualStudio2010\Amalgamate.vcxproj,然后编译生成即可。
最后的示例下载中有我编译的程序。
# gcc 编译
g++ Amalgamate.cpp juce_core_amalgam.cpp -o Amalgamate -lpthread -ldl
# clang编译
clang++ Amalgamate.cpp juce_core_amalgam.cpp -o Amalgamate -lpthread -ldl
具体的使用可以参考程序的帮助信息。
将libuv合并为单一头文件和源文件版本(Windows下)
用于合并的模板文件编写可以参考https://github.com/vinniefalco/Amalgams.git中的几个。
以libuv为例进行简单的说明。
先下载libuv的源码,目录结构如下:

首先先合并头文件
先编写一个头文件uv_all.h,里面把libuv-v1.9.1\include下的文件都include进来。
源码如下:
#include "android-ifaddrs.h"
#include "pthread-barrier.h"
#include "stdint-msvc2008.h"
#include "tree.h"
#include "uv.h"
#include "uv_all.h"
#include "uv-errno.h"
#include "uv-threadpool.h"
#include "uv-version.h"
#include "uv-win.h"
一个简单的做法就是cygwin或msys下使用命令ls *.h |xargs -I{} echo '#include "{}"'直接输出。
因为我这里只做windows平台的,所以把多余的都给删除了。
实际上因为uv.h已经把需要的都包含上了,所以这里直接使用uv.h也就够了。
运行下面命令生成合并后的头文件
Amalgamate.exe -i C:\Users\o\Documents\code\libuv-v1.9.1\include -w "*.h;*.c" C:\Users\o\Documents\code\libuv-v1.9.1\include\uv.h uv.h
执行完上面命令后会在当前目录生成一个新的uv.h文件,也就是合并后的文件。上面参数中-i后面的是附加包含目录,也就是和gcc中使用的-I是一样的。最后的uv.h是输出文件名,前面的是输入的配置模板文件。
合并源码文件
合并源码文件的做法和合并头文件的做法是一致的,先写一个配置文件uv_win_all.h(把src和src/win目录下所有文件都包含进来),内容如下:
#include "win/atomicops-inl.h"
#include "win/handle-inl.h"
#include "win/internal.h"
#include "win/req-inl.h"
#include "win/stream-inl.h"
#include "win/winapi.h"
#include "win/winsock.h"
#include "heap-inl.h"
#include "queue.h"
#include "uv-common.h"
#include "win/async.c"
#include "win/core.c"
#include "win/dl.c"
#include "win/error.c"
#include "win/fs.c"
#include "win/fs-event.c"
#include "win/getaddrinfo.c"
#include "win/getnameinfo.c"
#include "win/handle.c"
#include "win/loop-watcher.c"
#include "win/pipe.c"
#include "win/poll.c"
#include "win/process.c"
#include "win/process-stdio.c"
#include "win/req.c"
#include "win/signal.c"
#include "win/snprintf.c"
#include "win/stream.c"
#include "win/tcp.c"
#include "win/thread.c"
#include "win/timer.c"
#include "win/tty.c"
#include "win/udp.c"
#include "win/util.c"
#include "win/winapi.c"
#include "win/winsock.c"
#include "fs-poll.c"
#include "inet.c"
#include "threadpool.c"
#include "uv-common.c"
#include "version.c"
然后执行下面命令进行合并
Amalgamate.exe -i C:\Users\o\Documents\code\libuv-v1.9.1\include -i C:\Users\o\Documents\code\libuv-v1.9.1\src -w "*.h;*.c" C:\Users\o\Documents\code\libuv-v1.9.1\src\uv_win_all.c uv_win.c
合并后的文件中会遇到一些问题,需要手动修改一下。比如多出遇到uv_zero_重定义的问题,这个需要把第一次定义之后出现的都全部注释掉。
还有会遇到error LNK2019: 无法解析的外部符号 _InterlockedOr,该符号在函数 _uv_tty_line_read_thread@4 中被引用的问题,这个只需要使用VS2012之后的版本编译就没问题了。
合并后的源码及项目文件
这里不多说,直接放出下载链接 https://files.cnblogs.com/files/oloroso/libuv_webtest.7z
测试的代码部分来自于https://github.com/liigo/tinyweb.git
Amalgamate参数简单说明
| 参数 | 解释 |
|---|---|
| -s | 处理#include <xxx>的行,即处理包含在系统目录中的头文件(通常我们只需要处理双引号括起来的) |
| -w{wildcards} | 指定要处理的文件类型(后缀名),如果不是列表中指定的,那么即便使用#include包含也不会处理,默认设置是".cpp;.c;.h;.mm;*.m" |
-f {file|macro} |
在inlcude出现的所有行中强制重新指定文件或宏 |
-p {file|macro} |
避免在#include行中的后续出现中重新包含指定的文件或宏 |
| -d {name}={file} | 如果宏{name}出现在include包含行中,使用{file}替代 |
| -i {dir} | 在处理include包含时,可以在指定的{dir}目录中搜索文件 |
| -v | 输出详细信息 |
使用Amalgamate将C/C++项目合并成一个.h/.c[pp]文件的更多相关文章
- C#程序(含多个Dll)合并成一个Exe
把C#程序(含多个Dll)合并成一个Exe的超简单方法 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. 但是,很多时候我们本想开发一款只需要一 ...
- 将WinForm程序(含多个非托管Dll)合并成一个exe的方法
原文:将WinForm程序(含多个非托管Dll)合并成一个exe的方法 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. ILMerge能把托管dl ...
- 利用Costura.Fody制作绿色单文件程序(C#程序(含多个Dll)合并成一个Exe)
原文:利用Costura.Fody制作绿色单文件程序(C#程序(含多个Dll)合并成一个Exe) 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了.这 ...
- C# 实现将多个word文档合并成一个word文档的功能
前段时间项目上遇到这么一个需求,需要将多个OCR识别的word文档合并成一个,于是就在网上找了找,自己修改了一下.在这里跟大家分享一下,希望有用的到的. 要做多word文档合并,首先要导入Micros ...
- 多个jar包合并成一个jar包(ant)
https://blog.csdn.net/gzl003csdn/article/details/53539133 多个jar包合并成一个jar 使用Apache的Ant是一个基于Java的生成工具. ...
- 多个DLL合并成一个DLL
多个DLL合并成一个DLL,把DLL合并到Exe中的解决方案 1:) 下载 http://download.microsoft.com/download/1/3/4/1347C99E-9DFB-425 ...
- 多个UIImage合并成一个UIImage
多个UIImage合并成一个UIImage 创建两个UIImage UIImage *image1 = [UIImage imageNamed:@"iOSDevTip"]; UII ...
- 将Python项目打包成EXE可执行文件(单文件,多文件,包含图片)
解决 将Python项目打包成EXE可执行文件(单文件,多文件,包含图片) 1.当我们写了一个Python的项目时,特别是一个GUI项目,我们特备希望它能成为一个在Windows系统可执行的EXE文件 ...
- 多个EXCEL文件合并成一个
Python的numpy处理起来会比较方便,有空实现一下,这里是Excel内部代码的方式: 合并方法如下: 1.需要把多个excel表都放在同一个文件夹里面,并在这个文件夹里面新建一个excel.如图 ...
随机推荐
- 【C++】类前置声明范例
• 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的程序中,带注释的那行就是类B的前置说明.这是必须的,因为类A中用到了类B,而类B的声明出现在类A的后面 ...
- asp.net core 支付宝支付( 电脑2.0)
支付宝电脑支付实测在手机浏览器也可以唤醒手机支付宝进行支付,因此也可以作为支付宝手机web支付方式.支付宝电脑支付流程为使用支付宝官方sdk通过获取的支付宝参数构造DefaultAopClient实例 ...
- HDU4686 Arc of Dream 矩阵
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - HDU4686 题意概括 a0 = A0 ai = ai-1*AX+AY b0 = B0 bi = bi-1* ...
- BZOJ1853 [Scoi2010]幸运数字 容斥原理
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1853 题意概括 求一个区间范围内,近似幸运数字的个数. 定义: 幸运数字:仅由6或者8组成的数字. ...
- Nightmare HDU1072
非常标准的BFS 第一次写错了很多 1.到达4时设置为墙就好了 避免了死循环 2.不用开d数组 在结构体里面就行了 3.结构体初始化函数的写法: Node(int x=0,int y=0,int ...
- 037 关于pom.xml的一些问题的理解
最近在pom上出了一些问题,搞了一天才理解了一些问题,记录一下. 当在覆盖本地repository包之后,pom.xml上面出现了一个x. 当mvn->update project之后,还是有许 ...
- 匿名函数 lambda
lambda 参数 : 程序体 1. filter 与匿名函数结合运用 2. map与匿名函数结合运用
- ImportError: cannot import name cbook
Faster RCNN训练的时候,出现错误: from matplotlib import path, transforms File , in <module> from . impor ...
- JavaEE - 20181225
作者:沈世钧链接:https://www.zhihu.com/question/305924723/answer/557800752来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- 利用SQL为Code128码添加起始符和休止符
在利用code128码字体打印条码是,打印出来的条形码,扫描枪会出现认不出的情况,这种情况是由于直接将文本设置为code128字体而没有给他们指定起始符和休止符引起的. 经过查资料获发现好多人遇到这样 ...