[win] build DLLs with UI translation
parent
f4ef910886
commit
8e5a89a5a7
|
@ -66,7 +66,7 @@ jobs:
|
||||||
working-directory: ${{github.workspace}}/build/src/celestia
|
working-directory: ${{github.workspace}}/build/src/celestia
|
||||||
run: |
|
run: |
|
||||||
7z a celestia-dep.${{matrix.platform}}.7z ${{env.BUILD_TYPE}}\*
|
7z a celestia-dep.${{matrix.platform}}.7z ${{env.BUILD_TYPE}}\*
|
||||||
7z a celestia-win.${{matrix.platform}}.7z win32\${{env.BUILD_TYPE}}\*
|
7z a celestia-win.${{matrix.platform}}.7z win32\${{env.BUILD_TYPE}}\* win32\res\${{env.BUILD_TYPE}}\res_*.dll
|
||||||
c:\vcpkg\ports\qt5-base\qtdeploy.ps1 qt\${{env.BUILD_TYPE}}\
|
c:\vcpkg\ports\qt5-base\qtdeploy.ps1 qt\${{env.BUILD_TYPE}}\
|
||||||
7z a celestia-qt.${{matrix.platform}}.7z qt\${{env.BUILD_TYPE}}\*
|
7z a celestia-qt.${{matrix.platform}}.7z qt\${{env.BUILD_TYPE}}\*
|
||||||
cd ..\tools
|
cd ..\tools
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
function(_WINDRES_GET_UNIQUE_TARGET_NAME _name _unique_name)
|
||||||
|
set(propertyName "_WINDRES_UNIQUE_COUNTER_${_name}")
|
||||||
|
get_property(currentCounter GLOBAL PROPERTY "${propertyName}")
|
||||||
|
if(NOT currentCounter)
|
||||||
|
set(currentCounter 1)
|
||||||
|
endif()
|
||||||
|
set(${_unique_name} "${_name}_${currentCounter}" PARENT_SCOPE)
|
||||||
|
math(EXPR currentCounter "${currentCounter} + 1")
|
||||||
|
set_property(GLOBAL PROPERTY ${propertyName} ${currentCounter} )
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
macro(WINDRES_CREATE_TRANSLATIONS _rcFile _firstPoFileArg)
|
||||||
|
# make it a real variable, so we can modify it here
|
||||||
|
set(_firstPoFile "${_firstPoFileArg}")
|
||||||
|
|
||||||
|
set(_addToAll)
|
||||||
|
if(${_firstPoFile} STREQUAL "ALL")
|
||||||
|
set(_addToAll "ALL")
|
||||||
|
set(_firstPoFile)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_dllFiles)
|
||||||
|
foreach(_currentPoFile ${_firstPoFile} ${ARGN})
|
||||||
|
get_filename_component(_absFile ${_currentPoFile} ABSOLUTE)
|
||||||
|
get_filename_component(_lang ${_absFile} NAME_WE)
|
||||||
|
set(_locRcFile ${CMAKE_CURRENT_BINARY_DIR}/celestia_${_lang}.rc)
|
||||||
|
set(_dllFile res_${_lang})
|
||||||
|
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${_locRcFile}
|
||||||
|
COMMAND perl ${CMAKE_SOURCE_DIR}/po/translate_resources.pl ${_lang}
|
||||||
|
DEPENDS ${_absFile}
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library(${_dllFile} MODULE ${_locRcFile})
|
||||||
|
set_target_properties(${_dllFile} PROPERTIES PREFIX "" LINKER_LANGUAGE C)
|
||||||
|
if(MSVC)
|
||||||
|
set_target_properties(${_dllFile} PROPERTIES LINK_FLAGS "/MANIFEST:NO /NODEFAULTLIB /NOENTRY")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS ${_dllFile} LIBRARY DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
set(_dllFiles ${_dllFiles} ${_dllFile})
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
if(NOT TARGET resources)
|
||||||
|
add_custom_target(resources)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
_WINDRES_GET_UNIQUE_TARGET_NAME(resources uniqueTargetName)
|
||||||
|
add_custom_target(${uniqueTargetName} ${_addToAll} DEPENDS ${_dllFiles})
|
||||||
|
add_dependencies(resources ${uniqueTargetName})
|
||||||
|
endmacro()
|
|
@ -3,29 +3,25 @@
|
||||||
################################################################
|
################################################################
|
||||||
# Utility for i18n on Win32
|
# Utility for i18n on Win32
|
||||||
#
|
#
|
||||||
# Author: Christophe Teyssier <chris@teyssier.org>
|
# Copyright: 2006-2021, Celestia Development Team
|
||||||
# date: July 2006
|
# Original author: Christophe Teyssier <chris@teyssier.org>
|
||||||
|
# Original date: July 2006
|
||||||
#
|
#
|
||||||
# - Loads translations from the po files and produces translated .rc files in src/celestia/res
|
# - Loads translations from the po files and produces translated .rc
|
||||||
# - Produces a dll with the translated resources for each po file in the locale/ dir
|
# files in src/celestia/win32/res
|
||||||
# - Produces a list of unicode codepoints for each language in the current dir
|
|
||||||
# (to generate txf font textures)
|
|
||||||
# - Compiles .po files and installs catalogs under locale/
|
|
||||||
#
|
|
||||||
# Requirements:
|
|
||||||
# - rc.exe link.exe and msgfmt.exe must be in the PATH
|
|
||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
use Encode;
|
use Encode;
|
||||||
use File::Basename;
|
use File::Basename;
|
||||||
|
use File::Path qw(make_path);
|
||||||
|
use Cwd qw(getcwd);
|
||||||
|
|
||||||
my $dir = dirname $0;
|
my $lang = $ARGV[0];
|
||||||
my $resource_file = "$dir/../src/celestia/win32/res/celestia.rc";
|
|
||||||
my $output_dir = "$dir/../src/celestia/win32/res/";
|
|
||||||
|
|
||||||
opendir(DIR, $dir);
|
my $po_dir = dirname $0;
|
||||||
my @po_files = sort (grep( /\.po$/, readdir(DIR) ));
|
my $resource_file = "$po_dir/../src/celestia/win32/res/celestia.rc";
|
||||||
closedir DIR;
|
my $rc_dir = dirname $resource_file;
|
||||||
|
my $build_dir = getcwd;
|
||||||
|
|
||||||
open RES, "< $resource_file";
|
open RES, "< $resource_file";
|
||||||
my $resource;
|
my $resource;
|
||||||
|
@ -38,89 +34,92 @@ close RES;
|
||||||
# LangID and code page
|
# LangID and code page
|
||||||
# http://msdn.microsoft.com/en-us/library/dd318693
|
# http://msdn.microsoft.com/en-us/library/dd318693
|
||||||
my %lang = (
|
my %lang = (
|
||||||
ar => [ '401', 1256 ],
|
ar => [ '401', 1256, 'LANG_ARABIC, SUBLANG_DEFAULT'],
|
||||||
be => [ '423', 1251 ],
|
be => [ '423', 1251, 'LANG_BELARUSIAN, SUBLANG_DEFAULT'],
|
||||||
bg => [ '402', 1251 ],
|
bg => [ '402', 1251, 'LANG_BULGARIAN, SUBLANG_DEFAULT'],
|
||||||
de => [ '407', 1252 ],
|
de => [ '407', 1252, 'LANG_GERMAN, SUBLANG_DEFAULT'],
|
||||||
el => [ '408', 1253 ],
|
el => [ '408', 1253, 'LANG_GREEK, SUBLANG_DEFAULT'],
|
||||||
en => [ '409', 1252 ],
|
en => [ '409', 1252, 'LANG_ENGLISH, SUBLANG_DEFAULT'],
|
||||||
es => [ '40a', 1252 ],
|
es => [ '40a', 1252, 'LANG_SPANISH, SUBLANG_DEFAULT'],
|
||||||
fr => [ '40c', 1252 ],
|
fr => [ '40c', 1252, 'LANG_FRENCH, SUBLANG_DEFAULT'],
|
||||||
gl => [ '456', 1252 ],
|
gl => [ '456', 1252, 'LANG_GALICIAN, SUBLANG_DEFAULT' ],
|
||||||
hu => [ '40e', 1250 ],
|
hu => [ '40e', 1250, 'LANG_HUNGARIAN, SUBLANG_DEFAULT'],
|
||||||
it => [ '410', 1252 ],
|
it => [ '410', 1252, 'LANG_ITALIAN, SUBLANG_DEFAULT'],
|
||||||
ja => [ '411', 932 ],
|
ja => [ '411', 932, 'LANG_JAPANESE, SUBLANG_DEFAULT'],
|
||||||
ko => [ '412', 949 ],
|
ko => [ '412', 949, 'LANG_KOREAN, SUBLANG_DEFAULT'],
|
||||||
lt => [ '427', 1257 ],
|
lt => [ '427', 1257, 'LANG_LITHUANIAN, SUBLANG_DEFAULT'],
|
||||||
lv => [ '426', 1257 ],
|
lv => [ '426', 1257, 'LANG_LATVIAN, SUBLANG_DEFAULT'],
|
||||||
nl => [ '413', 1252 ],
|
nb => [ '414', 1252, 'LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL'],
|
||||||
no => [ '414', 1252 ],
|
nl => [ '413', 1252, 'LANG_DUTCH, SUBLANG_DEFAULT'],
|
||||||
pl => [ '415', 1250 ],
|
no => [ '814', 1252, 'LANG_NORWEGIAN, SUBLANG_NORWEGIAN_NYNORSK'],
|
||||||
pt_BR => [ '416', 1252 ],
|
pl => [ '415', 1250, 'LANG_POLISH, SUBLANG_DEFAULT'],
|
||||||
pt => [ '816', 1252 ],
|
pt_BR => [ '416', 1252, 'LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN'],
|
||||||
ro => [ '418', 1250 ],
|
pt => [ '816', 1252, 'LANG_PORTUGUESE, SUBLANG_PORTUGUESE_PORTUGAL'],
|
||||||
ru => [ '419', 1251 ],
|
ro => [ '418', 1250, 'LANG_ROMANIAN, SUBLANG_DEFAULT'],
|
||||||
sk => [ '41b', 1250 ],
|
ru => [ '419', 1251, 'LANG_RUSSIAN, SUBLANG_DEFAULT'],
|
||||||
sv => [ '41d', 1252 ],
|
sk => [ '41b', 1250, 'LANG_SLOVAK, SUBLANG_DEFAULT'],
|
||||||
tr => [ '41f', 1254 ],
|
sv => [ '41d', 1252, 'LANG_SWEDISH, SUBLANG_DEFAULT'],
|
||||||
uk => [ '422', 1251 ],
|
tr => [ '41f', 1254, 'LANG_TURKISH, SUBLANG_DEFAULT'],
|
||||||
zh_CN => [ '804', 936 ],
|
uk => [ '422', 1251, 'LANG_UKRAINIAN, SUBLANG_DEFAULT'],
|
||||||
zh_TW => [ '404', 950 ],
|
zh_CN => [ '804', 936, 'LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL'],
|
||||||
|
zh_TW => [ '404', 950, 'LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED'],
|
||||||
);
|
);
|
||||||
|
|
||||||
mkdir "$dir\\..\\locale" if ! -d "$dir\\..\\locale";
|
my @keywords = qw{
|
||||||
|
POPUP
|
||||||
|
MENUITEM
|
||||||
|
DEFPUSHBUTTON
|
||||||
|
LTEXT
|
||||||
|
CAPTION
|
||||||
|
PUSHBUTTON
|
||||||
|
RTEXT
|
||||||
|
CTEXT
|
||||||
|
LTEXT
|
||||||
|
GROUPBOX
|
||||||
|
CONTROL
|
||||||
|
GROUPBOX
|
||||||
|
AUTOCHECKBOX
|
||||||
|
AUTORADIOBUTTON
|
||||||
|
};
|
||||||
|
|
||||||
my %codepoints; # hash holds unicode codepoints used by language
|
my $keys = join('|', @keywords);
|
||||||
|
|
||||||
foreach my $po (@po_files) {
|
my $strings = load_po_strings("$po_dir/$lang.po");
|
||||||
my $strings = load_po_strings("$dir\\$po");
|
my @res = split(/\n|\r\n/, $resource);
|
||||||
my $res = $resource;
|
my $lang_id = $lang{$lang}[0];
|
||||||
my $lang = basename $po;
|
my $codepade = $lang{$lang}[1];
|
||||||
$lang =~ s/\..*//o;
|
my $lang_name = $lang{$lang}[2];
|
||||||
mkdir "$dir\\..\\locale\\$lang" if ! -d "$dir\\..\\locale\\$lang";
|
Encode::from_to($v, 'UTF-8', "CP$codepade");
|
||||||
mkdir "$dir\\..\\locale\\$lang\\LC_MESSAGES" if ! -d "$dir\\..\\locale\\$lang\\LC_MESSAGES";
|
|
||||||
|
|
||||||
while (my ($k, $v) = each %$strings) {
|
while (my ($k, $v) = each %$strings) {
|
||||||
map { $codepoints{$lang}{$_} = 1; } map { sprintf '%04X', ord($_); } split //, Encode::decode_utf8($v);
|
next if $k !~ /^(.+)\004(.+)$/;
|
||||||
Encode::from_to($v, 'UTF-8', "CP$lang{$lang}[1]");
|
my $msgctxt = $1;
|
||||||
map { $c{ord($_)} = 1; } split //, Encode::decode("UTF-8", $v);
|
my $msgid = $2;
|
||||||
$res =~ s/"\Q$k\E"/"$v"/g;
|
|
||||||
|
foreach my $line (@res) {
|
||||||
|
if ($line =~ /^\s*(?:$keys)/) {
|
||||||
|
$line =~ s/\bNC_\(\s*"\Q$msgctxt\E"\s*,\s*"\Q$msgid\E"\s*\)/"$v"/g;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$res=~ s/\Q#pragma code_page(1252)\E/#pragma code_page($lang{$lang}[1])/;
|
|
||||||
open OUT, "> $output_dir/celestia_$lang.rc";
|
|
||||||
print OUT $res;
|
|
||||||
close OUT;
|
|
||||||
system qq{rc /l $lang{$lang}[0] /d "NDEBUG" /fo $dir\\..\\src\\celestia\\win32\\celestia_$lang.res /i "$dir\\..\\src\\celestia\\win32\\res" $dir\\..\\src\\celestia\\win32\\res\\celestia_$lang.rc};
|
|
||||||
system qq{link /nologo /noentry /dll /machine:I386 /out:$dir\\..\\locale\\res_$lang.dll $dir\\..\\src\\celestia\\win32\\celestia_$lang.res};
|
|
||||||
system qq{msgfmt $dir\\$lang.po -o $dir\\..\\locale\\$lang\\LC_MESSAGES\\celestia.mo};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
opendir(DIR, "$dir\\..\\po2");
|
while (my ($k, $v) = each %$strings) {
|
||||||
my @po_files = sort (grep( /\.po$/, readdir(DIR) ));
|
next if $k =~ /^(.+)\004(.+)$/;
|
||||||
closedir DIR;
|
foreach my $line (@res) {
|
||||||
foreach my $po (@po_files) {
|
if ($line =~ /^\s*(?:$keys)/) {
|
||||||
my $lang = basename $po;
|
$line =~ s/"\Q$k\E"/"$v"/g;
|
||||||
$lang =~ s/\..*//o;
|
}
|
||||||
|
|
||||||
my $strings = load_po_strings("$dir\\..\\po2\\$po");
|
|
||||||
while (my ($k, $v) = each %$strings) {
|
|
||||||
map { $codepoints{$lang}{$_} = 1; } map { sprintf '%04X', ord($_); } split //, Encode::decode_utf8($v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mkdir "$dir\\..\\locale\\$lang" if ! -d "$dir\\..\\locale\\$lang";
|
|
||||||
mkdir "$dir\\..\\locale\\$lang\\LC_MESSAGES" if ! -d "$dir\\..\\locale\\$lang\\LC_MESSAGES";
|
|
||||||
system qq{msgfmt $dir\\..\\po2\\$lang.po -o $dir\\..\\locale\\$lang\\LC_MESSAGES\\celestia_constellations.mo};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $lang (keys %codepoints) {
|
foreach my $line (@res) {
|
||||||
# list of unicode codepoints to generate font textures
|
$line =~ s/LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US/\/\/LANGUAGE $lang_name/;
|
||||||
my $chr;
|
$line =~ s/\Q#pragma code_page(1252)\E/#pragma code_page($codepade)/;
|
||||||
map { $chr .= "$_ \n"; } sort keys %{$codepoints{$lang}};
|
$line =~ s/VALUE "Translation", 0x0?409, (?:1252|0x04B0)/VALUE "Translation", 0x$lang_id, $codepade/;
|
||||||
open CHR, "> $dir/codepoints_$lang.txt";
|
|
||||||
print CHR $chr;
|
|
||||||
close CHR;
|
|
||||||
}
|
}
|
||||||
|
open OUT, "> celestia_$lang.rc";
|
||||||
|
print OUT join("\r\n", @res);
|
||||||
|
close OUT;
|
||||||
|
|
||||||
sub load_po_strings {
|
sub load_po_strings {
|
||||||
my $po = shift;
|
my $po = shift;
|
||||||
|
@ -130,18 +129,28 @@ sub load_po_strings {
|
||||||
my $l1;
|
my $l1;
|
||||||
my $l2;
|
my $l2;
|
||||||
my $l3;
|
my $l3;
|
||||||
while ($l3 = <PO>) {
|
my $l4;
|
||||||
|
while ($l4 = <PO>) {
|
||||||
# The po file is read by groups of three lines.
|
# The po file is read by groups of three lines.
|
||||||
# we can safely ignore multiline msgids since resource files
|
# we can safely ignore multiline msgids since resource files
|
||||||
# use only single line strings
|
# use only single line strings
|
||||||
if ($l2 =~ /^msgid\s+"(.*)"/) {
|
if ($l3 =~ /^msgid\s+"(.*)"/) {
|
||||||
my $msgid = $1;
|
my $msgid = $1;
|
||||||
if ($l3 =~ /^msgstr\s+"(.+)"/ && $l1 !~ /fuzzy/ ) {
|
if ($l4 =~ /^msgstr\s+"(.+)"/) {
|
||||||
$strings{$msgid} = $1;
|
my $translation = $1;
|
||||||
|
if ($l2 =~ /^msgctxt\s+"(.+)"/) {
|
||||||
|
my $context = $1;
|
||||||
|
if ($l1 !~ /fuzzy/) {
|
||||||
|
$strings{"$context\004$msgid"} = $translation;
|
||||||
|
}
|
||||||
|
} elsif ($l2 !~ /fuzzy/) {
|
||||||
|
$strings{$msgid} = $translation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$l1 = $l2;
|
$l1 = $l2;
|
||||||
$l2 = $l3;
|
$l2 = $l3;
|
||||||
|
$l3 = $l4;
|
||||||
}
|
}
|
||||||
close PO;
|
close PO;
|
||||||
return \%strings;
|
return \%strings;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
if(NOT WIN32 OR NOT ENABLE_WIN)
|
if(NOT ((WIN32 OR MINGW) AND ENABLE_WIN))
|
||||||
message(STATUS "Either not Windows or Windows frontend is disabled.")
|
message(STATUS "Either not Windows or Windows frontend is disabled.")
|
||||||
return()
|
return()
|
||||||
endif()
|
endif()
|
||||||
|
@ -47,3 +47,5 @@ add_executable(celestia-win WIN32 ${WIN32_SOURCES} ${RESOURCES})
|
||||||
add_dependencies(celestia-win celestia)
|
add_dependencies(celestia-win celestia)
|
||||||
target_link_libraries(celestia-win celestia)
|
target_link_libraries(celestia-win celestia)
|
||||||
install(TARGETS celestia-win RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
install(TARGETS celestia-win RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||||
|
|
||||||
|
add_subdirectory(res)
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
if(NOT ENABLE_NLS)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
include(windres)
|
||||||
|
|
||||||
|
file(GLOB PO_FILES2 "${CMAKE_SOURCE_DIR}/po/*.po")
|
||||||
|
WINDRES_CREATE_TRANSLATIONS(celestia.rc ALL ${PO_FILES2})
|
Loading…
Reference in New Issue