簡體   English   中英

如何針對ICU 57.1 MinGW靜態鏈接我的應用

[英]How to link my app statically against ICU 57.1 MinGW

我已經用MinGW x32靜態構建了ICU 57.1; 結果,我在lib目錄中獲得了以下文件:

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文件時,我找出了一些相互依賴的關系,然后在cmd行中對.a文件重新排序后,錯誤減少到82個。

但是我不知道下一步要去哪里。 Google顯示,許多人在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)任何人都可以編寫一個簡單的單行命令來使用g ++靜態構建最簡單的ICU應用程序嗎? 可能嗎 2).a文件傳遞給鏈接器時,正確的順序是什么? 3)設置文件libsicudt.a,sicudt.a和sicudt.dll是什么? 4)我上面編寫的文件列表是否完整或我的構建已損壞? 5)我錯過做錯了什么嗎?

最后,我解決了這個問題。 為了與您分享我的經驗,我將描述我遇到的四個主要陷阱。 如果要重復這些步驟,我假設您使用msys2和MinGW-w32。

  1. 對所有內容使用相同的工具鏈。 請注意,MinGW,MinGW-w32和MinGW-w64是3個不同的工具鏈。 如果像我一樣有多個MinGW的安裝,請確保整個項目僅使用其中一個。 我出於兼容性考慮選擇了MinGW-w32。

  2. 最新版本的軟件通常包含錯誤,因此您需要與鈴鼓共舞。 在撰寫本文時,ICU v58還存在問題。 解決方案是恢復到舊版本(在我的情況下為57.1)。

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

查找文件C:\\ icu \\ source \\ 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

在不重命名且U_USING_ICU_NAMESPACE = 0的情況下為靜態構建配置ICU:

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庫。 如果您有4個核心,-j4可以加快處理過程:

mingw32-make -j4
mingw32-make install

清理中間文件:

mingw32-make clean

現在,您應該在icu / dist / lib中有靜態庫。

PITFALL 4:靜態鏈接時,應按正確的順序將庫傳遞給鏈接器。 這僅對靜態鏈接很重要。 但是,如何找出正確的順序呢? 在這里,pkg-config工具非常方便。 它的作用如下:以庫包名稱作為參數,計算依賴關系並返回完整的參數字符串,這些字符串可以直接饋送到編譯器,也可以由您查看以了解底層情況。

C:\\ icu \\ dist \\ lib \\ pkgconfig中有5個軟件包。 讓我們為pkg-config配置路徑:

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

那就是我們必須傳遞給編譯器的字符串。

作為最終測試,我們將使用命令行編譯一個簡單的示例應用程序:

使用文件test.cpp創建文件夾/ c / icu / dist / test:

#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;
}

轉到測試目錄:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM