簡述
C/C++開源庫通常是一堆的頭文件和源文件,作到聲明和實現分離,減少單個模塊大小,這在設計上是很好的,可是用起來稍顯麻煩。在網上看到有好心人推薦了一個開源工具Amalgamate,專門用來對C/C++的頭文件和源文件進行合併用的,因而嘗試了一下。 編譯過sqlite源碼的應該知道,sqlite3源碼包有一個是指包含sqlite3.h
、sqlite3_ext.h
、sqlite.c
等爲數很少幾個代碼文件的(也有分開的),嵌入到項目中很是方便。這就是用Amalgamate進行合併的。html
下載並編譯Amalgamate
下載很簡單,這裏就不細述了android
git clone https://github.com/vinniefalco/Amalgamate.git
編譯也很簡單,直接使用VS打開Amalgamate\Builds\VisualStudio2010\Amalgamate.vcxproj
,而後編譯生成便可。 最後的示例下載中有我編譯的程序。git
# gcc 編譯 g++ Amalgamate.cpp juce_core_amalgam.cpp -o Amalgamate -lpthread -ldl # clang編譯 clang++ Amalgamate.cpp juce_core_amalgam.cpp -o Amalgamate -lpthread -ldl
具體的使用能夠參考程序的幫助信息。github
將libuv合併爲單一頭文件和源文件版本(Windows下)
用於合併的模板文件編寫能夠參考https://github.com/vinniefalco/Amalgams.git中的幾個。web
以libuv
爲例進行簡單的說明。 先下載libuv
的源碼,目錄結構以下: sql
首先先合併頭文件
先編寫一個頭文件uv_all.h
,裏面把libuv-v1.9.1\include
下的文件都include
進來。 源碼以下:windows
#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
也就夠了。 運行下面命令生成合並後的頭文件api
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
是輸出文件名,前面的是輸入的配置模板文件。bash
合併源碼文件
合併源碼文件的作法和合並頭文件的作法是一致的,先寫一個配置文件uv_win_all.h
(把src和src/win目錄下全部文件都包含進來),內容以下:async
#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}` |
-p `{file | macro}` |
-d {name}={file} | 若是宏{name}出如今include包含行中,使用{file}替代 |
-i {dir} | 在處理include包含時,能夠在指定的{dir}目錄中搜索文件 |
-v | 輸出詳細信息 |