您好,登錄后才能下訂單哦!
這篇文章主要介紹了win10+vs2008編譯比特幣的方法是什么的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇win10+vs2008編譯比特幣的方法是什么文章都會有所收獲,下面我們一起來看看吧。
一、源碼
這里用的是bitcoin-0.1.0版本
二、配置依賴庫
a) wxWidgets (3.0.3版本)
安裝方法:到http://www.wxwidgets.org/downloads/下載Windows ZIP版本,解壓,
接下來對wxwidgets文件進行編譯,這里用到了mingw32-make命令,由于我之前安裝過codeblocks-13.12mingw-setup的緣故,這一步我直接可以進行,總結就不寫,codeblocks安裝還是比較簡單的。不過這里有一些環境變量配置的問題。環境變量設置就不說了,C:\Program Files (x86)\CodeBlocks\MinGW\bin
命令行進入wxwidgets的解壓目錄,輸入以下命令:
mingw32-make -f makefile.gcc MONOLITHIC=1 SHARED=1 UNICODE=1 BUILD=debug
這可能需要很久
b) openssl (1.0.2版本)
上面大神說的1.0.2后會出問題我沒有試,還不清楚,現在的目的是編譯通過。
安裝方法就是上面提到的取巧的方法
c) Berkeley DB (4.8.30 版本)
這里我下載是Windows安裝版,所以沒有編譯源碼的過程,還是很簡單的。
d) Boost (1.63.0 版本)
三、使用vs的從“源碼導入”導入bitcoin源碼
這里我們把src/ 目錄當作根目錄。
新建立一個目錄,比如叫做bitcoin什么的隨便好啦。然后把src/目錄下的所有文件都拷貝到這個新的目錄下。我們現在把這個新的目錄當做 / 。之后的描述都針對 / 作為根目錄進行。
打開vs
點擊新建
從現有代碼創建項目
彈出對話框,選擇默認的Visual C++ ,點擊下一步
項目位置填寫上剛才的 / 目錄的位置,項目名稱取名 bitcoin-v0.1或者其他你喜歡的項目名字,點擊下一步
使用visual studio ->項目類型選擇“Windows 應用程序項目” (就是說直接使用默認),其他的不動,點擊下一步
點擊完成
此時就已經新創建了項目,并導入的源碼。
四、配置
這步是很關鍵的第一步
現在我們先假設把剛才配置好的4個依賴庫都設置成環境變量(如果不設置環境變量也行,那么等會在配置項目的依賴的時候就填寫路徑就好了。)
回到桌面->對“此電腦”右鍵->屬性->高級系統設置->環境變量->在系統變量的部分開始創建環境變量
點擊新建:
舉例:wsWidgets =>那么就在變量名寫上WXWidgetsPath,然后變量值填寫剛才安裝(解壓)widgets的根目錄
其他3個依賴庫同理,則總共配置了4個環境變量:
WXWidgetsPath
OpenSSLPath
BDBPath
BoostPath
當然上面這4個環境變量的名字是我亂取的,并沒有什么約定,你可以根據自己想象取想取的名字。這里取這4個變量等會我們就會在項目的配置中引用這4個變量,自己取的名字等會就換成自己取的就好了。
此時先關閉剛才創建的項目,然后再重新啟動(這個是為了讓vs加載剛才取的環境變量,如果沒配置環境變量用不著重啟vs)
在解決方案中右鍵剛才創建的項目,選擇屬性。
a) 設置unicode字符集
注意,這步的配置不是必須,如果你的wxWidgets是老版本(似乎是小于2.8?)或者你在編譯wxWidgets庫的時候選擇關閉unicode開關,編譯除了非unicode的wxWidgets的庫時,可以直接跳過這步,不設置unicode字符集。否則在等會啟動編譯的時候會出現wxWidgets的setup.h找不到路徑。
如果你是vs編譯的,那么一定要設置unicode字符集。
在配置屬性-常規中找到項目默認值 - 字符集
點擊下拉框,選擇使用 Unicode 字符集
b) 設置VC++依賴項
在配置屬性-VC++目錄下找到包含目錄和庫目錄,點擊包含目錄,填寫
$(WXWidgetsPath)\include
$(WXWidgetsPath)\include\msvc
(注意這里的WXWidgetsPath就是剛才配置的環境變量,如果沒有配置,就直接填寫wxWidgets的路徑加上include路徑,以下同理)
這樣就引入了wxWidgets庫的頭文件路徑以及 lib 路徑。
注:因為wxWidgets庫是和windows應用程序綁定的,不是普通的c++依賴庫,所以必須在VC++的部分設置,否則,wxWidgets會不能通過編譯。
c) 設置C++依賴
在配置屬性 - c/c++ - 常規中找到“附加包含目錄”,點擊編輯,填寫:
$(BoostPath)
$(OpenSSLPath)\include
$(BDBPath)\include
這樣就引入了 boost,openssl, bdb的頭文件路徑
在配置屬性 - 鏈接器 -常規中找到“附加庫目錄”,點擊編輯,填寫:
$(OpenSSLPath)\lib
$(BDBPath)\lib // 注意這條可能根據你的環境改變
(加粗|醒目) oracle神坑的地方在這里就體現出來了。$(BDBPath)\lib指代的bdb的 libs 的路徑,但是!因為我們編譯的是 debug 項目,所以等會只能引入 debug 的dll(lib) (如果正常應該是可以引入release的lib的,但是對于bdb來說,debug項目使用release的dll在運行free()的時候會崩潰/(ㄒoㄒ)/~~)。
但是引入debug后,源安裝包中的 debug的dll似乎是有問題的(加粗),會直接引起程序崩潰!!(不清楚我是不是個例。如果出現了這個問題,請重新在自己的電腦上編譯debug版本的bdb,把$(BDBPath)\lib換成新的路徑,參考下一篇文章)
在配置屬性 - 鏈接器 -輸入中找到“附加依賴項”,點擊編輯,填寫:
libeay32.lib
libdb48d.lib // 注意這個是帶 'd' 的,也就是 debug 的dll庫
然后打開資源管理器(就是點我的電腦。。),找到這個項目的目錄,在本項目根目錄 / 下創建 libs/ 目錄,拷貝
$(OpenSSLPath) 目錄下的 libeay32.dll
和
$(BDBPath)\bin\debug 目錄下的libdb48d.dll
進入 libs 目錄。
注意,剛才描述的問題的dll就是這個 libdb48d.dll,如果出問題了,很可能需要替換成自己編譯的dll
然后回到 VS 的項目配置中
在配置屬性 - 生成事件 - 后期生成事件中找到“命令行”
填寫上:
xcopy /y /d "$(ProjectDir)libs\*.dll" "$(OutDir)"
這個command的 libs 就是剛才在項目的根目錄下創建的 libs/ 目錄。所以這句話的意思就是把 libs/ 目錄下的dll都拷貝到輸出目錄中(這里指代的就是 Debug 目錄)
五、修改源碼
錯誤
1. headers.h
vc6++ 與 vc9以上平臺沖突
因為源碼應該是在vc6++的平臺下編譯完成的,所以首先要先移除對于winnt的預定義,否則會產生兼容性問題。
找到headers.h文件,在第10行發現:
#ifdef _WIN32_WINNT
#undef _WIN32_WINNT
#endif
#define _WIN32_WINNT 0x0400 // 刪除這4行
將這4行都注釋掉,或者刪除。
windows.h與 winsokc2.h 順序
找到headers.h文件第23行發現:
#include <windows.h>
#include <winsock2.h>
#include <mswsock.h> // 把windows.h移動到最下面
移動windows.h得到
#include <winsock2.h>
#include <mswsock.h>
#include <windows.h>
或者引入一個宏也可以解決windows.h頭文件引入的問題:
#define _WINSOCKAPI_ // stops windows.h including winsock.h
#include <windows.h>
// ...
#include "MyClass.h" // Which includes <winsock2.h>
之后找到 net.cpp 文件,第5行交換頭文件引入
#include "headers.h"
#include <winsock2.h> // 和上面一樣互換這兩行
// =>
#include <winsock2.h>
#include "headers.h"
2. c++11 與現存代碼沖突
net.h/net.c boost::array 與c++11 的std::array 沖突
找到net.h文件,在第419行發現
extern array<bool, 10>vfThreadRunning; // 添加命名空間
// 修改為 =>
extern boost::array<bool, 10>vfThreadRunning; // 添加命名空間
找到net.c文件,第26行進行同樣更改
array<bool, 10>vfThreadRunning;
// 修改為 =>
boost::array<bool, 10>vfThreadRunning;
winsock.h的 bind 函數與std::bind 沖突
找到net.c文件,第937行
if (bind(hListenSocket, (structsockaddr*)&sockaddr, sizeof(sockaddr))
== SOCKET_ERROR) // bind函數沖突
// 轉變為=>
if (::bind(hListenSocket, (structsockaddr*)&sockaddr,
sizeof(sockaddr)) == SOCKET_ERROR) // 添加上::global 命名空間
3. serialize.h insert函數const char*想要強制轉換為const_iterator
找到serialize.h文件,在第 808 行發現一個根據宏的定義
#if !defined(_MSC_VER) || _MSC_VER >= 1300
void insert(iterator it, const char* first, const char* last)
{
insert(it, (const_iterator)first, (const_iterator)last);
}
#endif
修改為
#if !defined(_MSC_VER) || _MSC_VER >= 1300
void insert(iterator it, const char* first, const char* last)
{
vector_type v(first, last);
insert(it, v.begin(), v.end());
}
#endif
4. 似乎是關于MSVC8 allocator的兼容問題(不確定)
文件serialize.h第699行
typedef vector<char,constsecure_allocator<char>>vector_type;
// 修改為=>也就是把作者原來寫的這個secure_allocator移除,使用vector自帶的。
typedef vector<char>vector_type;
同時因為vector_type的typedef已經等同于vector<char>,所以對于CDataStream類的構造函數也要更改
文件serialize.h第741行, 刪除或著注釋掉這個構造函數
//CDataStream(const vector<char>&vchIn, intnTypeIn=0, int
VersionIn=VERSION) :vch(vchIn.begin(), vchIn.end())
//{
// Init(nTypeIn, nVersionIn);
//}
文件key.h第40行
typedef vector<unsigned char, constsecure_allocator<unsigned char>>
CPrivKey;
// =>修改方式同上
typedef vector<unsigned char>CPrivKey;
5. unicode字符的替換
ps: 若使用低版本的wxwidgets,總之就是沒開啟unicode宏的話不需要替換
util.cpp文件的第74行
long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, "Global", NULL,
NULL, pdata, &nSize);
// 把“Global”字符串該為 win32 支持的unicode =>
long ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, L"Global", NULL,
NULL, pdata, &nSize);
// 或者換成另一個版本的win API也行
long ret = RegQueryValueExA(HKEY_PERFORMANCE_DATA, "Global", NULL,
ULL, pdata, &nSize);
第173行
GetModuleFileName(NULL, pszModule, sizeof(pszModule));
//在unicode宏定義下的GetModuleFileName是寬字符版本,直接替換成Acsii版本=>
GetModuleFileNameA(NULL, pszModule, sizeof(pszModule));
第272行
returnGetFileAttributes(psz) != -1;
// 與上面同理 =>
returnGetFileAttributesA(psz) != -1;
util.h文件的第274行
OutputDebugString(p1);
// 與上同理 =>
OutputDebugStringA(p1);
6. ui.cpp / ui.h錯誤
ui.cpp 第254行,關于wsString的迭代器填充構造函數無法自動轉化的問題 (或許當wxWidgets版本低的時候不會出現這個問題)
returnCDataStream(strData.begin(), strData.begin() + event.GetInt(), SER_NETWORK);
// 替換成為 =>
const char* s = strData.mb_str();
returnCDataStream(s, s + event.GetInt(), SER_NETWORK);
類似的第2650,wsString到std::string的轉換
wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]->GetLabel(),
strValue));
// 把wsString調用ToStdString() =>
wtx.vOrderForm.push_back(make_pair(m_staticTextLabel[i]-
>GetLabel().ToStdString(), strValue));
ui.cpp 第1245行,字符缺少引號
ps: 強調!這里缺少引號,是因為本來源碼中這里是個十分奇怪的字符,在導入vs后打開的時候就被轉義了。所以這里的?實際上是代表原來的一個字符。但是這個函數并沒什么鳥用,所以這里隨便改正就好,不用還原原來的意思。
if (str.Find('?) != wxNOT_FOUND)
str.Remove(str.Find('?), 1);
// 添加上缺失的引號
if (str.Find('?') != wxNOT_FOUND)
str.Remove(str.Find('?'), 1);
2890行,寬字符
_CrtSetReportFile(_CRT_WARN, CreateFile("NUL", GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, 0));
// =>
_CrtSetReportFile(_CRT_WARN, CreateFile(L"NUL", GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, 0));
2913行,同上
HWND hwndPrev = FindWindow("wxWindowClassNR", "Bitcoin");
// =>
HWND hwndPrev = FindWindow(L"wxWindowClassNR", L"Bitcoin");
3148行,對于3.0以上的wxWidgets版本來說AddPendingEvent()函數已廢棄,需要依靠eventhandler才能調用。
//pframeMain->AddPendingEvent(event);
pframeMain->GetEventHandler()->AddPendingEvent(event);
7. 去除因跨平臺帶來的兼容問題
文件util.h第161行
inline string i64tostr(int64 n)
{
returnstrprintf("%"PRId64, n);
// 其中的PRId64 是為了跨平臺帶來的,修改為下面的代碼
// =>因為這里不關心跨平臺問題,只把環境限制在win64上,所以不必擔心int64的問題
returnstrprintf("%l", n);
}
8. berkeleydb版本為6.2+后的修改兼容 (使用4.7或4.8版本則無需考慮)
文件db.cpp 第18行
DbEnvdbenv(0);
// =>
DbEnvdbenv((u_int32_t)0);
警告
源碼中出現的警告多半是因為符號隱式轉換的問題,這個根據自己需要修改就行。
六、解決wx依賴庫的問題
http://www.cnblogs.com/waynecheng/archive/2012/04/18/2455765.html
按上述方法修改源碼后運行會出現找不到“wx/msw/wx.rc”,這需要引入資源文件,設置資源目錄,項目->屬性->資源->常規->附加包含目錄:E:\wxWidgets-3.0.3\include
接下來會出現一大堆error LNK2019: 無法解析的外部符號,這種錯誤,這是需要重新編譯wx,步驟如下:
進入E:\wxWidgets-3.0.3\build\msw目錄,Visual Studio 2008打開wx_vc9.sln,生成解決方案,之后會看到在\lib下生成vc_lib文件夾,其中包括生成的相應的.lib等文件和mswud文件夾。到此,wxWidgets編譯完畢。
項目設定
右鍵單擊項目->屬性->C/C++->常規
【附加包含目錄】 = "$(wxWin)\lib\vc_lib\mswud"
項目屬性->連接器->常規
【附加庫目錄】= "$(wxWin)\lib\vc_lib\"
項目屬性->連接器->輸入
【附加依賴項】=
wxmsw29ud_core.lib
wxbase29ud.lib
wxtiffd.lib
wxjpegd.lib
wxpngd.lib
wxzlibd.lib
wxregexud.lib
wxexpatd.lib
winmm.lib
comctl32.lib
rpcrt4.lib
wsock32.lib
odbc32.lib
再次編譯運行就可以了
七、運行
以上的部分只是解決在編譯期出現的問題,大頭是需要讓bitcoin能夠運行起來(慘····)
接下來將詳細描述如何修改代碼讓bitcoin運行起來。
好累。。
這里我只說我遇到的問題,
原因就不說了,我也沒看懂,直接來解決辦法,
因為安裝包中的release和debug都無法運行,所以只能自己編譯出Berkeley DB的lib和dll
假設現在的berkeleydb的根目錄是 \<bdbroot>
那么在 \<bdbroot>\db-4.8.30\build_windows目錄下可以找到 Berkeley_DB.sln
打開它向上兼容后,進行項目構建,然后將一個example項目設為主項目進行運行。如果能運行成功就是構建成功并且能夠正常運行。
此時在 \<bdbroot>\db-4.8.30\build_windows\Win32\Debug\ 目錄下可以發現 libdb48d.lib 和 libdb48d.dll 這兩個文件。而這兩個文件就是在自己平臺上編譯出來的動態鏈接庫。
之后把bitcoin源碼的關于Berkeley DB 的依賴庫修改為新的路徑,然后就可以正常運行了。。。
這里修改的路徑就是 $(BDBPath)\db-4.8.30\build_windows\Win32\Debug\
然后把 libdb48d.dll 拷貝到 bitcoin項目的 libs 目錄下。
關于“win10+vs2008編譯比特幣的方法是什么”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“win10+vs2008編譯比特幣的方法是什么”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。