使用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.如图 ...
随机推荐
- 使用super调用父类的构造方法
package com.bjpowernode.t02inheritance.c09; /* * 使用super调用父类的构造方法 */public class TestSuper02 { publi ...
- ruby学习-字符串
字符串 1.创建字符1:new用来创建新字符,empty?检验字符是否为空 title = String.new #=> "" title.empty? #=>true ...
- 和组合数有关的dp
1. UVaLive 7143 Room Assignment 用dp[i][r]表示,前i个盒子已经放完了,手上还拿着r对同色球. 状态转移方程为:dp[i+1][r-a-b] = dp[i][r] ...
- C# 使用委托实现多线程调用窗体的四种方式
1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口 ...
- Codeforces Round #424 E. Cards Sorting
题目大意:给你一堆n张牌(数字可以相同),你只能从上面取牌,如果是当前牌堆里面最小的值则拿走, 否则放到底部,问你一共要操作多少次. 思路:讲不清楚,具体看代码.. #include<bits/ ...
- java面试题大全-基础方面 答案自己写
Java基础方面: 1.作用域public,private,protected,以及不写时的区别 2.Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类, ...
- HDU Tody HDU2112
不想用floyd了 也不一定适合 floyd只能处理小数据 dijkstra算法 wa了很久 一个是dijkstra里面的u 导致RE了无数次 下标溢出 还有就是注意细节 当起点和终点 ...
- [OpenCV-Python] OpenCV 中图像特征提取与描述 部分 V (一)
部分 V图像特征提取与描述 OpenCV-Python 中文教程(搬运)目录 29 理解图像特征 目标本节我会试着帮你理解什么是图像特征,为什么图像特征很重要,为什么角点很重要等.29.1 解释 我相 ...
- 《Gradle权威指南》--Android Gradle NDK支持
No1: 在根项目下的local.properties文件中配置 sdk.dir=/home/frame/android/android-sdk ndk.dir=/home/frame/android ...
- Springboot 2.0.x 集成基于Centos7的Redis集群安装及配置
Redis简介 Redis是一个基于C语言开发的开源(BSD许可),开源高性能的高级内存数据结构存储,用作数据库.缓存和消息代理.它支持数据结构,如 字符串.散列.列表.集合,带有范围查询的排序集,位 ...