configure.ac | 11 solenv/bin/modules/installer/windows/mergemodule.pm | 252 ++++++++------------ solenv/bin/modules/installer/windows/update.pm | 22 - 3 files changed, 118 insertions(+), 167 deletions(-)
New commits: commit 1cabb20fad8303d16e25957ee245970f37ad2f82 Author: Christian Lohmaier <lohmaier+libreoff...@googlemail.com> AuthorDate: Fri Dec 6 12:22:30 2024 +0100 Commit: Christian Lohmaier <lohmaier+libreoff...@googlemail.com> CommitDate: Thu Dec 12 15:29:30 2024 +0100 replace a couple manual calls to cygpath with PathFormat this fixes using the MSM merge modules in the wsl-as-helper case and avoids "cygpath not found" error lines when doing the compiler tests when running configure. Also capture and report the output of failed msidb calls in the isntaller code and simplify the path-mangling to windows-style Change-Id: I6877edda72959ab592e686d662b1344487e6313e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/177966 Reviewed-by: Christian Lohmaier <lohmaier+libreoff...@googlemail.com> Tested-by: Jenkins diff --git a/configure.ac b/configure.ac index db7a8e901626..fb7369f6e806 100644 --- a/configure.ac +++ b/configure.ac @@ -4435,10 +4435,10 @@ test_cl_exe() AC_MSG_ERROR([No mspdb${mspdbnum}.dll in $2, Visual Studio installation broken?]) fi - # The compiles has to find its shared libraries + # The compiler has to find its shared libraries OLD_PATH="$PATH" - TEMP_PATH=`cygpath -d "$2"` - PATH="`cygpath -u "$TEMP_PATH"`:$PATH" + PathFormat "$2" + PATH="$formatted_path_unix:$PATH" if ! "$CL_EXE_PATH" -? </dev/null >/dev/null 2>&1; then AC_MSG_ERROR([no compiler (cl.exe) in $2]) @@ -7101,7 +7101,8 @@ find_msms() esac if test -n "$msmdir"; then - msmdir=`cygpath -m "$msmdir"` + PathFormat "$msmdir" + msmdir="$formatted_path" AC_MSG_RESULT([$msmdir]) else if test "$ENABLE_RELEASE_BUILD" = "TRUE" ; then @@ -8959,7 +8960,7 @@ if test $_os = "WINNT"; then if test "$i" = msi; then find_msms "$with_redist" if test -n "$msmdir"; then - MSM_PATH=`win_short_path_for_make "$msmdir"` + MSM_PATH=`win_short_path_for_make "$msmdir"`/ SCPDEFS="$SCPDEFS -DWITH_VC_REDIST=$with_redist" fi break diff --git a/solenv/bin/modules/installer/windows/mergemodule.pm b/solenv/bin/modules/installer/windows/mergemodule.pm index f737c2b905c6..2fc8a98c0211 100644 --- a/solenv/bin/modules/installer/windows/mergemodule.pm +++ b/solenv/bin/modules/installer/windows/mergemodule.pm @@ -57,7 +57,11 @@ sub merge_mergemodules_into_msi_database my $cabinetfile = "MergeModule.CABinet"; # the name of each cabinet file in a merge file my $infoline = ""; my $systemcall = ""; + my $systemcall_output = ""; my $returnvalue = ""; + # in cygwin the * glob needs to be escaped when passing it to msidb + my $globescape = ""; + $globescape = "\" if ( $^O =~ /cygwin/i ); # 1. Analyzing the MergeModule (has only to be done once) # a. -> Extracting cabinet file: msidb.exe -d <msmfile> -x MergeModule.CABinet @@ -103,16 +107,14 @@ sub merge_mergemodules_into_msi_database # remove an existing cabinet file if ( -f $cabinetfile ) { unlink($cabinetfile); } - # exclude cabinet file + # export cabinet file $systemcall = $msidb . " -d " . $filename . " -x " . $cabinetfile; - $returnvalue = system($systemcall); - - $infoline = "Systemcall: $systemcall "; - push( @installer::globals::logfileinfo, $infoline); + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; if ($returnvalue) { - $infoline = "ERROR: Could not execute $systemcall ! "; + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; push( @installer::globals::logfileinfo, $infoline); installer::exiter::exit_program("ERROR: Could not extract cabinet file from merge file: $completedest !", "merge_mergemodules_into_msi_database"); } @@ -122,34 +124,25 @@ sub merge_mergemodules_into_msi_database push( @installer::globals::logfileinfo, $infoline); } - # exclude tables from mergefile + # export tables from mergefile # Attention: All listed tables have to exist in the database. If they not exist, an error window pops up # and the return value of msidb.exe is not zero. The error window makes it impossible to check the existence # of a table with the help of the return value. # Solution: Export of all tables by using "*" . Some tables must exist (File Component Directory), other # tables do not need to exist (MsiAssembly). - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - my $localworkdir = $workdir; - $localworkdir =~ s/\//\\/g; - $systemcall = $msidb . " -d " . $filename . " -f " . $localworkdir . " -e \\*"; - } - else - { - $systemcall = $msidb . " -d " . $filename . " -f " . $workdir . " -e \*"; - } - - $returnvalue = system($systemcall); + $systemcall = $msidb . " -d " . $filename . " -f " . $workdir . " -e $globescape*"; + # msidb.exe really wants backslashes + $systemcall =~ s/\//\\/g; - $infoline = "Systemcall: $systemcall "; - push( @installer::globals::logfileinfo, $infoline); + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; if ($returnvalue) { - $infoline = "ERROR: Could not execute $systemcall ! "; + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; push( @installer::globals::logfileinfo, $infoline); - installer::exiter::exit_program("ERROR: Could not exclude tables from merge file: $completedest !", "merge_mergemodules_into_msi_database"); + installer::exiter::exit_program("ERROR: Could not export tables from merge file: $completedest !", "merge_mergemodules_into_msi_database"); } else { @@ -249,39 +242,42 @@ sub merge_mergemodules_into_msi_database if ( ! -f $completeremovedest ) { installer::exiter::exit_program("ERROR: msm file not found: $completeremovedest !", "merge_mergemodules_into_msi_database"); } # Unpacking msm file - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - my $localcompleteremovedest = $completeremovedest; - my $localremoveworkdir = $removeworkdir; - $localcompleteremovedest =~ s/\//\\/g; - $localremoveworkdir =~ s/\//\\/g; - $systemcall = $msidb . " -d " . $localcompleteremovedest . " -f " . $localremoveworkdir . " -e \\*"; - } - else - { - $systemcall = $msidb . " -d " . $completeremovedest . " -f " . $removeworkdir . " -e \*"; + $systemcall = $msidb . " -d " . $completeremovedest . " -f " . $removeworkdir . " -e $globescape*"; + # msidb.exe really wants backslashes + $systemcall =~ s/\//\\/g; + + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; + + if ($returnvalue) { + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; + push( @installer::globals::logfileinfo, $infoline); + installer::exiter::exit_program("ERROR: $systemcall failed!", "merge_mergemodules_into_msi_database"); + } else { + $infoline = "Success: Executed $systemcall successfully! "; + push(@installer::globals::logfileinfo, $infoline); } - $returnvalue = system($systemcall); - my $idtfilename = $removeworkdir . $installer::globals::separator . "File.idt"; if ( -f $idtfilename ) { unlink $idtfilename; } unlink $completeremovedest; # Packing msm file without "File.idt" - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - my $localcompleteremovedest = $completeremovedest; - my $localremoveworkdir = $removeworkdir; - $localcompleteremovedest =~ s/\//\\/g; - $localremoveworkdir =~ s/\//\\/g; - $systemcall = $msidb . " -c -d " . $localcompleteremovedest . " -f " . $localremoveworkdir . " -i \\*"; - } - else - { - $systemcall = $msidb . " -c -d " . $completeremovedest . " -f " . $removeworkdir . " -i \*"; + $systemcall = $msidb . " -c -d " . $completeremovedest . " -f " . $removeworkdir . " -i $globescape*"; + # msidb.exe really wants backslashes + $systemcall =~ s/\//\\/g; + + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; + + if ($returnvalue) { + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; + push( @installer::globals::logfileinfo, $infoline); + installer::exiter::exit_program("ERROR: $systemcall failed!", "merge_mergemodules_into_msi_database"); + } else { + $infoline = "Success: Executed $systemcall successfully! "; + push( @installer::globals::logfileinfo, $infoline); } - $returnvalue = system($systemcall); # Using this msm file for merging if ( -f $completeremovedest ) { $completedest = $completeremovedest; } @@ -360,26 +356,16 @@ sub merge_mergemodules_into_msi_database installer::logger::include_timestamp_into_logfile(" Performance Info: Before merging database"); - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - my $localmergemodulepath = $mergemodulehash->{'mergefilepath'}; - my $localmsifilename = $msifilename; - $localmergemodulepath =~ s/\//\\/g; - $localmsifilename =~ s/\//\\/g; - $systemcall = $msidb . " -d " . $localmsifilename . " -m " . $localmergemodulepath; - } - else - { - $systemcall = $msidb . " -d " . $msifilename . " -m " . $mergemodulehash->{'mergefilepath'}; - } - $returnvalue = system($systemcall); + $systemcall = $msidb . " -d " . $msifilename . " -m " . $mergemodulehash->{'mergefilepath'}; + # msidb.exe really wants backslashes + $systemcall =~ s/\//\\/g; - $infoline = "Systemcall: $systemcall "; - push( @installer::globals::logfileinfo, $infoline); + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; if ($returnvalue) { - $infoline = "ERROR: Could not execute $systemcall . Returnvalue: $returnvalue! "; + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; push( @installer::globals::logfileinfo, $infoline); installer::exiter::exit_program("Could not merge msm file into database: $mergemodulehash->{'mergefilepath'} $infoline", "merge_mergemodules_into_msi_database"); } @@ -412,26 +398,16 @@ sub merge_mergemodules_into_msi_database if ( ( $mergemodulehash->{'componentcondition'} ) || ( $mergemodulehash->{'attributes_add'} ) ) { $workingtables = $workingtables . " Component"; } # Table "Feature" has to be exported, but it is not necessary to import it. - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - my $localmsifilename = $msifilename; - my $localworkdir = $workdir; - $localmsifilename =~ s/\//\\/g; - $localworkdir =~ s/\//\\/g; - $systemcall = $msidb . " -d " . $localmsifilename . " -f " . $localworkdir . " -e " . "Feature " . $workingtables; - } - else - { - $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $workingtables; - } - $returnvalue = system($systemcall); + $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $workingtables; + # msidb.exe really wants backslashes + $systemcall =~ s/\//\\/g; - $infoline = "Systemcall: $systemcall "; - push( @installer::globals::logfileinfo, $infoline); + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; if ($returnvalue) { - $infoline = "ERROR: Could not execute $systemcall ! "; + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; push( @installer::globals::logfileinfo, $infoline); installer::exiter::exit_program("ERROR: Could not exclude tables from msi database: $msifilename !", "merge_mergemodules_into_msi_database"); } @@ -489,34 +465,39 @@ sub merge_mergemodules_into_msi_database my $moduleexecutetables = "ModuleInstallExecuteSequence ModuleAdminExecuteSequence ModuleAdvtExecuteSequence"; # new tables my $executetables = "InstallExecuteSequence InstallUISequence AdminExecuteSequence AdvtExecuteSequence"; # tables to be merged + $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $moduleexecutetables; + # msidb.exe really wants backslashes + $systemcall =~ s/\//\\/g; - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - my $localmsifilename = $msifilename; - my $localworkdir = $workdir; - $localmsifilename =~ s/\//\\/g; - $localworkdir =~ s/\//\\/g; - $systemcall = $msidb . " -d " . $localmsifilename . " -f " . $localworkdir . " -e " . "Feature " . $moduleexecutetables; - } - else - { - $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $moduleexecutetables; - } - $returnvalue = system($systemcall); - - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - my $localmsifilename = $msifilename; - my $localworkdir = $workdir; - $localmsifilename =~ s/\//\\/g; - $localworkdir =~ s/\//\\/g; - $systemcall = $msidb . " -d " . $localmsifilename . " -f " . $localworkdir . " -e " . "Feature " . $executetables; + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; + + if ($returnvalue) { + # the exit status of this command had not been checked in the past, it fails because + # there is no ModuleAdminExecuteSequence table + $infoline = "IGNORING: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; + push( @installer::globals::logfileinfo, $infoline); + #installer::exiter::exit_program("ERROR: $infoline", "merge_mergemodules_into_msi_database"); + } else { + $infoline = "Success: Executed $systemcall successfully "; + push( @installer::globals::logfileinfo, $infoline); } - else - { - $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $executetables; + + $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -e " . "Feature " . $executetables; + # msidb.exe really wants backslashes + $systemcall =~ s/\//\\/g; + + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; + + if ($returnvalue) { + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; + push( @installer::globals::logfileinfo, $infoline); + installer::exiter::exit_program("$infoline", "merge_mergemodules_into_msi_database"); + } else { + $infoline = "Success: Executed $systemcall successfully "; + push( @installer::globals::logfileinfo, $infoline); } - $returnvalue = system($systemcall); # Using 8+3 table names, that are used, when tables are integrated into database. The export of tables # creates idt-files, that have long names. @@ -554,32 +535,16 @@ sub merge_mergemodules_into_msi_database installer::logger::include_timestamp_into_logfile(" Performance Info: Before including tables"); - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - my $localmsifilename = $msifilename; - my $localworkdir = $workdir; - $localmsifilename =~ s/\//\\/g; - $localworkdir =~ s/\//\\/g; - foreach my $table (split / /, $workingtables . ' ' . $executetables) { - $systemcall = $msidb . " -d " . $localmsifilename . " -f " . $localworkdir . " -i " . $table; - my $retval = system($systemcall); - $infoline = "Systemcall returned $retval: $systemcall "; - push( @installer::globals::logfileinfo, $infoline); - $returnvalue |= $retval; - } - } - else - { - $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -i " . $workingtables. " " . $executetables; - $returnvalue = system($systemcall); - $infoline = "Systemcall: $systemcall "; - push( @installer::globals::logfileinfo, $infoline); + $systemcall = $msidb . " -d " . $msifilename . " -f " . $workdir . " -i " . $workingtables. " " . $executetables; + # msidb.exe really wants backslashes + $systemcall =~ s/\//\\/g; - } + $systemcall_output = `$systemcall`; + $returnvalue = $? >> 8; if ($returnvalue) { - $infoline = "ERROR: Could not execute $systemcall ! "; + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; push( @installer::globals::logfileinfo, $infoline); installer::exiter::exit_program("ERROR: Could not include tables into msi database: $msifilename !", "merge_mergemodules_into_msi_database"); } @@ -1087,6 +1052,9 @@ sub change_file_table my $infoline = "Changing content of table \"File\" "; push( @installer::globals::logfileinfo, $infoline); + my $globescape = ""; + $globescape = "\" if ( $^O =~ /cygwin/i ); + my $idtfilename = "File.idt"; if ( ! -f $idtfilename ) { installer::exiter::exit_program("ERROR: Could not find file \"$idtfilename\" in \"$workdir\" !", "change_file_table"); } @@ -1107,6 +1075,8 @@ sub change_file_table my $empty = ""; my $unpackdir = installer::systemactions::create_directories("cab", \$empty); + $unpackdir = qx(cygpath -m "$unpackdir"); + chomp $unpackdir; push(@installer::globals::removedirs, $unpackdir); $unpackdir = $unpackdir . $installer::globals::separator . $mergemodulegid; @@ -1133,35 +1103,21 @@ sub change_file_table push( @installer::globals::logfileinfo, $infoline); # Avoid the Cygwin expand command - my $expandfile = "expand.exe"; # Has to be in the path - if ( $^O =~ /cygwin/i ) { - $expandfile = qx(cygpath -u "$ENV{WINDIR}"/System32/expand.exe); - chomp $expandfile; - } + my $expandfile = qx(cygpath -m "$ENV{WINDIR}"/System32/expand.exe); + chomp $expandfile; my $cabfilename = "MergeModule.CABinet"; - my $systemcall = ""; - if ( $^O =~ /cygwin/i ) { - my $localunpackdir = qx(cygpath -m "$unpackdir"); - chomp $localunpackdir; - $systemcall = $expandfile . " " . $cabfilename . " -F:\\* " . $localunpackdir; - } - else - { - $systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $unpackdir . " 2\>\&1"; - } - - my $returnvalue = system($systemcall); + my $systemcall = $expandfile . " " . $cabfilename . " -F:$globescape* " . $unpackdir . " 2\>\&1"; - $infoline = "Systemcall: $systemcall "; - push( @installer::globals::logfileinfo, $infoline); + my $systemcall_output = `$systemcall`; + my $returnvalue = $? >> 8; if ($returnvalue) { - $infoline = "ERROR: Could not execute $systemcall ! "; + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; push( @installer::globals::logfileinfo, $infoline); - installer::exiter::exit_program("ERROR: Could not extract cabinet file: $mergemodulehash->{'cabinetfile'} !", "change_file_table"); + installer::exiter::exit_program("ERROR: extracting $cabfilename failed using $systemcall", "change_file_table"); } else { diff --git a/solenv/bin/modules/installer/windows/update.pm b/solenv/bin/modules/installer/windows/update.pm index ad89d4065b14..5d1cfed619e0 100644 --- a/solenv/bin/modules/installer/windows/update.pm +++ b/solenv/bin/modules/installer/windows/update.pm @@ -41,28 +41,22 @@ sub extract_all_tables_from_msidatabase my $systemcall = ""; my $returnvalue = ""; my $extraslash = ""; # Has to be set for non-ActiveState perl + $extraslash = "\" if ( $^O =~ /cygwin/i ); # Export of all tables by using "*" - - if ( $^O =~ /cygwin/i ) { - # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) - $fulldatabasepath =~ s/\//\\/g; - $workdir =~ s/\//\\/g; - $extraslash = "\"; - } - if ( $^O =~ /linux/i) { - $extraslash = "\"; - } - $systemcall = $msidb . " -d " . $fulldatabasepath . " -f " . $workdir . " -e " . $extraslash . "*"; - $returnvalue = system($systemcall); + # msidb.exe really wants backslashes. (And double escaping because system() expands the string.) + $systemcall =~ s/\//\\/g; + + my $systemcall_output = `$systemcall`; + my $returnvalue = $? >> 8; $infoline = "Systemcall: $systemcall "; push( @installer::globals::logfileinfo, $infoline); if ($returnvalue) { - $infoline = "ERROR: Could not execute $systemcall ! "; + $infoline = "ERROR: Could not execute $systemcall - returncode: $returnvalue - output: $systemcall_output "; push( @installer::globals::logfileinfo, $infoline); installer::exiter::exit_program("ERROR: Could not exclude tables from msi database: $fulldatabasepath !", "extract_all_tables_from_msidatabase"); } @@ -456,7 +450,7 @@ sub readmergedatabase my $filename = $mergemodule->{'Name'}; my $mergefile = $ENV{'MSM_PATH'} . $filename; - if ( ! -f $mergefile ) { installer::exiter::exit_program("ERROR: msm file not found: $filename !", "readmergedatabase"); } + if ( ! -f $mergefile ) { installer::exiter::exit_program("ERROR: msm file not found: $mergefile !", "readmergedatabase"); } my $completesource = $mergefile; my $mergegid = $mergemodule->{'gid'};