简述

C/C++开源库一般是一堆的头文件和源文件,做到声明和实现分离,减小单个模块大小,这在设计上是很好的,但是用起来稍显麻烦。在网上看到有好心人推荐了一个开源工具Amalgamate,专门用来对C/C++的头文件和源文件进行合并用的,于是尝试了一下。

编译过sqlite源码的应该知道,sqlite3源码包有一个是指包含sqlite3.hsqlite3_ext.hsqlite.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]文件的更多相关文章

  1. C#程序(含多个Dll)合并成一个Exe

    把C#程序(含多个Dll)合并成一个Exe的超简单方法   开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. 但是,很多时候我们本想开发一款只需要一 ...

  2. 将WinForm程序(含多个非托管Dll)合并成一个exe的方法

    原文:将WinForm程序(含多个非托管Dll)合并成一个exe的方法 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了. ILMerge能把托管dl ...

  3. 利用Costura.Fody制作绿色单文件程序(C#程序(含多个Dll)合并成一个Exe)

    原文:利用Costura.Fody制作绿色单文件程序(C#程序(含多个Dll)合并成一个Exe) 开发程序的时候经常会引用一些第三方的DLL,然后编译生成的exe文件就不能脱离这些DLL独立运行了.这 ...

  4. C# 实现将多个word文档合并成一个word文档的功能

    前段时间项目上遇到这么一个需求,需要将多个OCR识别的word文档合并成一个,于是就在网上找了找,自己修改了一下.在这里跟大家分享一下,希望有用的到的. 要做多word文档合并,首先要导入Micros ...

  5. 多个jar包合并成一个jar包(ant)

    https://blog.csdn.net/gzl003csdn/article/details/53539133 多个jar包合并成一个jar 使用Apache的Ant是一个基于Java的生成工具. ...

  6. 多个DLL合并成一个DLL

    多个DLL合并成一个DLL,把DLL合并到Exe中的解决方案 1:) 下载 http://download.microsoft.com/download/1/3/4/1347C99E-9DFB-425 ...

  7. 多个UIImage合并成一个UIImage

    多个UIImage合并成一个UIImage 创建两个UIImage UIImage *image1 = [UIImage imageNamed:@"iOSDevTip"]; UII ...

  8. 将Python项目打包成EXE可执行文件(单文件,多文件,包含图片)

    解决 将Python项目打包成EXE可执行文件(单文件,多文件,包含图片) 1.当我们写了一个Python的项目时,特别是一个GUI项目,我们特备希望它能成为一个在Windows系统可执行的EXE文件 ...

  9. 多个EXCEL文件合并成一个

    Python的numpy处理起来会比较方便,有空实现一下,这里是Excel内部代码的方式: 合并方法如下: 1.需要把多个excel表都放在同一个文件夹里面,并在这个文件夹里面新建一个excel.如图 ...

随机推荐

  1. webservice restful一个小例子

    需求 公司有一个产品,包括前台WEB界面和多个后台服务,各个服务都需要在前面界面中进行配置和控 制,以调整服务的行为.以前,配置文件都存放在数据库中,界面上修改配置后入库,并发送消息(Socket)通 ...

  2. JavaScriptDom操作与高级应用(八)

    一:Dom操作基础与高级应用 Node接口也定义了一些所有节点类型都包含的属性和方法.

  3. [转] 为什么javascript是单线程的却能让AJAX异步调用?

    为什么JavaScript是单线程的却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的? function foo() { console.log( 'first' ); ...

  4. P1463 [SDOI2005]反素数ant

    题意: 题解: 思维难度不高,考虑到n较大,而反质数个数较少 所以只要算出每个反质数即可 考虑如何计算,可以发现,我们只需枚举计算出约数有x个的最小数,再做一下判断即可 另外约数的个数=(a1+1)( ...

  5. poj 2155(未完成)

    线段树套线段树模板题 链接:http://poj.org/problem?id=2155 题解: 代码: #include <bits/stdc++.h> using namespace ...

  6. day14--前端HTML、CSS

        HTML是一个裸体的人,CSS穿上华丽的衣服,JS动起来.     HTML 1. -一套规则,浏览器识别的规则 2. 开发者: 学习HTML规则 开发后台程序 - 写HTML文件(充当模板的 ...

  7. 066 linux下时间的修改

    1.关于时间的修改,在linux还是很重要的,在这里只是介绍一个简单的常用的命令,并且时间不会写入到系统. 2.命令 3.如果想把时间写进系统 修改完成之后,输入clock -w 时间将会被写进CMO ...

  8. 初识Style和Theme

    初识Style和Theme 学习自 http://www.jcodecraeer.com/a/basictutorial/2016/0812/6533.html 认识Style 大家还记得如何设置一个 ...

  9. 数据库中,表一sum得出一个值,赋给表二的某个字段,为null

    尝试使用了isnull(arg1,arg2)函数表示无效 最后运用了COALESCE(arg1,arg2,arg3,...) 该函数标识返回参数中第一个不为null的值. update  a set ...

  10. C# OpenFileDialog打开文件对话框(详解)

    一.打开文件对话框(OpenFileDialog) 1. OpenFileDialog控件的基本属性 InitialDirectory:对话框的初始目录 Filter: 获取或设置当前文件名筛选器字符 ...