Claude-skill-registry dotnet-cpp-localizer
Comprehensive internationalization (i18n) and localization (l10n) for .NET and C++ applications. Generate resource files, manage translations, and implement best practices for multi-language support.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dotnet-cpp-localizer" ~/.claude/skills/majiayu000-claude-skill-registry-dotnet-cpp-localizer && rm -rf "$T"
skills/data/dotnet-cpp-localizer/SKILL.md.NET & C++ Localizer Skill
.NETとC++アプリケーションの国際化(i18n)と地域化(l10n)を完全サポートするスキルです。
概要
このスキルは、.NET(.resx)とC++(gettext/ICU)の両方に対応した、エンタープライズレベルの国際化ソリューションを提供します。リソースファイル生成、翻訳管理、ベストプラクティス適用まで、国際化のすべてをカバーします。
主な機能
- 🎯 .NET サポート: .resx、IStringLocalizer、ASP.NET Core localization
- 🎯 C++ サポート: gettext (.po/.pot)、ICU、Boost.Locale
- 📦 リソース生成: 自動リソースファイル作成
- 🔍 文字列抽出: ハードコードされた文字列の自動検出
- 🌐 翻訳管理: 複数言語の翻訳ファイル管理
- ✅ 品質チェック: 翻訳漏れ、重複、フォーマットエラー検出
- 📊 進捗トラッキング: 言語別の翻訳完了率
- 🔄 同期ツール: コード変更への自動追従
- 🎨 複数形対応: .NET plural rules、gettext ngettext
- 📱 文化対応: 日付・通貨・数値のロケール別フォーマット
サポート技術
.NET ファミリー
- .NET Core / .NET 6/7/8/9
- ASP.NET Core (MVC, Razor Pages, Blazor)
- WPF (Windows Presentation Foundation)
- WinForms (Windows Forms)
- Xamarin (iOS/Android)
- .NET MAUI (Multi-platform App UI)
- Unity (C# ゲームエンジン)
C++ フレームワーク
- gettext - GNU翻訳システム(最も人気)
- ICU - International Components for Unicode
- Boost.Locale - C++標準ライブラリ風API
- Qt Linguist - Qt フレームワーク (.ts ファイル)
- wxWidgets - クロスプラットフォームGUI
使用方法
.NET アプリケーションの国際化
基本的なリソースファイル生成
.NET Coreプロジェクトに国際化を追加: プロジェクトタイプ: ASP.NET Core MVC 言語: 英語(デフォルト)、日本語、中国語、スペイン語 リソース場所: Resources/ 文化: ja-JP, zh-CN, es-ES タスク: 1. .resx ファイル生成 2. IStringLocalizer 設定 3. Startup.cs 設定 4. ハードコード文字列の抽出と置き換え
WPF アプリケーション
WPF デスクトップアプリに多言語対応: 言語: 英語、日本語、ドイツ語 リソース: Properties/Resources.resx UI更新: すべてのラベル、ボタン、メッセージボックス 言語切り替え: ランタイムで切り替え可能
C++ アプリケーションの国際化
gettext 統合
C++ コンソールアプリケーションにgettextを統合: ライブラリ: GNU gettext 言語: 英語、日本語、フランス語 ドメイン: myapp 出力: po/ja/myapp.po, po/fr/myapp.po タスク: 1. gettext セットアップコード生成 2. 文字列抽出(xgettext) 3. .pot/.po ファイル生成 4. コード修正(_() マクロ)
ICU 統合
C++ プロジェクトにICUを統合: 機能: - Unicode文字列処理 - 日付・時刻フォーマット(ロケール別) - 数値・通貨フォーマット - 複数形ルール - ソート・検索(ロケール対応)
.NET 実装パターン
1. ASP.NET Core MVC の国際化
生成されるファイル構成:
MyWebApp/ ├── Resources/ │ ├── Controllers/ │ │ ├── HomeController.en.resx │ │ ├── HomeController.ja.resx │ │ └── HomeController.zh.resx │ ├── Views/ │ │ ├── Home/ │ │ │ ├── Index.en.resx │ │ │ ├── Index.ja.resx │ │ │ └── Index.zh.resx │ │ └── Shared/ │ │ ├── _Layout.en.resx │ │ └── _Layout.ja.resx │ └── SharedResources.resx ├── Program.cs (または Startup.cs) └── appsettings.json
Program.cs (.NET 6+):
using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Options; using System.Globalization; var builder = WebApplication.CreateBuilder(args); // Localization サービス追加 builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); builder.Services.AddControllersWithViews() .AddViewLocalization() .AddDataAnnotationsLocalization(); // サポートする文化を設定 var supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("ja"), new CultureInfo("zh"), new CultureInfo("es") }; builder.Services.Configure<RequestLocalizationOptions>(options => { options.DefaultRequestCulture = new RequestCulture("en"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; // クッキーベースの文化選択 options.RequestCultureProviders.Insert(0, new CookieRequestCultureProvider()); }); var app = builder.Build(); // Localization ミドルウェア追加(重要: UseRouting より前) app.UseRequestLocalization( app.Services.GetRequiredService<IOptions<RequestLocalizationOptions>>().Value ); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
Resources/Controllers/HomeController.ja.resx:
<?xml version="1.0" encoding="utf-8"?> <root> <data name="Welcome" xml:space="preserve"> <value>ようこそ</value> </data> <data name="HelloMessage" xml:space="preserve"> <value>こんにちは、{0}さん!</value> </data> <data name="ItemCount" xml:space="preserve"> <value>{0} 件のアイテム</value> </data> </root>
HomeController.cs:
using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; public class HomeController : Controller { private readonly IStringLocalizer<HomeController> _localizer; public HomeController(IStringLocalizer<HomeController> localizer) { _localizer = localizer; } public IActionResult Index() { // リソースから文字列取得 ViewData["Message"] = _localizer["Welcome"]; // パラメータ付き var userName = "田中"; ViewData["Greeting"] = _localizer["HelloMessage", userName]; // 複数形対応 var count = 5; ViewData["Items"] = _localizer["ItemCount", count]; return View(); } [HttpPost] public IActionResult SetLanguage(string culture, string returnUrl) { Response.Cookies.Append( CookieRequestCultureProvider.DefaultCookieName, CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)), new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1) } ); return LocalRedirect(returnUrl); } }
Views/Home/Index.cshtml:
@using Microsoft.AspNetCore.Mvc.Localization @inject IViewLocalizer Localizer <h1>@Localizer["Welcome"]</h1> <p>@ViewData["Greeting"]</p> <p>@ViewData["Items"]</p> <!-- 言語切り替え --> <form asp-action="SetLanguage" asp-controller="Home" method="post"> <input type="hidden" name="returnUrl" value="@Context.Request.Path" /> <select name="culture" onchange="this.form.submit()"> <option value="en">English</option> <option value="ja">日本語</option> <option value="zh">中文</option> <option value="es">Español</option> </select> </form>
2. WPF デスクトップアプリケーション
App.xaml.cs:
using System.Globalization; using System.Threading; using System.Windows; public partial class App : Application { protected override void OnStartup(StartupEventArgs e) { base.OnStartup(e); // ユーザー設定から言語読み込み var cultureName = Properties.Settings.Default.Language ?? "en"; SetLanguage(cultureName); } public static void SetLanguage(string cultureName) { var culture = new CultureInfo(cultureName); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; // WPFのリソースディクショナリを更新 CultureInfo.DefaultThreadCurrentCulture = culture; CultureInfo.DefaultThreadCurrentUICulture = culture; } }
MainWindow.xaml.cs:
using System.Windows; public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); UpdateUI(); } private void UpdateUI() { // リソースから文字列取得 Title = Properties.Resources.AppTitle; WelcomeLabel.Content = Properties.Resources.Welcome; LoginButton.Content = Properties.Resources.Login; } private void LanguageComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (LanguageComboBox.SelectedItem is ComboBoxItem item) { var culture = item.Tag.ToString(); App.SetLanguage(culture); // 設定を保存 Properties.Settings.Default.Language = culture; Properties.Settings.Default.Save(); // UIを更新(または再起動) UpdateUI(); } } }
Properties/Resources.resx (英語):
<data name="AppTitle" xml:space="preserve"> <value>My Application</value> </data> <data name="Welcome" xml:space="preserve"> <value>Welcome!</value> </data> <data name="Login" xml:space="preserve"> <value>Login</value> </data>
Properties/Resources.ja.resx (日本語):
<data name="AppTitle" xml:space="preserve"> <value>私のアプリケーション</value> </data> <data name="Welcome" xml:space="preserve"> <value>ようこそ!</value> </data> <data name="Login" xml:space="preserve"> <value>ログイン</value> </data>
3. .NET MAUI (マルチプラットフォーム)
MauiProgram.cs:
using Microsoft.Extensions.Localization; using System.Globalization; public static class MauiProgram { public static MauiApp CreateMauiApp() { var builder = MauiApp.CreateBuilder(); builder .UseMauiApp<App>() .ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); }); // Localization追加 builder.Services.AddLocalization(); return builder.Build(); } }
Resources/Strings/AppResources.ja.resx:
<data name="Welcome" xml:space="preserve"> <value>ようこそ</value> </data>
MainPage.xaml.cs:
using Microsoft.Extensions.Localization; public partial class MainPage : ContentPage { private readonly IStringLocalizer<AppResources> _localizer; public MainPage(IStringLocalizer<AppResources> localizer) { InitializeComponent(); _localizer = localizer; WelcomeLabel.Text = _localizer["Welcome"]; } }
C++ 実装パターン
1. gettext による国際化
ファイル構成:
myapp/ ├── src/ │ ├── main.cpp │ └── i18n.h ├── po/ │ ├── myapp.pot # テンプレート │ ├── ja/ │ │ └── myapp.po # 日本語翻訳 │ ├── fr/ │ │ └── myapp.po # フランス語翻訳 │ └── de/ │ └── myapp.po # ドイツ語翻訳 ├── locale/ # コンパイル済み .mo ファイル │ ├── ja/ │ │ └── LC_MESSAGES/ │ │ └── myapp.mo │ └── fr/ │ └── LC_MESSAGES/ │ └── myapp.mo └── CMakeLists.txt
i18n.h (ヘッダー):
#ifndef I18N_H #define I18N_H #include <libintl.h> #include <locale.h> // 翻訳マクロ #define _(STRING) gettext(STRING) #define N_(STRING) STRING // 複数形対応 #define _n(SINGULAR, PLURAL, N) ngettext(SINGULAR, PLURAL, N) // 初期化関数 inline void initI18n(const char* domain, const char* locale_dir) { // ロケール設定 setlocale(LC_ALL, ""); // gettext設定 bindtextdomain(domain, locale_dir); bind_textdomain_codeset(domain, "UTF-8"); textdomain(domain); } #endif // I18N_H
main.cpp:
#include <iostream> #include <string> #include "i18n.h" int main(int argc, char* argv[]) { // 国際化初期化 initI18n("myapp", "./locale"); // 翻訳された文字列を使用 std::cout << _("Welcome to My Application!") << std::endl; std::cout << _("Please enter your name: "); std::string name; std::getline(std::cin, name); // パラメータ付き(printfスタイル) printf(_("Hello, %s!\n"), name.c_str()); // 複数形対応 int count = 5; printf(_n("You have %d new message", "You have %d new messages", count), count); std::cout << std::endl; // メニュー表示 std::cout << "\n" << _("Menu:") << std::endl; std::cout << "1. " << _("View Profile") << std::endl; std::cout << "2. " << _("Settings") << std::endl; std::cout << "3. " << _("Exit") << std::endl; return 0; }
翻訳ファイル生成手順:
# 1. 翻訳可能な文字列を抽出 (.pot ファイル生成) xgettext --keyword=_ --keyword=_n:1,2 --language=C++ \ --add-comments --sort-output \ --output=po/myapp.pot \ src/*.cpp # 2. 各言語の .po ファイル作成(初回のみ) msginit --input=po/myapp.pot --locale=ja_JP --output=po/ja/myapp.po msginit --input=po/myapp.pot --locale=fr_FR --output=po/fr/myapp.po # 3. .po ファイルを編集(翻訳者が実施) # 例: po/ja/myapp.po # 4. 既存の .po ファイルを更新(コード変更時) msgmerge --update po/ja/myapp.po po/myapp.pot # 5. .mo ファイルにコンパイル msgfmt --output-file=locale/ja/LC_MESSAGES/myapp.mo po/ja/myapp.po msgfmt --output-file=locale/fr/LC_MESSAGES/myapp.mo po/fr/myapp.po
po/ja/myapp.po (日本語翻訳例):
# Japanese translation for myapp msgid "" msgstr "" "Project-Id-Version: myapp 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Language: ja\n" msgid "Welcome to My Application!" msgstr "私のアプリケーションへようこそ!" msgid "Please enter your name: " msgstr "お名前を入力してください: " msgid "Hello, %s!\n" msgstr "こんにちは、%sさん!\n" # 複数形 msgid "You have %d new message" msgid_plural "You have %d new messages" msgstr[0] "%d 件の新しいメッセージがあります" msgid "Menu:" msgstr "メニュー:" msgid "View Profile" msgstr "プロフィールを表示" msgid "Settings" msgstr "設定" msgid "Exit" msgstr "終了"
CMakeLists.txt (ビルド統合):
cmake_minimum_required(VERSION 3.10) project(myapp) set(CMAKE_CXX_STANDARD 17) # gettext ライブラリを探す find_package(Gettext REQUIRED) find_package(Intl REQUIRED) # 実行ファイル add_executable(myapp src/main.cpp) # インクルードディレクトリ target_include_directories(myapp PRIVATE ${Intl_INCLUDE_DIRS}) # ライブラリリンク target_link_libraries(myapp PRIVATE ${Intl_LIBRARIES}) # .po ファイルから .mo ファイルを生成 set(LANGUAGES ja fr de) set(PO_DIR ${CMAKE_SOURCE_DIR}/po) set(LOCALE_DIR ${CMAKE_BINARY_DIR}/locale) foreach(LANG ${LANGUAGES}) set(PO_FILE ${PO_DIR}/${LANG}/myapp.po) set(MO_DIR ${LOCALE_DIR}/${LANG}/LC_MESSAGES) set(MO_FILE ${MO_DIR}/myapp.mo) # ディレクトリ作成 file(MAKE_DIRECTORY ${MO_DIR}) # カスタムコマンド: .po → .mo add_custom_command( OUTPUT ${MO_FILE} COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${MO_FILE} ${PO_FILE} DEPENDS ${PO_FILE} COMMENT "Compiling ${LANG} translation" ) list(APPEND MO_FILES ${MO_FILE}) endforeach() # すべての .mo ファイルをビルド add_custom_target(translations ALL DEPENDS ${MO_FILES}) add_dependencies(myapp translations) # インストール install(DIRECTORY ${LOCALE_DIR}/ DESTINATION share/locale)
2. ICU による高度な国際化
ICU 使用例:
#include <iostream> #include <unicode/ucnv.h> #include <unicode/unistr.h> #include <unicode/datefmt.h> #include <unicode/numfmt.h> #include <unicode/plurrule.h> #include <unicode/msgfmt.h> using namespace icu; int main() { UErrorCode status = U_ZERO_ERROR; // 1. Unicode文字列処理 UnicodeString text("Hello, 世界! 你好!"); std::cout << "Length: " << text.length() << " characters" << std::endl; // 2. 日付フォーマット(ロケール別) Locale localeJa("ja_JP"); Locale localeEn("en_US"); DateFormat* dateFormatJa = DateFormat::createDateInstance( DateFormat::kFull, localeJa); DateFormat* dateFormatEn = DateFormat::createDateInstance( DateFormat::kFull, localeEn); UDate now = Calendar::getNow(); UnicodeString dateJa, dateEn; dateFormatJa->format(now, dateJa); dateFormatEn->format(now, dateEn); std::string dateJaUtf8, dateEnUtf8; dateJa.toUTF8String(dateJaUtf8); dateEn.toUTF8String(dateEnUtf8); std::cout << "Date (ja): " << dateJaUtf8 << std::endl; std::cout << "Date (en): " << dateEnUtf8 << std::endl; // 3. 数値フォーマット(通貨) NumberFormat* currencyJa = NumberFormat::createCurrencyInstance( localeJa, status); NumberFormat* currencyEn = NumberFormat::createCurrencyInstance( localeEn, status); double amount = 1234567.89; UnicodeString currencyJaStr, currencyEnStr; currencyJa->format(amount, currencyJaStr); currencyEn->format(amount, currencyEnStr); std::string currencyJaUtf8, currencyEnUtf8; currencyJaStr.toUTF8String(currencyJaUtf8); currencyEnStr.toUTF8String(currencyEnUtf8); std::cout << "Currency (ja): " << currencyJaUtf8 << std::endl; std::cout << "Currency (en): " << currencyEnUtf8 << std::endl; // 4. 複数形ルール PluralRules* pluralRulesEn = PluralRules::forLocale(localeEn, status); for (int i = 0; i <= 5; i++) { UnicodeString keyword = pluralRulesEn->select(i); std::string keywordUtf8; keyword.toUTF8String(keywordUtf8); std::cout << i << " -> " << keywordUtf8 << std::endl; } // 5. MessageFormat (パラメータ付きメッセージ) UnicodeString pattern("{0} has {1, plural, " "one {# apple} " "other {# apples}}."); MessageFormat msgFormat(pattern, localeEn, status); UnicodeString name("Alice"); int appleCount = 3; Formattable args[] = { name, appleCount }; UnicodeString result; msgFormat.format(args, 2, result, status); std::string resultUtf8; result.toUTF8String(resultUtf8); std::cout << "Message: " << resultUtf8 << std::endl; // クリーンアップ delete dateFormatJa; delete dateFormatEn; delete currencyJa; delete currencyEn; delete pluralRulesEn; return 0; }
CMakeLists.txt (ICU):
cmake_minimum_required(VERSION 3.10) project(icu_example) set(CMAKE_CXX_STANDARD 17) # ICU を探す find_package(ICU REQUIRED COMPONENTS uc i18n) add_executable(icu_example main.cpp) target_include_directories(icu_example PRIVATE ${ICU_INCLUDE_DIRS}) target_link_libraries(icu_example PRIVATE ${ICU_LIBRARIES})
3. Boost.Locale (C++標準風API)
#include <boost/locale.hpp> #include <iostream> using namespace boost::locale; int main() { // ロケールジェネレーター generator gen; // サポートロケール追加 gen.add_messages_path("./locale"); gen.add_messages_domain("myapp"); // ロケール設定 std::locale::global(gen("ja_JP.UTF-8")); std::cout.imbue(std::locale()); // 翻訳 std::cout << translate("Welcome!") << std::endl; std::cout << translate("Hello, {1}!").str("田中") << std::endl; // 複数形 std::cout << format(translate("You have {1} message", "You have {1} messages", 5)) % 5 << std::endl; // 日付フォーマット auto now = std::time(nullptr); std::cout << as::date << std::put_time(std::localtime(&now), "%x") << std::endl; // 通貨 std::cout << as::currency << 1234.56 << std::endl; return 0; }
ベストプラクティス
.NET
- IStringLocalizer 使用: ResourceManager より推奨
- リソース配置: コントローラー/ビュー別に整理
- ハードコード回避: すべての文字列をリソース化
- 文化フォールバック:
→ja-JP
→ デフォルトja - キャッシング: パフォーマンス向上
- データアノテーション: バリデーションメッセージも国際化
C++
- gettext 優先: 翻訳管理に最適
- ICU 併用: 日付・通貨・複数形はICU
- UTF-8 統一: すべての文字列をUTF-8
- マクロ使用:
でシンプルに_() - コンテキスト: pgettext でキー重複回避
- 自動抽出: xgettext で翻訳文字列抽出
翻訳ワークフロー
1. 文字列抽出
.NET:
# カスタムツールで .resx から未翻訳キーを抽出 dotnet run --project LocalizationTool extract --output missing.csv
C++:
# xgettext で翻訳可能文字列を抽出 xgettext --keyword=_ --output=messages.pot src/**/*.cpp
2. 翻訳
- 手動翻訳: Poedit、Lokalize などのGUIツール
- 機械翻訳: DeepL/Google Translate API統合
- 翻訳サービス: Crowdin、Lokalise、Phrase
3. 品質チェック
# .NET: 重複キー検出 dotnet run --project LocalizationTool validate # C++: .po ファイル検証 msgfmt --check-format --check-header ja.po
4. 進捗レポート
Translation Progress ==================== Japanese (ja): 100% ✅ (250/250) Chinese (zh): 85% ⚠️ (213/250) Spanish (es): 60% ❌ (150/250) Missing in Chinese: - Settings.Privacy.DeleteAccount - Checkout.Payment.ApplePay ...
高度な機能
複数形ルール
.NET (.resx):
<data name="ItemCount" xml:space="preserve"> <value>{0} items</value> </data>
C++ (gettext):
msgid "%d item" msgid_plural "%d items" msgstr[0] "%d 個のアイテム" # 日本語は単複同形
日付・通貨フォーマット
.NET:
var date = DateTime.Now; var formattedDate = date.ToString("D", CultureInfo.CurrentCulture); var price = 1234.56m; var formattedPrice = price.ToString("C", CultureInfo.CurrentCulture); // ja-JP: ¥1,235 // en-US: $1,234.56
C++ (ICU):
NumberFormat* fmt = NumberFormat::createCurrencyInstance(Locale("ja_JP"), status); UnicodeString result; fmt->format(1234.56, result); // ¥1,235
ツールとユーティリティ
.NET ツール
- ResXManager - Visual Studio拡張
- Zeta Resource Editor - スタンドアロンエディター
- Lokalise.NET - APIクライアント
C++ ツール
- Poedit - .po ファイルエディター(GUI)
- gettext utilities - xgettext, msgfmt, msgmerge
- translate-toolkit - Pythonベース変換ツール
統合例
例1: ASP.NET Core Web API
ASP.NET Core Web APIに多言語対応: - API レスポンスメッセージ - バリデーションエラー - Accept-Language ヘッダー対応 言語: 英語、日本語、中国語
例2: WPF デスクトップアプリ
WPF 在庫管理アプリを多言語化: - すべてのUI要素 - メッセージボックス - レポート出力 - ランタイム言語切り替え 言語: 英語、日本語、ドイツ語、スペイン語
例3: C++ クロスプラットフォームCLI
C++ コマンドラインツールにgettext統合: - ヘルプメッセージ - エラーメッセージ - 進捗表示 - 環境変数でロケール切り替え 言語: 英語、日本語、フランス語
制限事項
- .NET: リソースファイルはコンパイル時埋め込み(動的追加不可)
- C++: gettext はランタイムで .mo ファイル必要
- ICU: ライブラリサイズが大きい(30MB+)
- 複数形: 言語により複数形ルールが異なる
バージョン情報
- スキルバージョン: 1.0.0
- 対応 .NET: .NET Core 3.1+, .NET 6/7/8/9
- 対応 C++: C++11 以上
- 最終更新: 2025-11-22
使用例:
ASP.NET Core MVC プロジェクトに国際化を追加: 言語: 英語(デフォルト)、日本語、中国語 リソース配置: Resources/ 機能: - すべてのビュー、コントローラー - データアノテーション - クッキーベース言語切り替え - 日付・通貨のロケール別フォーマット 完全な実装コード、設定ファイル、リソースファイルを生成してください。
または
C++ デスクトップアプリケーションにgettextを統合: ライブラリ: gettext 言語: 英語、日本語、ドイツ語 機能: - すべてのUI文字列 - エラーメッセージ - 複数形対応 - CMake ビルド統合 セットアップコード、翻訳ファイル、ビルドスクリプトを生成してください。
エンタープライズレベルの国際化が実装されます!