2016-12-14 92 views
1

我用MinGW x32靜態構建ICU 57.1; 其結果是,我得到了以下文件在lib目錄:如何將我的應用靜態鏈接到ICU 57.1 MinGW

libsicudt.a 
libsicuin.a 
libsicuio.a 
libsicule.a 
libsiculx.a 
libsicutest.a 
libsicutu.a 
libsicuuc.a 
sicudt.a 
sicudt.dll 

現在我想要運行的例子之一,但無論我嘗試 我收到這樣 「未定義的引用錯誤unum_ .. 。 unum_setAttribute unum_formatInt64 u_isspace「。 之初錯誤的總數約爲1700 分析pkgconfig文件,我想通了一些相互依賴和 減少錯誤重新排序.a文件在CMD線82

之後,但我不知道下一步去哪裏。 谷歌顯示,許多人與ICU有同樣的問題,但到目前爲止還沒有解決方案適用於我,並解釋了原因。

建設的時候,我使用Qt Creator中爲方便起見,這裏是我的.pro文件:

TEMPLATE = app 
CONFIG += console c++11 
CONFIG -= app_bundle 
CONFIG -= qt 

SOURCES += main.cpp 

ICUDIR=$$(ICU_PATH) 
ICU_LIBPATH=$$ICUDIR"/dist/lib/" 
INCLUDEPATH += $$ICUDIR"/dist/include" 

LIBS += $$ICU_LIBPATH"libsicuuc.a" $$ICU_LIBPATH"libsicudt.a" \ 
$$ICU_LIBPATH"libsicuin.a" $$ICU_LIBPATH"libsicuio.a" \ 
$$ICU_LIBPATH"libsicule.a" $$ICU_LIBPATH"libsiculx.a" \ 
$$ICU_LIBPATH"libsicutu.a" $$ICU_LIBPATH"sicudt.a" 

我有以下幾個問題:1 )任何人可以寫一個靜態建立 的simpliest一個簡單的命令行ICU應用程序使用g ++?它甚至有可能嗎? 2)將.a文件傳遞給鏈接器時,它們的正確順序是什麼? 3)什麼是libsicudt.a,sicudt.a和sicudt.dll打算的文件? 4)我上面寫的文件列表是完整的還是我的內部版本已損壞? 5)有什麼我錯過了做錯了嗎?

回答

2

最後,我解決了這個問題。爲了與你分享我的經驗 我將描述我遇到的四大陷阱。 我假設你使用msys2和MinGW-w32如果你想重複這些步驟。

  1. 對一切都使用相同的工具鏈。請注意,MinGW,MinGW-w32和MinGW-w64 是3種不同的工具鏈。如果您像我一樣多次安裝MinGW ,請確保您在整個項目中僅使用其中一個。 出於兼容性原因,我選擇了MinGW-w32。

  2. 最新版本的軟件通常包含錯誤,並且它們需要更多與tambourins跳舞。 ICU v58在寫這篇文章的時候是buggy。 解決方案是恢復到舊版本(在我的情況下是57.1)。

  3. 在構建ICU庫之前,請確保正確設置所有內容。 這裏的問題是使用命名空間和重命名命名空間,默認情況下,ICU默認使用這種命名空間。

查找文件C:\ ICU \源\ COMMON \的Unicode \ uconfig.h,在開始處添加以下 後,包括警衛:

#define U_DISABLE_RENAMING 1 
#define U_USING_ICU_NAMESPACE 0 

保存文件。開放MSYS2終端和設置的mingw-W32作爲工作工具集:

export PATH="/c/msys64/mingw32/bin:$PATH" 

轉到ICU /源文件目錄:

cd /c/icu/source 

配置ICU用於靜電積累沒有重命名和U_USING_ICU_NAMESPACE = 0:

export CFLAGS="-DU_CHARSET_IS_UTF8=1 -DU_GNUC_UTF16_STRING=1 -DU_STATIC_IMPLEMENTATION" 
export CXXFLAGS="-DU_USING_ICU_NAMESPACE=0 -std=gnu++11 -DU_CHARSET_IS_UTF8=1 -DU_GNUC_UTF16_STRING=1 -DU_HAVE_CHAR16_T=1 -DUCHAR_TYPE=char16_t -Wall --std=c++11 -DU_STATIC_IMPLEMENTATION" -static-libstdc++ -fno-exceptions 
export CPPFLAGS="-DU_DISABLE_RENAMING=1 -DU_CHARSET_IS_UTF8=1 -DU_STATIC_IMPLEMENTATION" 
export LDFLAGS="-std=gnu++11" 

./runConfigureICU MinGW prefix=$PWD/../dist -enable-static -disable-shared --disable-renaming 

構建並安裝ICU庫。

mingw32-make -j4 
mingw32-make install 

清理中間文件:

mingw32-make clean 

現在你應該有位於ICU /距離/ lib中的靜態庫-j4如果你有4個內核加快了進程。

PITFALL 4:靜態鏈接時,應該按照正確的順序將庫傳遞給 鏈接器。這隻對靜態鏈接起作用。 但如何找出哪個訂單是正確的? 這裏的pkg-config工具非常方便。 它的作用如下:將庫包名稱作爲 參數,計算依賴關係並返回參數的完整字符串 ,這些參數可以直接送入編譯器 或由您查看以瞭解引擎蓋下的情況。

有5個軟件包位於C:\ icu \ dist \ lib \ pkgconfig。 讓我們配置路徑pkg配置:

export PKG_CONFIG_PATH="/c/icu/dist/lib/pkgconfig:$PKG_CONFIG_PATH" 

爲了測試它,鍵入:

pkg-config --static --cflags --libs icu-uc icu-i18n icu-io icu-le icu-lx 

輸出應該是:

-IC:/icu/dist/include -LC:/icu/dist/lib -lsicuio -lsicuin -lsiculx -lsicule -lsicuuc -lsicudt -lpthread -lm 

這是我們必須要通過串編譯器。

作爲最後的測試中,我們將使用命令行編譯一個簡單的示例應用:

創建文件夾/ C/ICU/DIST /裏面文件TEST.CPP測試:

#include <unicode/unistr.h> 
#include <unicode/ustdio.h> 
#include <unicode/brkiter.h> 
#include <stdlib.h> 

using namespace icu; 

void printUnicodeString(UFILE *out, const UnicodeString &s) { 
    UnicodeString other = s; 
    u_fprintf(out, "\"%S\"", other.getTerminatedBuffer()); 
} 

int main(void) 
{ 
    UFILE *out; 
    UErrorCode status = U_ZERO_ERROR; 
    out = u_finit(stdout, NULL, NULL); 
    if(!out) { 
     fprintf(stderr, "Could not initialize (finit()) over stdout! \n"); 
     return 1; 
    } 
    ucnv_setFromUCallBack(u_fgetConverter(out), UCNV_FROM_U_CALLBACK_ESCAPE, 
     NULL, NULL, NULL, &status); 
    if(U_FAILURE(status)) { 
     u_fprintf(out, "Warning- couldn't set the substitute callback - err %s\n", u_errorName(status)); 
    } 

    /* End Demo boilerplate */ 

    u_fprintf(out,"ICU Case Mapping Sample Program\n\n"); 
    u_fprintf(out, "C++ Case Mapping\n\n"); 

    UnicodeString string("This is a test"); 

    u_fprintf(out, "\nstring: "); 
    printUnicodeString(out, string); 
    string.toUpper(); /* string = "THIS IS A TEST" */ 
    u_fprintf(out, "\ntoUpper(): "); 
    printUnicodeString(out, string); 

    return 0; 
} 

轉到測試DIR:

cd /c/icu/dist/test 

g++ -o test test.cpp \ 
`pkg-config --cflags --libs --static icu-uc icu-i18n icu-io icu-le icu-lx` 

運行程序:

./test 

也許這不是最好的辦法, 特別是關於工作區,但它的工作原理。

更多關於pgk-config這裏: https://people.freedesktop.org/~dbn/pkg-config-guide.html