mirror of
https://github.com/cookiengineer/audacity
synced 2025-04-29 15:19:44 +02:00
Add targets for packaging DMG and InnoSetup
Fixes configure.sh Fixes Windows code signing Fixes an issue with conan cache on windows Fixes build manual script Fixes build manual Remove unused props Use long options Yet another manual fix Fixes iss
This commit is contained in:
parent
d21ee922e1
commit
6da25e1646
19
.github/workflows/cmake_build.yml
vendored
19
.github/workflows/cmake_build.yml
vendored
@ -15,6 +15,13 @@ jobs:
|
||||
env:
|
||||
AUDACITY_CMAKE_GENERATOR: ${{ matrix.config.generator }}
|
||||
AUDACITY_ARCH_LABEL: ${{ matrix.config.arch }}
|
||||
# Windows codesigning
|
||||
# This variables will be used by all the steps
|
||||
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
|
||||
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
|
||||
# Conan home location to be used for cache action
|
||||
CONAN_USER_HOME: "${{ github.workspace }}/conan-home/"
|
||||
CONAN_USER_HOME_SHORT: "${{ github.workspace }}/conan-home/short"
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@ -52,6 +59,13 @@ jobs:
|
||||
- name: Environment
|
||||
run: |
|
||||
source "scripts/ci/environment.sh"
|
||||
|
||||
- name: Install Apple codesigning certificates
|
||||
uses: apple-actions/import-codesign-certs@v1
|
||||
if: startswith( matrix.config.os, 'macos' ) && github.event_name == 'push'
|
||||
with:
|
||||
p12-file-base64: ${{ secrets.APPLE_CERTIFICATE }}
|
||||
p12-password: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||
|
||||
- name: Cache for .conan
|
||||
id: cache-conan
|
||||
@ -66,10 +80,15 @@ jobs:
|
||||
|
||||
- name: Configure
|
||||
env:
|
||||
# Error reporing
|
||||
SENTRY_DSN_KEY: ${{ secrets.SENTRY_DSN_KEY }}
|
||||
SENTRY_HOST: ${{ secrets.SENTRY_HOST }}
|
||||
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
|
||||
CRASH_REPORT_URL: ${{ secrets.CRASH_REPORT_URL }}
|
||||
# Apple code signing
|
||||
APPLE_CODESIGN_IDENTITY: ${{ secrets.APPLE_CODESIGN_IDENTITY }}
|
||||
APPLE_NOTARIZATION_USER_NAME: ${{ secrets.APPLE_NOTARIZATION_USER_NAME }}
|
||||
APPLE_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
run: |
|
||||
exec bash "scripts/ci/configure.sh"
|
||||
|
||||
|
@ -534,6 +534,42 @@ file( WRITE "${CMAKE_CURRENT_BINARY_DIR}/modules.dot" "digraph {
|
||||
execute_process( COMMAND
|
||||
dot -O -Tsvg "${CMAKE_CURRENT_BINARY_DIR}/modules.dot" )
|
||||
|
||||
#
|
||||
# Code signing
|
||||
#
|
||||
|
||||
cmd_option( ${_OPT}perform_codesign
|
||||
"Perform code signing during the install step. This only works on Windows and macOS."
|
||||
Off
|
||||
)
|
||||
|
||||
cmake_dependent_option(
|
||||
${_OPT}perform_notarization
|
||||
"Perform notarization during the install step. This only works on macOS."
|
||||
Off
|
||||
"${_OPT}perform_codesign;APPLE"
|
||||
Off
|
||||
)
|
||||
|
||||
if( ${_OPT}perform_codesign )
|
||||
include( AudacityCodeSigning )
|
||||
endif()
|
||||
|
||||
#
|
||||
# Packaging
|
||||
#
|
||||
|
||||
cmd_option( ${_OPT}package_manual
|
||||
"Package the manual along with the DMG and InnoSetup targets"
|
||||
Off
|
||||
)
|
||||
|
||||
# Variables, that are common for all package targets
|
||||
|
||||
if( CMAKE_SYSTEM_NAME MATCHES "Windows" )
|
||||
include( AudacityInnoSetup )
|
||||
endif()
|
||||
|
||||
# Uncomment what follows for symbol values.
|
||||
#[[
|
||||
get_cmake_property( _variableNames VARIABLES )
|
||||
|
36
cmake-proxies/cmake-modules/AudacityCodeSigning.cmake
Normal file
36
cmake-proxies/cmake-modules/AudacityCodeSigning.cmake
Normal file
@ -0,0 +1,36 @@
|
||||
# Code signing
|
||||
|
||||
if( CMAKE_SYSTEM_NAME MATCHES "Windows" )
|
||||
# On windows, we expect WINDOWS_CERTIFICATE to be set
|
||||
# as a CMake variable or as an environment variable
|
||||
if( DEFINED WINDOWS_CERTIFICATE )
|
||||
install( CODE "set( WINDOWS_CERTIFICATE \"${WINDOWS_CERTIFICATE}\" )" )
|
||||
endif()
|
||||
|
||||
if( DEFINED WINDOWS_CERTIFICATE_PASSWORD )
|
||||
# To simplify the helper script - we push password to the environment
|
||||
install( CODE "set( ENV{WINDOWS_CERTIFICATE_PASSWORD} \"${WINDOWS_CERTIFICATE_PASSWORD}\") " )
|
||||
endif()
|
||||
|
||||
install( CODE "set( PFX_SIGN_PS_LOCATION \"${CMAKE_SOURCE_DIR}/scripts/build/windows/PfxSign.ps1\") " )
|
||||
install( SCRIPT "scripts/build/windows/PfxSign.cmake" )
|
||||
elseif( CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||
set_from_env( APPLE_CODESIGN_IDENTITY )
|
||||
set_from_env( APPLE_NOTARIZATION_USER_NAME )
|
||||
set_from_env( APPLE_NOTARIZATION_PASSWORD )
|
||||
|
||||
# Pass arguments to cmake install script
|
||||
install( CODE "set( APPLE_CODESIGN_IDENTITY \"${APPLE_CODESIGN_IDENTITY}\" )" )
|
||||
install( CODE "set( APPLE_NOTARIZATION_USER_NAME \"${APPLE_NOTARIZATION_USER_NAME}\" )" )
|
||||
install( CODE "set( APPLE_NOTARIZATION_PASSWORD \"${APPLE_NOTARIZATION_PASSWORD}\" )" )
|
||||
|
||||
install( CODE "set( APP_IDENTIFIER \"org.audacityteam.audacity\" )" )
|
||||
install( CODE "get_filename_component( APP_LOCATION \${CMAKE_INSTALL_PREFIX}/Audacity.app ABSOLUTE )" )
|
||||
install( CODE "set( APPLE_CODESIGN_ENTITLEMENTS ${CMAKE_SOURCE_DIR}/mac/Audacity.entitlements )")
|
||||
|
||||
install( SCRIPT "scripts/build/macOS/SignMacos.cmake" )
|
||||
|
||||
if( ${_OPT}perform_notarization )
|
||||
install( SCRIPT "scripts/build/macOS/NotarizeMacos.cmake" )
|
||||
endif()
|
||||
endif()
|
39
cmake-proxies/cmake-modules/AudacityInnoSetup.cmake
Normal file
39
cmake-proxies/cmake-modules/AudacityInnoSetup.cmake
Normal file
@ -0,0 +1,39 @@
|
||||
# Defines innosetup target
|
||||
# The target will be only generated if InnoSetup 6 is installed.
|
||||
|
||||
find_program(
|
||||
INNO_SETUP_COMPILER
|
||||
NAMES iscc ISCC
|
||||
HINTS
|
||||
"C:/Program Files (x86)/Inno Setup 6"
|
||||
"C:/Program Files/Inno Setup 6"
|
||||
)
|
||||
|
||||
if( INNO_SETUP_COMPILER )
|
||||
message(STATUS "Creating target innosetup...")
|
||||
|
||||
set( TEMP_PACKAGE_PATH "${CMAKE_BINARY_DIR}/innosetup" )
|
||||
|
||||
add_custom_target(
|
||||
innosetup
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
-DBUILD_DIR=${CMAKE_BINARY_DIR}
|
||||
-DSOURCE_DIR=${CMAKE_SOURCE_DIR}
|
||||
-DOUTPUT_DIR=${TEMP_PACKAGE_PATH}
|
||||
-DINNO_SETUP_COMPILER=${INNO_SETUP_COMPILER}
|
||||
-DEMBED_MANUAL=${${_OPT}package_manual}
|
||||
-DBUILDING_64_BIT=${IS_64BIT}
|
||||
-DSIGN=${${_OPT}perform_codesign}
|
||||
-DWINDOWS_CERTIFICATE=${WINDOWS_CERTIFICATE}
|
||||
-D WINDOWS_CERTIFICATE_PASSWORD=${WINDOWS_CERTIFICATE_PASSWORD}
|
||||
-P "${CMAKE_SOURCE_DIR}/win/Inno_Setup_Wizard/BuildInnoSetupInstaller.cmake"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
if( ${_OPT}package_manual )
|
||||
add_dependencies( innosetup manual )
|
||||
endif()
|
||||
|
||||
set_target_properties( innosetup PROPERTIES FOLDER "packaging" )
|
||||
endif()
|
@ -2,6 +2,8 @@
|
||||
set(CPACK_PACKAGE_VERSION_MAJOR "${AUDACITY_VERSION}") # X
|
||||
set(CPACK_PACKAGE_VERSION_MINOR "${AUDACITY_RELEASE}") # Y
|
||||
set(CPACK_PACKAGE_VERSION_PATCH "${AUDACITY_REVISION}") # Z
|
||||
set(CPACK_PACKAGE_VENDOR "Audacity")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://audacityteam.org")
|
||||
|
||||
# X.Y.Z-alpha-20210615
|
||||
set(CPACK_PACKAGE_VERSION "${AUDACITY_VERSION}.${AUDACITY_RELEASE}.${AUDACITY_REVISION}${AUDACITY_SUFFIX}")
|
||||
@ -22,4 +24,22 @@ set(CPACK_PACKAGE_DIRECTORY "${CMAKE_BINARY_DIR}/package")
|
||||
|
||||
set(CPACK_GENERATOR ZIP)
|
||||
|
||||
if( CMAKE_SYSTEM_NAME STREQUAL "Darwin" )
|
||||
set( CPACK_GENERATOR DragNDrop )
|
||||
|
||||
set( CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/mac/Resources/Audacity-DMG-background.png")
|
||||
set( CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_SOURCE_DIR}/scripts/build/macOS/DMGSetup.scpt")
|
||||
|
||||
if( ${_OPT}perform_codesign )
|
||||
set( CPACK_APPLE_CODESIGN_IDENTITY ${APPLE_CODESIGN_IDENTITY} )
|
||||
set( CPACK_APPLE_NOTARIZATION_USER_NAME ${APPLE_NOTARIZATION_USER_NAME} )
|
||||
set( CPACK_APPLE_NOTARIZATION_PASSWORD ${APPLE_NOTARIZATION_PASSWORD} )
|
||||
set( CPACK_APPLE_SIGN_SCRIPTS "${CMAKE_SOURCE_DIR}/scripts/build/macOS" )
|
||||
set( CPACK_PERFORM_NOTARIZATION ${${_OPT}perform_notarization} )
|
||||
|
||||
# CPACK_POST_BUILD_SCRIPTS was added in 3.19, but we only need it on macOS
|
||||
SET( CPACK_POST_BUILD_SCRIPTS "${CMAKE_SOURCE_DIR}/scripts/build/macOS/DMGSign.cmake" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(CPack) # do this last
|
||||
|
@ -34,6 +34,20 @@ add_custom_command(
|
||||
|
||||
add_custom_target( ${TARGET} DEPENDS "${out}" )
|
||||
|
||||
if( ${_OPT}package_manual )
|
||||
install(CODE " \
|
||||
execute_process( \
|
||||
COMMAND \
|
||||
${CMAKE_COMMAND} \
|
||||
--build ${CMAKE_BINARY_DIR} \
|
||||
--config \${CMAKE_INSTALL_CONFIG_NAME} \
|
||||
--target manual \
|
||||
) \
|
||||
")
|
||||
|
||||
install( DIRECTORY "${out_dir}/${host}/" DESTINATION "help/manual" )
|
||||
endif()
|
||||
|
||||
if( NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" )
|
||||
if( NOT "${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
|
||||
install( DIRECTORY "${dst}" OPTIONAL
|
||||
@ -44,4 +58,3 @@ if( NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" )
|
||||
DESTINATION "${_DATADIR}/appdata" )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
22
scripts/build/macOS/DMGSetup.scpt
Normal file
22
scripts/build/macOS/DMGSetup.scpt
Normal file
@ -0,0 +1,22 @@
|
||||
on run argv
|
||||
set diskImage to item 1 of argv
|
||||
|
||||
tell application "Finder"
|
||||
tell disk diskImage
|
||||
open
|
||||
set current view of container window to icon view
|
||||
set toolbar visible of container window to false
|
||||
set statusbar visible of container window to false
|
||||
set the bounds of container window to {400, 100, 1000, 550}
|
||||
set theViewOptions to the icon view options of container window
|
||||
set arrangement of theViewOptions to not arranged
|
||||
set icon size of theViewOptions to 72
|
||||
set background picture of theViewOptions to file ".background:background.png"
|
||||
set position of item "Audacity" of container window to {170, 350}
|
||||
set position of item "Applications" of container window to {430, 350}
|
||||
close
|
||||
open
|
||||
update without registering applications
|
||||
end tell
|
||||
end tell
|
||||
end run
|
16
scripts/build/macOS/DMGSign.cmake
Normal file
16
scripts/build/macOS/DMGSign.cmake
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
set( APPLE_CODESIGN_IDENTITY ${CPACK_APPLE_CODESIGN_IDENTITY} )
|
||||
set( APPLE_NOTARIZATION_USER_NAME ${CPACK_APPLE_NOTARIZATION_USER_NAME} )
|
||||
set( APPLE_NOTARIZATION_PASSWORD ${CPACK_APPLE_NOTARIZATION_PASSWORD} )
|
||||
set( PERFORM_NOTARIZATION ${CPACK_PERFORM_NOTARIZATION} )
|
||||
set( APP_IDENTIFIER "org.audacityteam.audacity" )
|
||||
|
||||
foreach( file ${CPACK_PACKAGE_FILES} )
|
||||
set( DMG_LOCATION ${CPACK_PACKAGE_FILES} )
|
||||
|
||||
include( "${CPACK_APPLE_SIGN_SCRIPTS}/SignMacos.cmake" )
|
||||
|
||||
if( PERFORM_NOTARIZATION )
|
||||
include( "${CPACK_APPLE_SIGN_SCRIPTS}/NotarizeMacos.cmake" )
|
||||
endif()
|
||||
endforeach()
|
111
scripts/build/macOS/NotarizeMacos.cmake
Normal file
111
scripts/build/macOS/NotarizeMacos.cmake
Normal file
@ -0,0 +1,111 @@
|
||||
# CMake script to sign macOS build
|
||||
# Arguments:
|
||||
# APP_IDENTIFIER - app identifier
|
||||
# APP_LOCATION - the path to Audacity.app
|
||||
# DMG_LOCATION - the path to Audaicty dmg package
|
||||
# APPLE_NOTARIZATION_USER_NAME - notarization user name
|
||||
# APPLE_NOTARIZATION_PASSWORD - notarization password
|
||||
|
||||
# https://cmake.org/cmake/help/latest/policy/CMP0054.html
|
||||
cmake_policy( SET CMP0054 NEW )
|
||||
# https://cmake.org/cmake/help/latest/policy/CMP0011.html
|
||||
cmake_policy( SET CMP0011 NEW )
|
||||
|
||||
function( get_plist_value output path key )
|
||||
execute_process(
|
||||
COMMAND /usr/libexec/PlistBuddy -c "Print ${key}" "${path}"
|
||||
OUTPUT_VARIABLE result
|
||||
)
|
||||
|
||||
string( STRIP ${result} result )
|
||||
|
||||
set( ${output} ${result} PARENT_SCOPE )
|
||||
endfunction()
|
||||
|
||||
if( APP_LOCATION )
|
||||
get_filename_component( temp_dir "${APP_LOCATION}/.." ABSOLUTE )
|
||||
else()
|
||||
get_filename_component( temp_dir "${DMG_LOCATION}" DIRECTORY )
|
||||
endif()
|
||||
|
||||
set( temp_plist "${temp_dir}/NotarizationResult.plist" )
|
||||
|
||||
function( notarize path )
|
||||
message( STATUS "Notarizing ${path}" )
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
xcrun altool
|
||||
--notarize-app
|
||||
--primary-bundle-id "${APP_IDENTIFIER}"
|
||||
--file "${path}"
|
||||
--username "${APPLE_NOTARIZATION_USER_NAME}"
|
||||
--password "${APPLE_NOTARIZATION_PASSWORD}"
|
||||
--output-format xml
|
||||
OUTPUT_VARIABLE
|
||||
result
|
||||
)
|
||||
|
||||
file( WRITE ${temp_plist} ${result} )
|
||||
|
||||
get_plist_value( req_id ${temp_plist} "notarization-upload:RequestUUID" )
|
||||
|
||||
message( STATUS "\t Request ID: '${req_id}'" )
|
||||
|
||||
set( success Off )
|
||||
|
||||
while( NOT success )
|
||||
execute_process(COMMAND ${CMAKE_COMMAND} -E sleep 15)
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
xcrun altool
|
||||
--notarization-info ${req_id}
|
||||
--username ${APPLE_NOTARIZATION_USER_NAME}
|
||||
--password ${APPLE_NOTARIZATION_PASSWORD}
|
||||
--output-format xml
|
||||
OUTPUT_VARIABLE
|
||||
result
|
||||
)
|
||||
|
||||
file( WRITE ${temp_plist} ${result} )
|
||||
|
||||
get_plist_value( notarization_result ${temp_plist} "notarization-info:Status" )
|
||||
|
||||
message( STATUS "\t Status: ${notarization_result}" )
|
||||
|
||||
if( NOT "${notarization_result}" STREQUAL "in progress" )
|
||||
if ( NOT "${notarization_result}" STREQUAL "success" )
|
||||
message(FATAL_ERROR "Notarization failed:\n${result}\n")
|
||||
else()
|
||||
message(STATUS "Notarization successfull")
|
||||
endif()
|
||||
|
||||
break()
|
||||
endif()
|
||||
endwhile()
|
||||
endfunction()
|
||||
|
||||
if( DEFINED APP_LOCATION )
|
||||
get_filename_component( archive "${APP_LOCATION}/../notarization.zip" ABSOLUTE )
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
xcrun ditto
|
||||
-c -k --keepParent
|
||||
${APP_LOCATION}
|
||||
${archive}
|
||||
)
|
||||
|
||||
notarize( ${archive} )
|
||||
execute_process( COMMAND stapler staple "${APP_LOCATION}" )
|
||||
|
||||
file( REMOVE "${APP_LOCATION}/../notarization.zip" )
|
||||
endif()
|
||||
|
||||
if( DEFINED DMG_LOCATION )
|
||||
notarize( ${DMG_LOCATION} )
|
||||
execute_process( COMMAND stapler staple "${DMG_LOCATION}" )
|
||||
endif()
|
||||
|
||||
file( REMOVE ${temp_plist} )
|
54
scripts/build/macOS/SignMacos.cmake
Normal file
54
scripts/build/macOS/SignMacos.cmake
Normal file
@ -0,0 +1,54 @@
|
||||
# CMake script to sign macOS build
|
||||
# Arguments:
|
||||
# APP_IDENTIFIER - app identifier
|
||||
# APP_LOCATION - the path to Audacity.app
|
||||
# DMG_LOCATION - the path to Audaicty dmg package
|
||||
# APPLE_CODESIGN_IDENTITY - identity to use
|
||||
# APPLE_CODESIGN_ENTITLEMENTS - path to the entitlements
|
||||
|
||||
function( codesign path deep is_dmg)
|
||||
message(STATUS "Signing ${path}")
|
||||
|
||||
set ( args
|
||||
--verbose
|
||||
--timestamp
|
||||
--identifier "${APP_IDENTIFIER}"
|
||||
--sign "${APPLE_CODESIGN_IDENTITY}"
|
||||
)
|
||||
|
||||
if( NOT is_dmg )
|
||||
list( APPEND args
|
||||
--options runtime
|
||||
--entitlements "${APPLE_CODESIGN_ENTITLEMENTS}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if( deep )
|
||||
list( APPEND args --deep)
|
||||
endif()
|
||||
|
||||
execute_process( COMMAND xcrun codesign ${args} ${path} )
|
||||
endfunction()
|
||||
|
||||
function( sign_modules path )
|
||||
message(STATUS "\tLooking for modules or plugins in: '${path}'")
|
||||
|
||||
file( GLOB_RECURSE modules
|
||||
LIST_DIRECTORIES Off
|
||||
"${path}/*.so" "${path}/*.dylib"
|
||||
)
|
||||
|
||||
foreach( module ${modules} )
|
||||
codesign( ${module} Off Off )
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
if( DEFINED APP_LOCATION )
|
||||
sign_modules( "${APP_LOCATION}/Contents/modules" )
|
||||
sign_modules( "${APP_LOCATION}/Contents/plug-ins" )
|
||||
codesign( "${APP_LOCATION}" On Off )
|
||||
endif()
|
||||
|
||||
if (DEFINED DMG_LOCATION )
|
||||
codesign( "${DMG_LOCATION}" Off On)
|
||||
endif()
|
28
scripts/build/windows/PfxSign.cmake
Normal file
28
scripts/build/windows/PfxSign.cmake
Normal file
@ -0,0 +1,28 @@
|
||||
# This is a CMake script that properly calls the PfxSign.ps1
|
||||
|
||||
if( DEFINED WINDOWS_CERTIFICATE_PASSWORD )
|
||||
set( ENV{WINDOWS_CERTIFICATE_PASSWORD} "${WINDOWS_CERTIFICATE_PASSWORD}" )
|
||||
endif()
|
||||
|
||||
if(DEFINED WINDOWS_CERTIFICATE)
|
||||
execute_process(
|
||||
COMMAND powershell
|
||||
-ExecutionPolicy Bypass
|
||||
-File ${PFX_SIGN_PS_LOCATION}
|
||||
-Directory ${CMAKE_INSTALL_PREFIX}
|
||||
-CertFile ${WINDOWS_CERTIFICATE}
|
||||
)
|
||||
elseif(DEFINED ENV{WINDOWS_CERTIFICATE})
|
||||
execute_process(
|
||||
COMMAND powershell
|
||||
-ExecutionPolicy Bypass
|
||||
-File ${PFX_SIGN_PS_LOCATION}
|
||||
-Directory ${CMAKE_INSTALL_PREFIX}
|
||||
)
|
||||
else()
|
||||
message(FATAL_ERROR [[
|
||||
Code signing is skipped, as certifacte is missing.
|
||||
Please, set the path to PFX file using -DWINDOWS_CERTIFICATE=...
|
||||
or set the environment variable WINDOWS_CERTIFICATE to base64 encoded PFX certifacte.
|
||||
]])
|
||||
endif()
|
108
scripts/build/windows/PfxSign.ps1
Normal file
108
scripts/build/windows/PfxSign.ps1
Normal file
@ -0,0 +1,108 @@
|
||||
# This script uses Set-AuthenticodeSignature to sign a file
|
||||
# or exe/dll/msi files in a directory using a pfx file.
|
||||
# If PFX file is not present, script expects a base64 encode certificate
|
||||
# in WINDOWS_CERTIFICATE environment variable.
|
||||
# Password can be passed using WINDOWS_CERTIFICATE_PASSWORD environmnet variable.
|
||||
# The script only signs previously unsigned files
|
||||
|
||||
[CmdletBinding()]
|
||||
param (
|
||||
# A path to the certificate file. If missing, env:WINDOWS_CERTIFICATE will be used.
|
||||
[string]$CertFile,
|
||||
# A password for the certificate. If missing, env:WINDOWS_CERTIFICATE_PASSWORD will be used.
|
||||
[string]$Password,
|
||||
# A file to sign.
|
||||
[string]$File,
|
||||
# A directory to sign.
|
||||
[string]$Directory
|
||||
)
|
||||
|
||||
# Configure the error behavior
|
||||
$ErrorActionPreference = "Stop"
|
||||
$PSDefaultParameterValues['*:ErrorAction']='Stop'
|
||||
|
||||
# Sign a file, if it was previously unsigned
|
||||
# We sign using SHA256, as we only support Windows 7+.
|
||||
function Set-FileSignature {
|
||||
param (
|
||||
[String]$InputFile,
|
||||
$pfxCert
|
||||
)
|
||||
if((Get-AuthenticodeSignature $InputFile).Status -ne [System.Management.Automation.SignatureStatus]::Valid) {
|
||||
Write-Host "Singning file $InputFile"
|
||||
|
||||
Set-AuthenticodeSignature `
|
||||
-FilePath $InputFile `
|
||||
-Certificate $pfxCert `
|
||||
-IncludeChain All `
|
||||
-TimestampServer 'http://timestamp.digicert.com' `
|
||||
-HashAlgorithm 'sha256' `
|
||||
-Force
|
||||
} else {
|
||||
Write-Host "Skipping file $InputFile as it is already signed"
|
||||
}
|
||||
}
|
||||
|
||||
# Sanity checks: only allow File or Directory
|
||||
if ($File -eq "" -and $Directory -eq "") {
|
||||
Write-Host "-File or -Directory should be provided"
|
||||
exit 1
|
||||
} elseif ($File -ne "" -and $Directory -ne "") {
|
||||
Write-Host "Only one of -File or -Directory should be provided"
|
||||
exit 1
|
||||
}
|
||||
|
||||
$cleanupPfx = $false
|
||||
|
||||
# Check, if we need to retrieve PFX from environment
|
||||
if($CertFile -eq "") {
|
||||
Write-Host "Trying to read certificate file from env:WINDOWS_CERTIFICATE"
|
||||
|
||||
if(Test-Path "env:WINDOWS_CERTIFICATE") {
|
||||
$CertFile = "cert.pfx"
|
||||
|
||||
[IO.File]::WriteAllBytes($CertFile, [System.Convert]::FromBase64String($env:WINDOWS_CERTIFICATE))
|
||||
|
||||
$cleanupPfx = $true
|
||||
} else {
|
||||
Write-Host "No certificate is provided"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Check, if we need to retrieve password from environment
|
||||
if($Password -eq "") {
|
||||
if (Test-Path "env:WINDOWS_CERTIFICATE_PASSWORD") {
|
||||
$Password = $env:WINDOWS_CERTIFICATE_PASSWORD
|
||||
}
|
||||
}
|
||||
|
||||
$pfx = $null
|
||||
|
||||
# Retrieve the actual certificate
|
||||
if($Password -ne "") {
|
||||
$securePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force
|
||||
$pfx = Get-PfxData -FilePath "$CertFile" -Password $securePassword
|
||||
} else {
|
||||
$pfx = Get-PfxData -FilePath "$CertFile"
|
||||
}
|
||||
|
||||
$pfxCert = $pfx.EndEntityCertificates[0]
|
||||
|
||||
# Perform the code signing.
|
||||
if ($File -ne "") {
|
||||
Set-FileSignature -InputFile $File -pfxCert $pfxCert
|
||||
} else {
|
||||
Get-ChildItem `
|
||||
-Path "$Directory" `
|
||||
-Include *.dll,*.exe,*.msi `
|
||||
-Recurse `
|
||||
-File | ForEach-Object {
|
||||
Set-FileSignature -InputFile $_.FullName -pfxCert $pfxCert
|
||||
}
|
||||
}
|
||||
|
||||
# Remove PFX file if it was created from environment.
|
||||
if($cleanupPfx) {
|
||||
Remove-Item "${CertFile}"
|
||||
}
|
@ -34,5 +34,34 @@ elif [[ "${AUDACITY_CMAKE_GENERATOR}" == Xcode* ]]; then
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ -n "${APPLE_CODESIGN_IDENTITY}" && "${OSTYPE}" == darwin* ]]; then
|
||||
cmake_args+=(
|
||||
-D APPLE_CODESIGN_IDENTITY="${APPLE_CODESIGN_IDENTITY}"
|
||||
-D audacity_perform_codesign=yes
|
||||
)
|
||||
|
||||
if [[ ${GIT_BRANCH} == release* ]]; then
|
||||
cmake_args+=(
|
||||
-D APPLE_NOTARIZATION_USER_NAME="${APPLE_NOTARIZATION_USER_NAME}"
|
||||
-D APPLE_NOTARIZATION_PASSWORD="${APPLE_NOTARIZATION_PASSWORD}"
|
||||
-D audacity_perform_notarization=yes
|
||||
)
|
||||
fi
|
||||
elif [[ -n "${WINDOWS_CERTIFICATE}" && "${OSTYPE}" == msys* ]]; then
|
||||
# Windows certificate will be used from the environment
|
||||
cmake_args+=(
|
||||
-D audacity_perform_codesign=yes
|
||||
)
|
||||
fi
|
||||
|
||||
if [[ ${GIT_BRANCH} == release* ]]; then
|
||||
cmake_args+=(
|
||||
-D audacity_package_manual=yes
|
||||
)
|
||||
fi
|
||||
|
||||
# Configure Audacity
|
||||
cmake "${cmake_args[@]}"
|
||||
|
||||
# Remove build directories and sources to reduce the cache size.
|
||||
conan remove "*" --src --builds --force
|
||||
|
@ -15,11 +15,10 @@ function gh_export()
|
||||
|
||||
repository_root="$(cd "$(dirname "${BASH_SOURCE}")/../.."; echo "${PWD}")"
|
||||
|
||||
gh_export CONAN_USER_HOME="${repository_root}/conan-home/"
|
||||
gh_export CONAN_USER_HOME_SHORT="${repository_root}/conan-home/short"
|
||||
|
||||
gh_export GIT_HASH="$(git show -s --format='%H')"
|
||||
gh_export GIT_HASH_SHORT="$(git show -s --format='%h')"
|
||||
|
||||
gh_export AUDACITY_BUILD_TYPE="RelWithDebInfo"
|
||||
gh_export AUDACITY_INSTALL_PREFIX="${repository_root}/build/install"
|
||||
|
||||
gh_export GIT_BRANCH=${GITHUB_REF##*/}
|
||||
|
@ -5,4 +5,12 @@
|
||||
set -euxo pipefail
|
||||
|
||||
cd build
|
||||
cpack -C "${AUDACITY_BUILD_TYPE}" --verbose
|
||||
|
||||
if [[ "${OSTYPE}" == msys* && ${GIT_BRANCH} == release* ]]; then # Windows
|
||||
cmake --build . --target innosetup --config "${AUDACITY_BUILD_TYPE}"
|
||||
else
|
||||
cpack -C "${AUDACITY_BUILD_TYPE}" --verbose
|
||||
fi
|
||||
|
||||
# Remove the temporary directory
|
||||
rm -Rf package/_CPack_Packages
|
||||
|
79
win/Inno_Setup_Wizard/BuildInnoSetupInstaller.cmake
Normal file
79
win/Inno_Setup_Wizard/BuildInnoSetupInstaller.cmake
Normal file
@ -0,0 +1,79 @@
|
||||
# This CMake script is invoked to build the InnoSetup installer for Audacity
|
||||
# Requiered parameters:
|
||||
# BUILD_DIR - should be set to CMAKE_BINARY_DIR by the caller
|
||||
# SOURCE_DIR - should be set to CMAKE_SOURCE_DIR by teh caller
|
||||
# OUTPUT_DIR - directory, where installer will be built
|
||||
# INNO_SETUP_COMPILER - InnoSetup compiler executable
|
||||
# BUILDING_64_BIT - Flag, that indicates that we are building a 64-bit installer
|
||||
# EMBED_MANUAL - embed a fresh copy of manual
|
||||
# SIGN - sign the installer
|
||||
# WINDOWS_CERTIFICATE - path to PFX file. If not present, env:WINDOWS_CERTIFICATE will be used
|
||||
# WINDOWS_CERTIFICATE_PASSWORD - password for the PFX file. If not present, env:WINDOWS_CERTIFICATE_PASSWORD will be used
|
||||
|
||||
if( BUILDING_64_BIT )
|
||||
set( INSTALLER_SUFFIX "x64" )
|
||||
set( INSTALLER_X64_MODE "ArchitecturesInstallIn64BitMode=x64")
|
||||
else()
|
||||
set( INSTALLER_SUFFIX "x86" )
|
||||
set( INSTALLER_X64_MODE "ArchitecturesInstallIn64BitMode=x64")
|
||||
endif()
|
||||
|
||||
if( SIGN )
|
||||
set( SIGN_TOOL "SignTool=byparam powershell -ExecutionPolicy Bypass -File \$q${SOURCE_DIR}/scripts/build/windows/PfxSign.ps1\$q -File $f")
|
||||
|
||||
if( WINDOWS_CERTIFICATE )
|
||||
string(APPEND SIGN_TOOL " -CertFile \$q${WINDOWS_CERTIFICATE}\$q")
|
||||
endif()
|
||||
|
||||
if( WINDOWS_CERTIFICATE_PASSWORD )
|
||||
message("Setting env:WINDOWS_CERTIFICATE_PASSWORD...")
|
||||
set( ENV{WINDOWS_CERTIFICATE_PASSWORD} "${WINDOWS_CERTIFICATE_PASSWORD}")
|
||||
endif()
|
||||
else()
|
||||
set( SIGN_TOOL )
|
||||
endif()
|
||||
|
||||
if( EMBED_MANUAL )
|
||||
set ( MANUAL [[Source: "Package\help\manual\*"; DestDir: "{app}\help\manual\"; Flags: ignoreversion recursesubdirs]])
|
||||
else()
|
||||
set( MANUAL )
|
||||
endif()
|
||||
|
||||
# Prepare the output directory
|
||||
|
||||
file(COPY "${SOURCE_DIR}/win/Inno_Setup_Wizard/" DESTINATION "${OUTPUT_DIR}")
|
||||
configure_file("${OUTPUT_DIR}/audacity.iss.in" "${OUTPUT_DIR}/audacity.iss")
|
||||
|
||||
# Copy additional files
|
||||
|
||||
file(COPY "${SOURCE_DIR}/presets" DESTINATION "${OUTPUT_DIR}/Additional")
|
||||
|
||||
file(COPY
|
||||
"${SOURCE_DIR}/LICENSE.txt"
|
||||
"${SOURCE_DIR}/README.txt"
|
||||
"${SOURCE_DIR}/win/audacity.ico"
|
||||
DESTINATION
|
||||
"${OUTPUT_DIR}/Additional"
|
||||
)
|
||||
|
||||
# "Install" prebuilt package
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
--install ${BUILD_DIR}
|
||||
--prefix "${OUTPUT_DIR}/Package"
|
||||
)
|
||||
|
||||
# Build the installer
|
||||
|
||||
execute_process(
|
||||
COMMAND
|
||||
${INNO_SETUP_COMPILER} /Sbyparam=$p "audacity.iss"
|
||||
WORKING_DIRECTORY
|
||||
${OUTPUT_DIR}
|
||||
)
|
||||
|
||||
# Emulate CPack behavior
|
||||
|
||||
file( COPY "${OUTPUT_DIR}/Output/" DESTINATION "${BUILD_DIR}/package" )
|
@ -1,5 +1,5 @@
|
||||
; Audacity: A Digital Audio Editor
|
||||
; Audacity(R) is copyright (c) 1999-2016 Audacity Team.
|
||||
; Audacity(R) is copyright (c) 1999-2021 Audacity Team.
|
||||
; License: GPL v2. See License.txt.
|
||||
;
|
||||
; audacity.iss
|
||||
@ -7,7 +7,8 @@
|
||||
;
|
||||
|
||||
; This requires that the ISS Preprocessor be installed
|
||||
#define AppExe "..\release\audacity.exe"
|
||||
|
||||
#define AppExe "Package\audacity.exe"
|
||||
#define AppMajor ""
|
||||
#define AppMinor ""
|
||||
#define AppRev ""
|
||||
@ -22,7 +23,7 @@ Filename: "{app}\unins*.*";
|
||||
|
||||
[Setup]
|
||||
; compiler-related directives
|
||||
OutputBaseFilename=audacity-win-{#AppVersion}
|
||||
OutputBaseFilename=audacity-win-{#AppVersion}-@INSTALLER_SUFFIX@
|
||||
|
||||
WizardImageFile=".\audacity_InnoWizardImage.bmp"
|
||||
WizardSmallImageFile=".\audacity_InnoWizardSmallImage.bmp"
|
||||
@ -43,8 +44,9 @@ AppPublisherURL=http://audacityteam.org
|
||||
AppSupportURL=http://audacityteam.org
|
||||
AppUpdatesURL=http://audacityteam.org
|
||||
ChangesAssociations=yes
|
||||
@INSTALLER_X64_MODE@
|
||||
|
||||
DefaultDirName={pf}\Audacity
|
||||
DefaultDirName={commonpf}\Audacity
|
||||
|
||||
VersionInfoProductName={#AppName}
|
||||
VersionInfoProductTextVersion={#GetFileProductVersion(AppExe)}
|
||||
@ -63,7 +65,7 @@ UninstallDisplayIcon="{app}\audacity.exe"
|
||||
|
||||
; No longer force them to accept the license, just display it. LicenseFile=..\LICENSE.txt
|
||||
InfoBeforeFile=".\audacity_InnoWizard_InfoBefore.rtf"
|
||||
InfoAfterFile=..\..\README.txt
|
||||
InfoAfterFile=Additional\README.txt
|
||||
|
||||
; We no longer produce new ANSI builds.
|
||||
; As we use Inno Setup (u), the Unicode version, to build this script,
|
||||
@ -72,7 +74,9 @@ InfoAfterFile=..\..\README.txt
|
||||
; MinVersion=4.0,5.0
|
||||
|
||||
; cosmetic-related directives
|
||||
SetupIconFile="..\audacity.ico"
|
||||
SetupIconFile="Additional\audacity.ico"
|
||||
|
||||
@SIGN_TOOL@
|
||||
|
||||
[INI]
|
||||
Filename: "{app}\FirstTime.ini"; Section: "FromInno"; Key: "ResetPrefs"; String: "1"; Tasks: resetPrefs;
|
||||
@ -89,47 +93,26 @@ Name: resetPrefs; Description: "{cm:ResetPrefs}"; Flags: unchecked
|
||||
Source: ".\FirstTimeModel.ini"; DestDir: "{app}"; DestName: "FirstTime.ini"; Permissions: users-modify
|
||||
|
||||
; Don't display in separate window, rather as InfoAfterFile. Source: "..\README.txt"; DestDir: "{app}"; Flags: ignoreversion isreadme
|
||||
Source: "..\..\README.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "Additional\README.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||
|
||||
Source: "..\..\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "Additional\LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "{#AppExe}"; DestDir: "{app}"; Flags: ignoreversion
|
||||
|
||||
; Manual, which should be got from the manual wiki using ..\scripts\mw2html_audacity\wiki2htm.bat
|
||||
Source: "..\..\help\manual\*"; DestDir: "{app}\help\manual\"; Flags: ignoreversion recursesubdirs
|
||||
@MANUAL@
|
||||
|
||||
Source: "..\..\presets\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
|
||||
Source: "Additional\presets\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs
|
||||
|
||||
; wxWidgets DLLs. Be specific (not *.dll) so we don't accidentally distribute avformat.dll, for example.
|
||||
; Don't use the WXWIN environment variable, because...
|
||||
; 1) Can't get the documented {%WXWIN|default dir} parsing to work.
|
||||
; 2) Need the DLL's in the release dir for testing, anyway.
|
||||
Source: "..\release\wxbase313u_xml_vc_custom.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\release\wxbase313u_vc_custom.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\release\wxmsw313u_core_vc_custom.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\release\wxmsw313u_html_vc_custom.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\release\wxmsw313u_qa_vc_custom.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
; We include all dll files from the Adacity root directory. This script is now executed as a part of CI build process,
|
||||
; so we controll which dll files are present in the directory.
|
||||
Source: "Package\*.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
|
||||
; MSVC runtime DLLs. Some users can't put these in the system dir, so just put them in the EXE dir.
|
||||
; It's legal, per http://www.fsf.org/licensing/licenses/gpl-faq.html#WindowsRuntimeAndGPL .
|
||||
; This is not an ideal solution, but should need the least tech support.
|
||||
; We'll know we have the right version, don't step on anybody else's older version, and
|
||||
; it's easy to make the zip (and they match better).
|
||||
; Copy the several required DLL's from
|
||||
; "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\redist\x86\Microsoft.VC120.CRT\"
|
||||
; or "C:\Program Files\Microsoft Visual Studio 12.0\VC\redist\x86\Microsoft.VC120.CRT\"
|
||||
; according to your system
|
||||
Source: "..\release\concrt140.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\release\msvcp140.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\release\msvcp140_1.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\release\msvcp140_2.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
Source: "..\release\vcruntime140.dll"; DestDir: "{app}"; Flags: ignoreversion
|
||||
|
||||
Source: "..\release\languages\*"; DestDir: "{app}\Languages\"; Flags: ignoreversion recursesubdirs
|
||||
Source: "Package\languages\*"; DestDir: "{app}\Languages\"; Flags: ignoreversion recursesubdirs
|
||||
; We don't ship all modules, so the next line is commented out
|
||||
; Source: "..\release\modules\*"; DestDir: "{app}\Modules\"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
|
||||
Source: "..\release\nyquist\*"; DestDir: "{app}\Nyquist\"; Flags: ignoreversion recursesubdirs
|
||||
Source: "..\release\plug-ins\*"; DestDir: "{app}\Plug-Ins\"; Flags: ignoreversion
|
||||
Source: "..\release\modules\mod-script-pipe.dll"; DestDir: "{app}\modules\"; Flags: ignoreversion
|
||||
; Source: "Package\modules\*"; DestDir: "{app}\Modules\"; Flags: ignoreversion recursesubdirs skipifsourcedoesntexist
|
||||
Source: "Package\nyquist\*"; DestDir: "{app}\Nyquist\"; Flags: ignoreversion recursesubdirs
|
||||
Source: "Package\plug-ins\*"; DestDir: "{app}\Plug-Ins\"; Flags: ignoreversion
|
||||
Source: "Package\modules\*"; DestDir: "{app}\modules\"; Flags: ignoreversion recursesubdirs
|
||||
|
||||
[Icons]
|
||||
Name: "{commonprograms}\Audacity"; Filename: "{app}\audacity.exe"
|
||||
@ -213,8 +196,8 @@ Filename: "{app}\audacity.exe"; Description: "{cm:LaunchProgram,Audacity}"; Flag
|
||||
; NOTE: "0" in locale name will be translated to "@" when read by Audacity.
|
||||
|
||||
; Create subdirectories where we'll store the unofficial and dummy translation files
|
||||
{#expr Exec("cmd", "/c mkdir """ + CompilerPath + "Languages\dummy""", , , SW_HIDE), \
|
||||
Exec("cmd", "/c mkdir """ + CompilerPath + "Languages\unofficial""", , , SW_HIDE)}
|
||||
{#expr Exec("cmd", "/c mkdir """ + "Languages\dummy""", '.\', , SW_HIDE), \
|
||||
Exec("cmd", "/c mkdir """ + "Languages\unofficial""", '.\', , SW_HIDE)}
|
||||
|
||||
; Download Additional Inno Setup translations from:
|
||||
;
|
||||
@ -227,28 +210,28 @@ Filename: "{app}\audacity.exe"; Description: "{cm:LaunchProgram,Audacity}"; Flag
|
||||
; the Inno Setup Languages folder if it hasn't already been downloaded.
|
||||
; (Sorry, it's not a quick process, but it only happens once.)
|
||||
#define Get(URL) \
|
||||
Local[0] = "Languages\unofficial\" + Copy(URL, RPos("/", URL) + 1), \
|
||||
Local[1] = (FileExists(CompilerPath + Local[0]) \
|
||||
Local[0] = ".\Languages\unofficial\" + Copy(URL, RPos("/", URL) + 1), \
|
||||
Local[1] = (FileExists(Local[0]) \
|
||||
? "alreadyexists" \
|
||||
: Exec("powershell", "echo 'Downloading: " + URL + "'; $wc = new-object System.Net.WebClient; $wc.DownloadFile('" + URLBase + URL + "', '" + Local[0] + "')", , , SW_NORMAL)), \
|
||||
"compiler:" + Local[0]
|
||||
: Exec("powershell", "echo 'Downloading: " + URL + "'; $wc = new-object System.Net.WebClient; $wc.DownloadFile('" + URLBase + URL + "', '" + Local[0] + "')", '.\', , SW_NORMAL)), \
|
||||
Local[0]
|
||||
|
||||
; This macro will define a dummy translation based on the Defaults.isl
|
||||
#define Dummy(NAME, ID) \
|
||||
Local[0] = "Languages\dummy\", \
|
||||
Local[0] = ".\Languages\dummy\", \
|
||||
Local[1] = Local[0] + NAME + ".isl", \
|
||||
Local[2] = CompilerPath + Local[1], \
|
||||
Local[2] = SourcePath + Local[1], \
|
||||
Local[3] = (FileExists(Local[2]) \
|
||||
? "alreadyexists" \
|
||||
: (CopyFile(CompilerPath + "Default.isl", Local[2]), \
|
||||
WriteIni(Local[2], "LangOptions", "LanguageName", NAME), \
|
||||
WriteIni(Local[2], "LangOptions", "LanguageID", "$" + ID))), \
|
||||
"compiler:" + Local[1]
|
||||
Local[1]
|
||||
|
||||
Name: "af"; MessagesFile: "{#Get('Afrikaans.isl')}"
|
||||
Name: "ar"; MessagesFile: "{#Get('Arabic.isl')}"
|
||||
Name: "be"; MessagesFile: "{#Get('Belarusian.isl')}"
|
||||
Name: "bg"; MessagesFile: "{#Get('Bulgarian.isl')}"
|
||||
Name: "bg"; MessagesFile: "compiler:Languages\Bulgarian.isl"
|
||||
Name: "bn"; MessagesFile: "{#Get('Bengali.islu')}"
|
||||
Name: "bs"; MessagesFile: "{#Get('Bosnian.isl')}"
|
||||
Name: "ca"; MessagesFile: "compiler:Languages\Catalan.isl"
|
||||
@ -258,7 +241,7 @@ Name: "cs"; MessagesFile: "compiler:Languages\Czech.isl"
|
||||
Name: "cy"; MessagesFile: "{#Dummy('Welsh', '0452')}"
|
||||
Name: "da"; MessagesFile: "compiler:Languages\Danish.isl"
|
||||
Name: "de"; MessagesFile: "compiler:Languages\German.isl"
|
||||
Name: "el"; MessagesFile: "compiler:Languages\Greek.isl"
|
||||
Name: "el"; MessagesFile: "{#Get('Greek.isl')}"
|
||||
Name: "en"; MessagesFile: "compiler:Default.isl"
|
||||
Name: "es"; MessagesFile: "compiler:Languages\Spanish.isl"
|
||||
Name: "eu"; MessagesFile: "{#Get('Basque.isl')}"
|
||||
@ -270,19 +253,19 @@ Name: "gl"; MessagesFile: "{#Get('Galician.isl')}"
|
||||
Name: "he"; MessagesFile: "compiler:Languages\Hebrew.isl"
|
||||
Name: "hi"; MessagesFile: "{#Get('Hindi.islu')}"
|
||||
Name: "hr"; MessagesFile: "{#Get('Croatian.isl')}"
|
||||
Name: "hu"; MessagesFile: "compiler:Languages\Hungarian.isl"
|
||||
Name: "hy"; MessagesFile: "compiler:Languages\Armenian.islu"
|
||||
Name: "hu"; MessagesFile: "{#Get('Hungarian.isl')}"
|
||||
Name: "hy"; MessagesFile: "compiler:Languages\Armenian.isl"
|
||||
Name: "id"; MessagesFile: "{#Get('Indonesian.isl')}"
|
||||
Name: "it"; MessagesFile: "compiler:Languages\Italian.isl"
|
||||
Name: "ja"; MessagesFile: "compiler:Languages\Japanese.isl"
|
||||
Name: "ka"; MessagesFile: "{#Get('Georgian.islu')}"
|
||||
Name: "ka"; MessagesFile: "{#Get('Georgian.isl')}"
|
||||
Name: "km"; MessagesFile: "{#Dummy('Khmer', '0409')}"
|
||||
Name: "ko"; MessagesFile: "{#Dummy('Korean', '0412')}"
|
||||
Name: "lt"; MessagesFile: "{#Get('Lithuanian.isl')}"
|
||||
Name: "mk"; MessagesFile: "{#Get('Macedonian.isl')}"
|
||||
Name: "my"; MessagesFile: "{#Dummy('Burmese', '0409')}"
|
||||
Name: "nb"; MessagesFile: "compiler:Languages\Norwegian.isl"
|
||||
;Name: "ne"; MessagesFile: "compiler:Languages\Nepali.islu"
|
||||
Name: "ne"; MessagesFile: "{#Get('Nepali.islu')}"
|
||||
Name: "nl"; MessagesFile: "compiler:Languages\Dutch.isl"
|
||||
Name: "oc"; MessagesFile: "{#Get('Occitan.isl')}"
|
||||
Name: "pl"; MessagesFile: "compiler:Languages\Polish.isl"
|
||||
@ -290,16 +273,16 @@ Name: "pt_PT"; MessagesFile: "compiler:Languages\Portuguese.isl"
|
||||
Name: "pt_BR"; MessagesFile: "compiler:Languages\BrazilianPortuguese.isl"
|
||||
Name: "ro"; MessagesFile: "{#Get('Romanian.isl')}"
|
||||
Name: "ru"; MessagesFile: "compiler:Languages\Russian.isl"
|
||||
Name: "sk"; MessagesFile: "{#Get('Slovak.isl')}"
|
||||
Name: "sk"; MessagesFile: "compiler:Languages\Slovak.isl"
|
||||
Name: "sl"; MessagesFile: "compiler:Languages\Slovenian.isl"
|
||||
Name: "sr_RS"; MessagesFile: "compiler:Languages\SerbianCyrillic.isl"
|
||||
Name: "sr_RS0latin"; MessagesFile: "compiler:Languages\SerbianLatin.isl"
|
||||
Name: "sr_RS"; MessagesFile: "{#Get('SerbianCyrillic.isl')}"
|
||||
Name: "sr_RS0latin"; MessagesFile: "{#Get('SerbianLatin.isl')}"
|
||||
Name: "sv"; MessagesFile: "{#Get('Swedish.isl')}"
|
||||
Name: "ta"; MessagesFile: "{#Dummy('Tamil', '0449')}"
|
||||
Name: "tg"; MessagesFile: "{#Dummy('Tajik', '0428')}"
|
||||
Name: "tr"; MessagesFile: "compiler:Languages\Turkish.isl"
|
||||
Name: "uk"; MessagesFile: "compiler:Languages\Ukrainian.isl"
|
||||
;Name: "vi"; MessagesFile: "{#Get('Vietnamese.islu')}"
|
||||
Name: "vi"; MessagesFile: "{#Get('Vietnamese.isl')}"
|
||||
Name: "zh_CN"; MessagesFile: "{#Get('ChineseSimplified.isl')}"
|
||||
Name: "zh_TW"; MessagesFile: "{#Get('ChineseTraditional.isl')}"
|
||||
|
||||
@ -361,7 +344,7 @@ lt.ResetPrefs=Reset Preferences
|
||||
mk.ResetPrefs=Reset Preferences
|
||||
my.ResetPrefs=Reset Preferences
|
||||
nb.ResetPrefs=Reset Preferences
|
||||
;ne.ResetPrefs=Reset Preferences
|
||||
ne.ResetPrefs=Reset Preferences
|
||||
nl.ResetPrefs=Voorkeuren herstellen?
|
||||
oc.ResetPrefs=Reset Preferences
|
||||
pl.ResetPrefs=Zresetować ustawienia?
|
Loading…
x
Reference in New Issue
Block a user