diff --git a/.hgtags b/.hgtags
index 1ff18695ce..9bb5c8766b 100755
--- a/.hgtags
+++ b/.hgtags
@@ -37,6 +37,7 @@ ab632018105ccfdf8a9e5ea1a8302badd58b686e Firestorm_5.0.1_Release
54c17cd8cbb3fe79cd41091b1548b13a263a1b58 Firestorm_5.0.11_Release
6eb3eb572c053c7c7b83287b2a57dbb57442a011 Firestorm_5.1.7_Release
8888a131acad19c49fcff1ad2cf75c54c8a41bb8 Firestorm_6.0.1_Beta
+ba5e1592f3a79317a3ebac441ee5946a81b97fab Firestorm_6.0.2_Release
bb38ff1a763738609e1b3cada6d15fa61e5e84b9 2.1.1-release
003dd9461bfa479049afcc34545ab3431b147c7c v2start
52d96ad3d39be29147c5b2181b3bb46af6164f0e alpha-3
@@ -581,5 +582,7 @@ ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release
23ea0fe36fadf009a60c080392ce80e4bf8af8d9 5.1.8-release
52422540bfe54b71155aa455360bee6e3ef1fd96 5.1.9-release
+1cfa567caf5088ae299271be08cc2d9f0801ff6a pre-Poseidon
821edfcd14919c0e95c590866171c61fb57e8623 6.0.0-release
21b7604680ef6b6ea67f8bebaaa588d6e263bdc1 6.0.1-release
+a3143db58a0f6b005232bf9018e7fef17ff9ec90 6.1.0-release
diff --git a/README_BUILD_FIRESTORM_LINUX.txt b/README_BUILD_FIRESTORM_LINUX.txt
index 5cc83248da..4a8595363e 100755
--- a/README_BUILD_FIRESTORM_LINUX.txt
+++ b/README_BUILD_FIRESTORM_LINUX.txt
@@ -1,7 +1,5 @@
First, make sure gcc-4.7 and g++-4.7 are installed.
-32bit build platforms are better tested at this point and strongly recommended.
-
Ensure you can build a stock viewer-development try as described in the SL wiki. Before asking for any help
compiling Firestorm, make sure you can build viewer-development first. If you try and skip this step, you may
receive much less help. http://wiki.secondlife.com/wiki/Compiling_the_viewer_(Linux)
diff --git a/autobuild.xml b/autobuild.xml
index 8cde2f9d8b..7914023e2a 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -3,6 +3,36 @@
windows
@@ -4001,6 +3909,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
ReleaseFS
+ build
+
+ command
+ bash
+ options
+
+ ../scripts/configure_firestorm.sh
+ --build
+ --version
+ --opensim
+
+
configure
command
@@ -4018,6 +3938,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
ReleaseFS_AVX
+ build
+
+ command
+ bash
+ options
+
+ ../scripts/configure_firestorm.sh
+ --build
+ --version
+ --opensim
+ --avx
+
+
configure
command
@@ -4036,6 +3969,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
ReleaseFS_AVX2
+ build
+
+ command
+ bash
+ options
+
+ ../scripts/configure_firestorm.sh
+ --build
+ --version
+ --opensim
+ --avx2
+
+
configure
command
@@ -4054,6 +4000,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
ReleaseFS_open
+ build
+
+ command
+ bash
+ options
+
+ ../scripts/configure_firestorm.sh
+ --build
+ --version
+ --opensim
+
+
configure
command
@@ -4071,6 +4029,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
RelWithDebInfoFS
+ build
+
+ command
+ bash
+ options
+
+ ../scripts/configure_firestorm.sh
+ --btype RelWithDebInfo
+ --build
+ --version
+ --opensim
+
+
configure
command
@@ -4089,6 +4060,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
RelWithDebInfoFS_open
+ build
+
+ command
+ bash
+ options
+
+ ../scripts/configure_firestorm.sh
+ --btype RelWithDebInfo
+ --build
+ --version
+ --opensim
+
+
configure
command
@@ -4241,14 +4225,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- command
- ../scripts/configure_firestorm.sh
options
- --build
--package
--platform darwin
- --btype RelWithDebInfo
--fmodstudio
--kdu
@@ -4259,7 +4239,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
--platform darwin
--package
- --btype RelWithDebInfo
--fmodstudio
--kdu
@@ -4273,14 +4252,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- command
- ../scripts/configure_firestorm.sh
options
- --build
--package
--platform darwin
- --btype RelWithDebInfo
configure
@@ -4289,7 +4264,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
--platform darwin
--package
- --btype RelWithDebInfo
name
@@ -4299,11 +4273,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- command
- ../scripts/configure_firestorm.sh
options
- --build
--platform darwin
--fmodstudio
--kdu
@@ -4457,19 +4428,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
name
default
-
RelWithDebInfoFS
build
- command
- ../scripts/configure_firestorm.sh
options
- --build
- --platform linux32
+ --platform linux
--package
- --btype RelWithDebInfo
configure
@@ -4478,9 +4444,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
--kdu
--fmodstudio
- --platform linux32
+ --platform linux
--package
- --btype RelWithDebInfo
default
@@ -4492,23 +4457,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- command
- ../scripts/configure_firestorm.sh
options
- --build
- --platform linux32
+ --platform linux
--package
- --btype RelWithDebInfo
configure
options
- --platform linux32
+ --platform linux
--package
- --btype RelWithDebInfo
name
@@ -4518,12 +4478,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- command
- ../scripts/configure_firestorm.sh
options
--build
- --platform linux32
+ --platform linux
configure
@@ -4532,7 +4490,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
--kdu
--fmodstudio
- --platform linux32
+ --platform linux
name
@@ -4542,12 +4500,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- command
- ../scripts/configure_firestorm.sh
options
--build
- --platform linux32
+ --platform linux
--package
@@ -4555,14 +4511,13 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
options
- --platform linux32
+ --platform linux
--package
name
ReleaseFS_open
-
name
linux
@@ -4717,23 +4672,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- arguments
-
- Firestorm.sln
-
- command
- msbuild.exe
options
- /p:Configuration=RelWithDebInfo
- /flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log
- /flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err
- /p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}
- /t:Build
- /p:useenv=true
- /verbosity:normal
- /toolsversion:12.0
- /p:VCBuildAdditionalOptions= /incremental
+ --fmodstudio
+ --kdu
+ --version
+ --platform windows
configure
@@ -4743,8 +4687,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
--fmodstudio
--kdu
--version
- --btype RelWithDebInfo
- --platform win32
+ --platform windows
default
@@ -4756,23 +4699,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- arguments
-
- Firestorm.sln
-
- command
- msbuild.exe
options
- /p:Configuration=RelWithDebInfo
- /flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log
- /flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err
- /p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}
- /t:Build
- /p:useenv=true
- /verbosity:normal
- /toolsversion:12.0
- /p:VCBuildAdditionalOptions= /incremental
+ --version
+ --btype RelWithDebInfo
+ --platform windows
configure
@@ -4781,7 +4712,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
--version
--btype RelWithDebInfo
- --platform win32
+ --platform windows
name
@@ -4791,23 +4722,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- arguments
-
- Firestorm.sln
-
- command
- msbuild.exe
options
- /p:Configuration=Release
- /flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log
- /flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err
- /p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}
- /t:Build
- /p:useenv=true
- /verbosity:normal
- /toolsversion:12.0
- /p:VCBuildAdditionalOptions= /incremental
+ --fmodstudio
+ --kdu
+ --version
+ --platform windows
configure
@@ -4817,7 +4737,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
--fmodstudio
--kdu
--version
- --platform win32
+ --platform windows
name
@@ -4827,34 +4747,22 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- arguments
-
- Firestorm.sln
-
- command
- msbuild.exe
options
- /p:Configuration=Release
- /flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log
- /flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err
- /p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}
- /t:Build
- /p:useenv=true
- /verbosity:normal
- /toolsversion:12.0
- /p:VCBuildAdditionalOptions= /incremental
+ --fmodstudio
+ --kdu
+ --version
+ --platform windows
configure
options
- --avx
--fmodstudio
--kdu
--version
- --platform win32
+ --platform windows
name
@@ -4864,34 +4772,22 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- arguments
-
- Firestorm.sln
-
- command
- msbuild.exe
options
- /p:Configuration=Release
- /flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log
- /flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err
- /p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}
- /t:Build
- /p:useenv=true
- /verbosity:normal
- /toolsversion:12.0
- /p:VCBuildAdditionalOptions= /incremental
+ --fmodstudio
+ --kdu
+ --version
+ --platform windows
configure
options
- --avx2
--fmodstudio
--kdu
--version
- --platform win32
+ --platform windows
name
@@ -4901,23 +4797,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
build
- arguments
-
- Firestorm.sln
-
- command
- msbuild.exe
options
- /p:Configuration=Release
- /flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log
- /flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err
- /p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}
- /t:Build
- /p:useenv=true
- /verbosity:minimal
- /toolsversion:12.0
- /p:VCBuildAdditionalOptions= /incremental
+ --version
+ --platform windows
configure
@@ -4925,7 +4808,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
options
--version
- --platform win32
+ --platform windows
name
diff --git a/build.sh b/build.sh
index e6e9e0b7f5..c1dcb94cea 100755
--- a/build.sh
+++ b/build.sh
@@ -95,23 +95,54 @@ pre_build()
&& [ -r "$master_message_template_checkout/message_template.msg" ] \
&& template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
- # nat 2016-12-20: disable HAVOK on Mac until we get a 64-bit Mac build.
RELEASE_CRASH_REPORTING=ON
HAVOK=ON
SIGNING=()
- if [ "$arch" == "Darwin" ]
+ if [ "$arch" == "Darwin" -a "$variant" == "Release" ]
+ then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
+ "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
+ fi
+
+ if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
then
- if [ "$variant" == "Release" ]
- then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
- "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
+ case "$arch" in
+ CYGWIN)
+ symplat="windows"
+ ;;
+ Darwin)
+ symplat="darwin"
+ ;;
+ Linux)
+ symplat="linux"
+ ;;
+ esac
+ # This name is consumed by indra/newview/CMakeLists.txt. Make it
+ # absolute because we've had troubles with relative pathnames.
+ abs_build_dir="$(cd "$build_dir"; pwd)"
+ VIEWER_SYMBOL_FILE="$(native_path "$abs_build_dir/newview/$variant/secondlife-symbols-$symplat-${AUTOBUILD_ADDRSIZE}.tar.bz2")"
+ fi
+
+ # don't spew credentials into build log
+ bugsplat_sh="$build_secrets_checkout/bugsplat/bugsplat.sh"
+ set +x
+ if [ -r "$bugsplat_sh" ]
+ then # show that we're doing this, just not the contents
+ echo source "$bugsplat_sh"
+ source "$bugsplat_sh"
+ # important: we test this and use its value in [grand-]child processes
+ if [ -n "${BUGSPLAT_DB:-}" ]
+ then echo export BUGSPLAT_DB
+ export BUGSPLAT_DB
fi
fi
+ set -x
"$autobuild" configure --quiet -c $variant -- \
-DPACKAGE:BOOL=ON \
- -DUNATTENDED:BOOL=ON \
-DHAVOK:BOOL="$HAVOK" \
-DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
+ -DVIEWER_SYMBOL_FILE:STRING="${VIEWER_SYMBOL_FILE:-}" \
+ -DBUGSPLAT_DB:STRING="${BUGSPLAT_DB:-}" \
-DVIEWER_CHANNEL:STRING="${viewer_channel}" \
-DGRID:STRING="\"$viewer_grid\"" \
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
@@ -193,6 +224,8 @@ then
exit 1
fi
+shopt -s nullglob # if nothing matches a glob, expand to nothing
+
initialize_build # provided by master buildscripts build.sh
begin_section "autobuild initialize"
@@ -232,7 +265,6 @@ initialize_version # provided by buildscripts build.sh; sets version id
# Now run the build
succeeded=true
-build_processes=
last_built_variant=
for variant in $variants
do
@@ -240,7 +272,6 @@ do
last_built_variant="$variant"
build_dir=`build_dir_$arch $variant`
- build_dir_stubs="$build_dir/win_setup/$variant"
begin_section "Initialize $variant Build Directory"
rm -rf "$build_dir"
@@ -414,19 +445,7 @@ then
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
then
# Upload crash reporter file
- # These names must match the set of VIEWER_SYMBOL_FILE in indra/newview/CMakeLists.txt
- case "$arch" in
- CYGWIN)
- symbolfile="$build_dir/newview/Release/secondlife-symbols-windows-${AUTOBUILD_ADDRSIZE}.tar.bz2"
- ;;
- Darwin)
- symbolfile="$build_dir/newview/Release/secondlife-symbols-darwin-${AUTOBUILD_ADDRSIZE}.tar.bz2"
- ;;
- Linux)
- symbolfile="$build_dir/newview/Release/secondlife-symbols-linux-${AUTOBUILD_ADDRSIZE}.tar.bz2"
- ;;
- esac
- python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$symbolfile" \
+ python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$VIEWER_SYMBOL_FILE" \
|| fatal "Upload of symbolfile failed"
fi
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 9bd8341c5c..db6bb03a52 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -81,6 +81,7 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
add_custom_target(viewer)
+
add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
add_subdirectory(${LIBS_OPEN_PREFIX}llui)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index f3cc2697ec..2939f6b90b 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES
Audio.cmake
BerkeleyDB.cmake
Boost.cmake
+ bugsplat.cmake
BuildVersion.cmake
CEFPlugin.cmake
CMakeCopyIfDifferent.cmake
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index e93cc504cd..b03bfc104e 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -49,6 +49,20 @@ if(WINDOWS)
libhunspell.dll
)
+ # Filenames are different for 32/64 bit BugSplat file and we don't
+ # have any control over them so need to branch.
+ if (BUGSPLAT_DB)
+ if(ADDRESS_SIZE EQUAL 32)
+ set(release_files ${release_files} BugSplat.dll)
+ set(release_files ${release_files} BugSplatRc.dll)
+ set(release_files ${release_files} BsSndRpt.exe)
+ else(ADDRESS_SIZE EQUAL 32)
+ set(release_files ${release_files} BugSplat64.dll)
+ set(release_files ${release_files} BugSplatRc64.dll)
+ set(release_files ${release_files} BsSndRpt64.exe)
+ endif(ADDRESS_SIZE EQUAL 32)
+ endif (BUGSPLAT_DB)
+
set(release_files ${release_files} growl++.dll growl.dll )
if (FMODSTUDIO)
if(ADDRESS_SIZE EQUAL 32)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 8fb7485949..d9c282be3f 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -1,4 +1,5 @@
# -*- cmake -*-
+include(00-Common)
include(LLTestCommand)
# Google Mock/Test is not used
diff --git a/indra/cmake/LLBase.cmake b/indra/cmake/LLBase.cmake
deleted file mode 100644
index 76e3c688a3..0000000000
--- a/indra/cmake/LLBase.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-
-use_prebuilt_binary(llbase)
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index 861b648bac..2ba997d6e0 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -77,6 +77,7 @@ if (WINDOWS)
wldap32
gdi32
user32
+ ole32
dbghelp
)
else (WINDOWS)
diff --git a/indra/cmake/Requests.cmake b/indra/cmake/Requests.cmake
deleted file mode 100644
index b9c729d697..0000000000
--- a/indra/cmake/Requests.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-if (DARWIN)
- include (Prebuilt)
- use_prebuilt_binary(requests)
- use_prebuilt_binary(urllib3)
- use_prebuilt_binary(chardet)
- use_prebuilt_binary(idna)
-endif (DARWIN)
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 78180b03e5..b74990ce7d 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -33,6 +33,8 @@ set(INTEGRATION_TESTS_PREFIX)
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
+set(VIEWER_SYMBOL_FILE "" CACHE STRING "Name of tarball into which to place symbol files")
+set(BUGSPLAT_DB "" CACHE STRING "BugSplat database name, if BugSplat crash reporting is desired")
if(LIBS_CLOSED_DIR)
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)
@@ -213,7 +215,7 @@ set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if
set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.")
-set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
+set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.") # No Teamcity -> allow unattended
set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
# When using Havok, we have to turn OpenSim support off
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
new file mode 100644
index 0000000000..59644b73ce
--- /dev/null
+++ b/indra/cmake/bugsplat.cmake
@@ -0,0 +1,25 @@
+# BugSplat is engaged by setting BUGSPLAT_DB to the target BugSplat database
+# name.
+if (BUGSPLAT_DB)
+ if (USESYSTEMLIBS)
+ message(STATUS "Looking for system BugSplat")
+ set(BUGSPLAT_FIND_QUIETLY ON)
+ set(BUGSPLAT_FIND_REQUIRED ON)
+ include(FindBUGSPLAT)
+ else (USESYSTEMLIBS)
+ message(STATUS "Engaging autobuild BugSplat")
+ include(Prebuilt)
+ use_prebuilt_binary(bugsplat)
+ if (WINDOWS)
+ set(BUGSPLAT_LIBRARIES
+ ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
+ )
+ elseif (DARWIN)
+ find_library(BUGSPLAT_LIBRARIES BugsplatMac
+ PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
+ else (WINDOWS)
+
+ endif (WINDOWS)
+ set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
+ endif (USESYSTEMLIBS)
+endif (BUGSPLAT_DB)
diff --git a/indra/cmake/jemalloc.cmake b/indra/cmake/jemalloc.cmake
new file mode 100644
index 0000000000..da77d0f160
--- /dev/null
+++ b/indra/cmake/jemalloc.cmake
@@ -0,0 +1,10 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+if( USE_JEMALLOC )
+ if (USESYSTEMLIBS)
+ message( WARNING "Not implemented" )
+ else (USESYSTEMLIBS)
+ use_prebuilt_binary(jemalloc)
+ endif (USESYSTEMLIBS)
+endif()
diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt
index 13cf1f7bde..d9353f904c 100644
--- a/indra/integration_tests/llimage_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt
@@ -40,7 +40,7 @@ add_executable(llimage_libtest
WIN32
MACOSX_BUNDLE
${llimage_libtest_SOURCE_FILES}
-)
+ )
set_target_properties(llimage_libtest
PROPERTIES
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 025347502d..054633d780 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -33,13 +33,14 @@ import filecmp
import fnmatch
import getopt
import glob
+import itertools
+import operator
import os
import re
import shutil
+import subprocess
import sys
import tarfile
-import errno
-import subprocess
class ManifestError(RuntimeError):
"""Use an exception more specific than generic Python RuntimeError"""
@@ -49,7 +50,9 @@ class ManifestError(RuntimeError):
class MissingError(ManifestError):
"""You specified a file that doesn't exist"""
- pass
+ def __init__(self, msg):
+ self.msg = msg
+ super(MissingError, self).__init__(self.msg)
def path_ancestors(path):
drive, path = os.path.splitdrive(os.path.normpath(path))
@@ -90,7 +93,7 @@ DEFAULT_SRCTREE = os.path.dirname(sys.argv[0])
CHANNEL_VENDOR_BASE = 'Firestorm'
RELEASE_CHANNEL = CHANNEL_VENDOR_BASE + ' Development'
-ARGUMENTS=[
+BASE_ARGUMENTS=[
dict(name='actions',
description="""This argument specifies the actions that are to be taken when the
script is run. The meaningful actions are currently:
@@ -108,8 +111,19 @@ ARGUMENTS=[
Example use: %(name)s --arch=i686
On Linux this would try to use Linux_i686Manifest.""",
default=""),
+ dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE),
dict(name='build', description='Build directory.', default=DEFAULT_SRCTREE),
dict(name='buildtype', description='Build type (i.e. Debug, Release, RelWithDebInfo).', default=None),
+ dict(name='bundleid',
+ description="""The Mac OS X Bundle identifier.""",
+ default="com.secondlife.indra.viewer"),
+ dict(name='channel',
+ description="""The channel to use for updates, packaging, settings name, etc.""",
+ default='CHANNEL UNSET'),
+ dict(name='channel_suffix',
+ description="""Addition to the channel for packaging and channel value,
+ but not application name (used internally)""",
+ default=None),
dict(name='configuration',
description="""The build configuration used.""",
default="Release"),
@@ -117,12 +131,6 @@ ARGUMENTS=[
dict(name='grid',
description="""Which grid the client will try to connect to.""",
default=None),
- dict(name='channel',
- description="""The channel to use for updates, packaging, settings name, etc.""",
- default='CHANNEL UNSET'),
- dict(name='channel_suffix',
- description="""Addition to the channel for packaging and channel value, but not application name (used internally)""",
- default=None),
dict(name='installer_name',
description=""" The name of the file that the installer should be
packaged up into. Only used on Linux at the moment.""",
@@ -134,10 +142,14 @@ ARGUMENTS=[
description="""The current platform, to be used for looking up which
manifest class to run.""",
default=get_default_platform),
+ dict(name='signature',
+ description="""This specifies an identity to sign the viewer with, if any.
+ If no value is supplied, the default signature will be used, if any. Currently
+ only used on Mac OS X.""",
+ default=None),
dict(name='source',
description='Source directory.',
default=DEFAULT_SRCTREE),
- dict(name='artwork', description='Artwork directory.', default=DEFAULT_SRCTREE),
dict(name='touch',
description="""File to touch when action is finished. Touch file will
contain the name of the final package in a form suitable
@@ -145,24 +157,17 @@ ARGUMENTS=[
default=None),
dict(name='versionfile',
description="""The name of a file containing the full version number."""),
- dict(name='bundleid',
- description="""The Mac OS X Bundle identifier.""",
- default="com.secondlife.indra.viewer"),
- dict(name='signature',
- description="""This specifies an identity to sign the viewer with, if any.
- If no value is supplied, the default signature will be used, if any. Currently
- only used on Mac OS X.""",
- default=None),
- dict(name='viewer_flavor', description='Type of viewer build. Can be oss or hvk.', default="oss"),
+ dict(name='viewer_flavor',
+ description='Type of viewer build. Can be oss or hvk.', default="oss"),
]
-def usage(srctree=""):
+def usage(arguments, srctree=""):
nd = {'name':sys.argv[0]}
print """Usage:
%(name)s [options] [destdir]
Options:
""" % nd
- for arg in ARGUMENTS:
+ for arg in arguments:
default = arg['default']
if hasattr(default, '__call__'):
default = "(computed value) \"" + str(default(srctree)) + '"'
@@ -173,13 +178,16 @@ def usage(srctree=""):
default,
arg['description'] % nd)
-def main():
-## import itertools
+def main(extra=[]):
## print ' '.join((("'%s'" % item) if ' ' in item else item)
## for item in itertools.chain([sys.executable], sys.argv))
- option_names = [arg['name'] + '=' for arg in ARGUMENTS]
+ # Supplement our default command-line switches with any desired by
+ # application-specific caller.
+ arguments = list(itertools.chain(BASE_ARGUMENTS, extra))
+ # Alphabetize them by option name in case we display usage.
+ arguments.sort(key=operator.itemgetter('name'))
+ option_names = [arg['name'] + '=' for arg in arguments]
option_names.append('help')
-
options, remainder = getopt.getopt(sys.argv[1:], "", option_names)
# convert options to a hash
@@ -201,11 +209,11 @@ def main():
# early out for help
if 'help' in args:
# *TODO: it is a huge hack to pass around the srctree like this
- usage(args['source'])
+ usage(arguments, srctree=args['source'])
return
# defaults
- for arg in ARGUMENTS:
+ for arg in arguments:
if arg['name'] not in args:
default = arg['default']
if hasattr(default, '__call__'):
@@ -236,104 +244,68 @@ def main():
print "Option:", opt, "=", args[opt]
# pass in sourceid as an argument now instead of an environment variable
- try:
- args['sourceid'] = os.environ["sourceid"]
- except KeyError:
- args['sourceid'] = ""
+ args['sourceid'] = os.environ.get("sourceid", "")
# Build base package.
touch = args.get('touch')
if touch:
- print 'Creating base package'
- args['package_id'] = "" # base package has no package ID
+ print '================ Creating base package'
+ else:
+ print '================ Starting base copy'
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions'])
# Store package file for later if making touched file.
base_package_file = ""
if touch:
- print 'Created base package ', wm.package_file
+ print '================ Created base package ', wm.package_file
base_package_file = "" + wm.package_file
+ else:
+ print '================ Finished base copy'
# handle multiple packages if set
- try:
- additional_packages = os.environ["additional_packages"]
- except KeyError:
- additional_packages = ""
+ # ''.split() produces empty list
+ additional_packages = os.environ.get("additional_packages", "").split()
if additional_packages:
# Determine destination prefix / suffix for additional packages.
- base_dest_postfix = args['dest']
- base_dest_prefix = ""
- base_dest_parts = args['dest'].split(os.sep)
- if len(base_dest_parts) > 1:
- base_dest_postfix = base_dest_parts[len(base_dest_parts) - 1]
- base_dest_prefix = base_dest_parts[0]
- i = 1
- while i < len(base_dest_parts) - 1:
- base_dest_prefix = base_dest_prefix + os.sep + base_dest_parts[i]
- i = i + 1
+ base_dest_parts = list(os.path.split(args['dest']))
+ base_dest_parts.insert(-1, "{}")
+ base_dest_template = os.path.join(*base_dest_parts)
# Determine touched prefix / suffix for additional packages.
- base_touch_postfix = ""
- base_touch_prefix = ""
if touch:
- base_touch_postfix = touch
- base_touch_parts = touch.split('/')
+ base_touch_parts = list(os.path.split(touch))
+ # Because of the special insert() logic below, we don't just want
+ # [dirpath, basename]; we want [dirpath, directory, basename].
+ # Further split the dirpath and replace it in the list.
+ base_touch_parts[0:1] = os.path.split(base_touch_parts[0])
if "arwin" in args['platform']:
- if len(base_touch_parts) > 1:
- base_touch_postfix = base_touch_parts[len(base_touch_parts) - 1]
- base_touch_prefix = base_touch_parts[0]
- i = 1
- while i < len(base_touch_parts) - 1:
- base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
- i = i + 1
+ base_touch_parts.insert(-1, "{}")
else:
- if len(base_touch_parts) > 2:
- base_touch_postfix = base_touch_parts[len(base_touch_parts) - 2] + '/' + base_touch_parts[len(base_touch_parts) - 1]
- base_touch_prefix = base_touch_parts[0]
- i = 1
- while i < len(base_touch_parts) - 2:
- base_touch_prefix = base_touch_prefix + '/' + base_touch_parts[i]
- i = i + 1
- # Store base channel name.
- base_channel_name = args['channel']
- # Build each additional package.
- package_id_list = additional_packages.split(" ")
- args['channel'] = base_channel_name
- for package_id in package_id_list:
- try:
- if package_id + "_viewer_channel_suffix" in os.environ:
- args['channel_suffix'] = os.environ[package_id + "_viewer_channel_suffix"]
- else:
- args['channel_suffix'] = None
- if package_id + "_sourceid" in os.environ:
- args['sourceid'] = os.environ[package_id + "_sourceid"]
- else:
- args['sourceid'] = None
- args['dest'] = base_dest_prefix + os.sep + package_id + os.sep + base_dest_postfix
- except KeyError:
- sys.stderr.write("Failed to create package for package_id: %s" % package_id)
- sys.stderr.flush()
- continue
+ base_touch_parts.insert(-2, "{}")
+ base_touch_template = os.path.join(*base_touch_parts)
+ for package_id in additional_packages:
+ args['channel_suffix'] = os.environ.get(package_id + "_viewer_channel_suffix")
+ args['sourceid'] = os.environ.get(package_id + "_sourceid")
+ args['dest'] = base_dest_template.format(package_id)
if touch:
- print 'Creating additional package for "', package_id, '" in ', args['dest']
+ print '================ Creating additional package for "', package_id, '" in ', args['dest']
+ else:
+ print '================ Starting additional copy for "', package_id, '" in ', args['dest']
try:
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions'])
except Exception as err:
sys.exit(str(err))
if touch:
- print 'Created additional package ', wm.package_file, ' for ', package_id
- faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix
- fp = open(faketouch, 'w')
- fp.write('set package_file=%s\n' % wm.package_file)
- fp.close()
-
+ print '================ Created additional package ', wm.package_file, ' for ', package_id
+ with open(base_touch_template.format(package_id), 'w') as fp:
+ fp.write('set package_file=%s\n' % wm.package_file)
+ else:
+ print '================ Finished additional copy "', package_id, '" in ', args['dest']
# Write out the package file in this format, so that it can easily be called
# and used in a .bat file - yeah, it sucks, but this is the simplest...
- touch = args.get('touch')
if touch:
- fp = open(touch, 'w')
- fp.write('set package_file=%s\n' % base_package_file)
- fp.close()
+ with open(touch, 'w') as fp:
+ fp.write('set package_file=%s\n' % base_package_file)
print 'touched', touch
return 0
@@ -379,7 +351,7 @@ class LLManifest(object):
in the file list by path()."""
self.excludes.append(glob)
- def prefix(self, src='', build=None, dst=None):
+ def prefix(self, src='', build='', dst='', src_dst=None):
"""
Usage:
@@ -389,8 +361,21 @@ class LLManifest(object):
For the duration of the 'with' block, pushes a prefix onto the stack.
Within that block, all relevant method calls (esp. to path()) will
prefix paths with the entire prefix stack. Source and destination
- prefixes can be different, though if only one is provided they are
- both equal. To specify a no-op, use an empty string, not None.
+ prefixes are independent; if omitted (or passed as the empty string),
+ the prefix has no effect. Thus:
+
+ with self.prefix(src='foo'):
+ # no effect on dst
+
+ with self.prefix(dst='bar'):
+ # no effect on src
+
+ If you want to set both at once, use src_dst:
+
+ with self.prefix(src_dst='subdir'):
+ # same as self.prefix(src='subdir', dst='subdir')
+ # Passing src_dst makes any src or dst argument in the same
+ # parameter list irrelevant.
Also supports the older (pre-Python-2.5) syntax:
@@ -404,34 +389,42 @@ class LLManifest(object):
returned True specifically so that the caller could indent the
relevant block of code with 'if', just for aesthetic purposes.
"""
- if dst is None:
- dst = src
- if build is None:
- build = src
+ if src_dst is not None:
+ src = src_dst
+ dst = src_dst
self.src_prefix.append(src)
self.artwork_prefix.append(src)
self.build_prefix.append(build)
self.dst_prefix.append(dst)
+## self.display_stacks()
+
# The above code is unchanged from the original implementation. What's
# new is the return value. We're going to return an instance of
# PrefixManager that binds this LLManifest instance and Does The Right
# Thing on exit.
return self.PrefixManager(self)
+ def display_stacks(self):
+ width = 1 + max(len(stack) for stack in self.PrefixManager.stacks)
+ for stack in self.PrefixManager.stacks:
+ print "{} {}".format((stack + ':').ljust(width),
+ os.path.join(*getattr(self, stack)))
+
class PrefixManager(object):
+ # stack attributes we manage in this LLManifest (sub)class
+ # instance
+ stacks = ("src_prefix", "artwork_prefix", "build_prefix", "dst_prefix")
+
def __init__(self, manifest):
self.manifest = manifest
- # stack attributes we manage in this LLManifest (sub)class
- # instance
- stacks = ("src_prefix", "artwork_prefix", "build_prefix", "dst_prefix")
# If the caller wrote:
# with self.prefix(...):
# as intended, then bind the state of each prefix stack as it was
# just BEFORE the call to prefix(). Since prefix() appended an
# entry to each prefix stack, capture len()-1.
self.prevlen = { stack: len(getattr(self.manifest, stack)) - 1
- for stack in stacks }
+ for stack in self.stacks }
def __nonzero__(self):
# If the caller wrote:
@@ -464,6 +457,8 @@ class LLManifest(object):
# truncate that list back to 'prevlen'
del getattr(self.manifest, stack)[prevlen:]
+## self.manifest.display_stacks()
+
def end_prefix(self, descr=None):
"""Pops a prefix off the stack. If given an argument, checks
the argument against the top of the stack. If the argument
@@ -509,6 +504,19 @@ class LLManifest(object):
relative to the destination directory."""
return os.path.join(self.get_dst_prefix(), relpath)
+ def _relative_dst_path(self, dstpath):
+ """
+ Returns the path to a file or directory relative to the destination directory.
+ This should only be used for generating diagnostic output in the path method.
+ """
+ dest_root=self.dst_prefix[0]
+ if dstpath.startswith(dest_root+os.path.sep):
+ return dstpath[len(dest_root)+1:]
+ elif dstpath.startswith(dest_root):
+ return dstpath[len(dest_root):]
+ else:
+ return dstpath
+
def ensure_src_dir(self, reldir):
"""Construct the path for a directory relative to the
source path, and ensures that it exists. Returns the
@@ -626,9 +634,16 @@ class LLManifest(object):
# *TODO is this gonna be useful?
print "Cleaning up " + c
+ def process_either(self, src, dst):
+ # If it's a real directory, recurse through it --
+ # but not a symlink! Handle those like files.
+ if os.path.isdir(src) and not os.path.islink(src):
+ return self.process_directory(src, dst)
+ else:
+ return self.process_file(src, dst)
+
def process_file(self, src, dst):
if self.includes(src, dst):
-# print src, "=>", dst
for action in self.actions:
methodname = action + "_action"
method = getattr(self, methodname, None)
@@ -653,10 +668,7 @@ class LLManifest(object):
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
- if os.path.isdir(srcname):
- count += self.process_directory(srcname, dstname)
- else:
- count += self.process_file(srcname, dstname)
+ count += self.process_either(srcname, dstname)
return count
def includes(self, src, dst):
@@ -696,7 +708,11 @@ class LLManifest(object):
# Don't recopy file if it's up-to-date.
# If we seem to be not not overwriting files that have been
# updated, set the last arg to False, but it will take longer.
+## reldst = (dst[len(self.dst_prefix[0]):]
+## if dst.startswith(self.dst_prefix[0])
+## else dst).lstrip(r'\/')
if os.path.exists(dst) and filecmp.cmp(src, dst, True):
+## print "{} (skipping, {} exists)".format(src, reldst)
return
# only copy if it's not excluded
if self.includes(src, dst):
@@ -706,6 +722,7 @@ class LLManifest(object):
if err.errno != errno.ENOENT:
raise
+## print "{} => {}".format(src, reldst)
shutil.copy2(src, dst)
def ccopytree(self, src, dst):
@@ -804,13 +821,13 @@ class LLManifest(object):
return self.path(os.path.join(path, file), file)
def path(self, src, dst=None):
- sys.stdout.write("Processing %s => %s ... " % (src, dst))
sys.stdout.flush()
if src == None:
raise ManifestError("No source file, dst is " + dst)
if dst == None:
dst = src
dst = os.path.join(self.get_dst_prefix(), dst)
+ sys.stdout.write("Processing %s => %s ... " % (src, self._relative_dst_path(dst)))
def try_path(src):
# expand globs
@@ -823,29 +840,21 @@ class LLManifest(object):
# if we're specifying a single path (not a glob),
# we should error out if it doesn't exist
self.check_file_exists(src)
- # if it's a directory, recurse through it
- if os.path.isdir(src):
- count += self.process_directory(src, dst)
- else:
- count += self.process_file(src, dst)
+ count += self.process_either(src, dst)
return count
- for pfx in self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix():
+ try_prefixes = [self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix()]
+ tried=[]
+ count=0
+ while not count and try_prefixes:
+ pfx = try_prefixes.pop(0)
try:
count = try_path(os.path.join(pfx, src))
except MissingError:
- # If src isn't a wildcard, and if that file doesn't exist in
- # this pfx, try next pfx.
- count = 0
- continue
-
- # Here try_path() didn't raise MissingError. Did it process any files?
- if count:
- break
- # Even though try_path() didn't raise MissingError, it returned 0
- # files. src is probably a wildcard meant for some other pfx. Loop
- # back to try the next.
-
+ tried.append(pfx)
+ if not try_prefixes:
+ # no more prefixes left to try
+ print "unable to find '%s'; looked in:\n %s" % (src, '\n '.join(tried))
print "%d files" % count
# Let caller check whether we processed as many files as expected. In
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index 029096df37..315aed8d11 100644
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -78,4 +78,4 @@ target_link_libraries(linux-crash-logger
)
add_custom_target(linux-crash-logger-target ALL
- DEPENDS linux-crash-logger)
+ DEPENDS linux-crash-logger)
diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp
index 381665a1d5..7196667d75 100644
--- a/indra/llappearance/llavatarjoint.cpp
+++ b/indra/llappearance/llavatarjoint.cpp
@@ -121,7 +121,11 @@ void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
- LLAvatarJoint* joint = dynamic_cast(*iter);
+// LLAvatarJoint* joint = dynamic_cast(*iter);
+// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
+ // Dynamic cast is pointless if the result isn't actually checked (and if we know it won't fail we can just static cast)
+ LLAvatarJoint* joint = static_cast(*iter);
+// [/SL:KB]
joint->setSkeletonComponents(comp, recursive);
}
}
@@ -147,7 +151,10 @@ void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
- LLAvatarJoint* joint = dynamic_cast(*iter);
+// LLAvatarJoint* joint = dynamic_cast(*iter);
+// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
+ LLAvatarJoint* joint = static_cast(*iter);
+// [/SL:KB]
joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
}
}
@@ -157,7 +164,10 @@ void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind,
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
- LLAvatarJoint* joint = dynamic_cast(*iter);
+// LLAvatarJoint* joint = dynamic_cast(*iter);
+// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
+ LLAvatarJoint* joint = static_cast(*iter);
+// [/SL:KB]
joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
}
}
@@ -167,7 +177,10 @@ void LLAvatarJoint::updateJointGeometry()
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
- LLAvatarJoint* joint = dynamic_cast(*iter);
+// LLAvatarJoint* joint = dynamic_cast(*iter);
+// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
+ LLAvatarJoint* joint = static_cast(*iter);
+// [/SL:KB]
joint->updateJointGeometry();
}
}
@@ -214,7 +227,10 @@ void LLAvatarJoint::dump()
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
- LLAvatarJoint* joint = dynamic_cast(*iter);
+// LLAvatarJoint* joint = dynamic_cast(*iter);
+// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
+ LLAvatarJoint* joint = static_cast(*iter);
+// [/SL:KB]
joint->dump();
}
}
diff --git a/indra/llappearance/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp
index b7ad5e67cb..3fc406d51d 100644
--- a/indra/llappearance/lllocaltextureobject.cpp
+++ b/indra/llappearance/lllocaltextureobject.cpp
@@ -211,4 +211,3 @@ void LLLocalTextureObject::setBakedReady(BOOL ready)
{
mIsBakedReady = ready;
}
-
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 350305f573..fd2ae8df2b 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -281,6 +281,11 @@ list(APPEND llcommon_HEADER_FILES "tea.h" )
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
+if (BUGSPLAT_DB)
+ set_source_files_properties(llapp.cpp
+ PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (BUGSPLAT_DB)
+
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
if(LLCOMMON_LINK_SHARED)
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index a177fba444..94f07c7e78 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -402,7 +402,7 @@ void LLApp::setupErrorHandling(bool second_instance, EMiniDumpType minidump_type
#if LL_WINDOWS
-#if LL_SEND_CRASH_REPORTS
+#if LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT)
EnableCrashingOnCrashes();
// This sets a callback to handle w32 signals to the console window.
@@ -481,8 +481,15 @@ void LLApp::setupErrorHandling(bool second_instance, EMiniDumpType minidump_type
mExceptionHandler->set_handle_debug_exceptions(true);
}
}
-#endif
-#else
+#endif // LL_SEND_CRASH_REPORTS && ! defined(LL_BUGSPLAT)
+#else // ! LL_WINDOWS
+
+#if defined(LL_BUGSPLAT)
+ // Don't install our own signal handlers -- BugSplat needs to hook them,
+ // or it's completely ineffectual.
+ bool installHandler = false;
+
+#else // ! LL_BUGSPLAT
//
// Start up signal handling.
//
@@ -490,9 +497,11 @@ void LLApp::setupErrorHandling(bool second_instance, EMiniDumpType minidump_type
// thread, asynchronous signals can be delivered to any thread (in theory)
//
setup_signals();
-
+
// Add google breakpad exception handler configured for Darwin/Linux.
bool installHandler = true;
+#endif // ! LL_BUGSPLAT
+
#if LL_DARWIN
// For the special case of Darwin, we do not want to install the handler if
// the process is being debugged as the app will exit with value ABRT (6) if
@@ -525,7 +534,7 @@ void LLApp::setupErrorHandling(bool second_instance, EMiniDumpType minidump_type
// installing the handler.
installHandler = true;
}
- #endif
+ #endif // ! LL_RELEASE_FOR_DOWNLOAD
if(installHandler && (mExceptionHandler == 0))
{
@@ -541,9 +550,9 @@ void LLApp::setupErrorHandling(bool second_instance, EMiniDumpType minidump_type
google_breakpad::MinidumpDescriptor desc(mDumpPath);
mExceptionHandler = new google_breakpad::ExceptionHandler(desc, NULL, unix_minidump_callback, NULL, true, -1);
}
-#endif
+#endif // LL_LINUX
-#endif
+#endif // ! LL_WINDOWS
startErrorThread();
}
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 8fb27af6a4..c551413811 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -169,6 +169,26 @@ public:
static void set_consuming(bool consuming);
static bool get_consuming();
+ /**
+ * RAII control of the consuming flag
+ */
+ class OverrideConsuming
+ {
+ public:
+ OverrideConsuming(bool consuming):
+ mPrevConsuming(get_consuming())
+ {
+ set_consuming(consuming);
+ }
+ ~OverrideConsuming()
+ {
+ set_consuming(mPrevConsuming);
+ }
+
+ private:
+ bool mPrevConsuming;
+ };
+
/**
* Please do NOT directly use boost::dcoroutines::future! It is essential
* to maintain the "current" coroutine at every context switch. This
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index a4432a1f13..487ab7fc4f 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -125,6 +125,9 @@ namespace {
public:
RecordToFile(const std::string& filename)
{
+ // Don't screw up log file output
+ this->showMultiline(true);
+
mFile.open(filename.c_str(), std::ios_base::out | std::ios_base::app);
if (!mFile)
{
@@ -137,8 +140,6 @@ namespace {
mFile.sync_with_stdio(false);
}
}
- mWantsTime = true;
- mWantsTags = true;
}
~RecordToFile()
@@ -180,7 +181,7 @@ namespace {
public:
RecordToStderr(bool timestamp) : mUseANSI(ANSI_PROBE)
{
- mWantsTime = timestamp;
+ this->showMultiline(true);
}
virtual bool enabled() override
@@ -249,7 +250,13 @@ namespace {
class RecordToFixedBuffer : public LLError::Recorder
{
public:
- RecordToFixedBuffer(LLLineBuffer* buffer) : mBuffer(buffer) { }
+ RecordToFixedBuffer(LLLineBuffer* buffer)
+ : mBuffer(buffer)
+ {
+ this->showMultiline(true);
+ this->showTags(false);
+ this->showLocation(false);
+ }
virtual bool enabled() override
{
@@ -271,7 +278,11 @@ namespace {
{
public:
RecordToWinDebug()
- {}
+ {
+ this->showMultiline(true);
+ this->showTags(false);
+ this->showLocation(false);
+ }
virtual bool enabled() override
{
@@ -427,6 +438,7 @@ namespace
public:
std::ostringstream messageStream;
bool messageStreamInUse;
+ std::string mFatalMessage;
void addCallSite(LLError::CallSite&);
void invalidateCallSites();
@@ -462,15 +474,13 @@ namespace
namespace LLError
{
- class SettingsConfig: public LLRefCount
+ class SettingsConfig : public LLRefCount
{
friend class Settings;
public:
virtual ~SettingsConfig();
- bool mPrintLocation;
-
LLError::ELevel mDefaultLevel;
bool mLogAlwaysFlush;
@@ -515,7 +525,6 @@ namespace LLError
SettingsConfig::SettingsConfig()
: LLRefCount(),
- mPrintLocation(false),
mDefaultLevel(LLError::LEVEL_DEBUG),
mLogAlwaysFlush(true),
mEnabledLogTypesMask(255),
@@ -752,23 +761,22 @@ namespace LLError
commonInit(user_dir, app_dir, log_to_stderr);
}
- void setPrintLocation(bool print)
- {
- SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
- s->mPrintLocation = print;
- }
-
void setFatalFunction(const FatalFunction& f)
{
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
s->mCrashFunction = f;
}
- FatalFunction getFatalFunction()
- {
+ FatalFunction getFatalFunction()
+ {
SettingsConfigPtr s = Settings::getInstance()->getSettingsConfig();
- return s->mCrashFunction;
- }
+ return s->mCrashFunction;
+ }
+
+ std::string getFatalMessage()
+ {
+ return Globals::getInstance()->mFatalMessage;
+ }
void setTimeFunction(TimeFunction f)
{
@@ -891,7 +899,6 @@ namespace LLError
s->mTagLevelMap.clear();
s->mUniqueLogMessages.clear();
- setPrintLocation(config["print-location"]);
setDefaultLevel(decodeLevel(config["default-level"]));
if (config.has("log-always-flush"))
{
@@ -927,11 +934,12 @@ namespace LLError
namespace LLError
{
Recorder::Recorder()
- : mWantsTime(false),
- mWantsTags(false),
- mWantsLevel(true),
- mWantsLocation(false),
- mWantsFunctionName(true)
+ : mWantsTime(true)
+ , mWantsTags(true)
+ , mWantsLevel(true)
+ , mWantsLocation(true)
+ , mWantsFunctionName(true)
+ , mWantsMultiline(false)
{
}
@@ -968,6 +976,42 @@ namespace LLError
return mWantsFunctionName;
}
+ // virtual
+ bool Recorder::wantsMultiline()
+ {
+ return mWantsMultiline;
+ }
+
+ void Recorder::showTime(bool show)
+ {
+ mWantsTime = show;
+ }
+
+ void Recorder::showTags(bool show)
+ {
+ mWantsTags = show;
+ }
+
+ void Recorder::showLevel(bool show)
+ {
+ mWantsLevel = show;
+ }
+
+ void Recorder::showLocation(bool show)
+ {
+ mWantsLocation = show;
+ }
+
+ void Recorder::showFunctionName(bool show)
+ {
+ mWantsFunctionName = show;
+ }
+
+ void Recorder::showMultiline(bool show)
+ {
+ mWantsMultiline = show;
+ }
+
void addRecorder(RecorderPtr recorder)
{
if (!recorder)
@@ -1000,17 +1044,15 @@ namespace LLError
s->mFileRecorder.reset();
s->mFileRecorderFileName.clear();
- if (file_name.empty())
+ if (!file_name.empty())
{
- return;
- }
-
- RecorderPtr recordToFile(new RecordToFile(file_name));
- if (boost::dynamic_pointer_cast(recordToFile)->okay())
- {
- s->mFileRecorderFileName = file_name;
- s->mFileRecorder = recordToFile;
- addRecorder(recordToFile);
+ RecorderPtr recordToFile(new RecordToFile(file_name));
+ if (boost::dynamic_pointer_cast(recordToFile)->okay())
+ {
+ s->mFileRecorderFileName = file_name;
+ s->mFileRecorder = recordToFile;
+ addRecorder(recordToFile);
+ }
}
}
@@ -1021,14 +1063,12 @@ namespace LLError
removeRecorder(s->mFixedBufferRecorder);
s->mFixedBufferRecorder.reset();
- if (!fixedBuffer)
+ if (fixedBuffer)
{
- return;
- }
-
- RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
- s->mFixedBufferRecorder = recordToFixedBuffer;
- addRecorder(recordToFixedBuffer);
+ RecorderPtr recordToFixedBuffer(new RecordToFixedBuffer(fixedBuffer));
+ s->mFixedBufferRecorder = recordToFixedBuffer;
+ addRecorder(recordToFixedBuffer);
+ }
}
std::string logFileName()
@@ -1040,9 +1080,9 @@ namespace LLError
namespace
{
- /* Hide the log sanitize function so gcc doesnt complain.
- void addEscapedMessage(std::ostream& out, const std::string& message)
+ std::string escapedMessageLines(const std::string& message)
{
+ std::ostringstream out;
size_t written_out = 0;
size_t all_content = message.length();
size_t escape_char_index; // always relative to start of message
@@ -1078,13 +1118,16 @@ namespace
// write whatever was left
out << message.substr(written_out, std::string::npos);
}
- } */
+ return out.str();
+ }
- void writeToRecorders(const LLError::CallSite& site, const std::string& escaped_message)
+ void writeToRecorders(const LLError::CallSite& site, const std::string& message)
{
LLError::ELevel level = site.mLevel;
LLError::SettingsConfigPtr s = LLError::Settings::getInstance()->getSettingsConfig();
-
+
+ std::string escaped_message;
+
for (Recorders::const_iterator i = s->mRecorders.begin();
i != s->mRecorders.end();
++i)
@@ -1110,13 +1153,13 @@ namespace
}
message_stream << " ";
- if (r->wantsTags() && !site.mTagString.empty())
+ if (r->wantsTags())
{
- message_stream << site.mTagString << " ";
+ message_stream << site.mTagString;
}
message_stream << " ";
- if (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation)
+ if (r->wantsLocation() || level == LLError::LEVEL_ERROR)
{
message_stream << site.mLocationString;
}
@@ -1128,7 +1171,18 @@ namespace
}
message_stream << " : ";
- message_stream << escaped_message;
+ if (r->wantsMultiline())
+ {
+ message_stream << message;
+ }
+ else
+ {
+ if (escaped_message.empty())
+ {
+ escaped_message = escapedMessageLines(message);
+ }
+ message_stream << escaped_message;
+ }
r->recordMessage(level, message_stream.str());
}
@@ -1331,10 +1385,11 @@ namespace LLError
std::ostringstream prefix;
if( nd::logging::throttle( site.mFile, site.mLine, &prefix ) )
return;
- std::ostringstream message_stream;
if (site.mPrintOnce)
{
+ std::ostringstream message_stream;
+
std::map::iterator messageIter = s->mUniqueLogMessages.find(message);
if (messageIter != s->mUniqueLogMessages.end())
{
@@ -1354,18 +1409,19 @@ namespace LLError
message_stream << "ONCE: ";
s->mUniqueLogMessages[message] = 1;
}
+ message_stream << message;
+ message = message_stream.str();
}
- // Fix log output - we don't need an escaped output
- //addEscapedMessage(message_stream, message);
- message_stream << message;
- //
+ writeToRecorders(site, message);
- writeToRecorders(site, message_stream.str());
-
- if (site.mLevel == LEVEL_ERROR && s->mCrashFunction)
+ if (site.mLevel == LEVEL_ERROR)
{
- s->mCrashFunction(message_stream.str());
+ g->mFatalMessage = message;
+ if (s->mCrashFunction)
+ {
+ s->mCrashFunction(message);
+ }
}
}
}
@@ -1670,3 +1726,4 @@ bool debugLoggingEnabled(const std::string& tag)
}
+
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index 1730f0c640..276d22fc36 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -106,6 +106,9 @@ namespace LLError
LL_COMMON_API FatalFunction getFatalFunction();
// Retrieve the previously-set FatalFunction
+ LL_COMMON_API std::string getFatalMessage();
+ // Retrieve the message last passed to FatalFunction, if any
+
/// temporarily override the FatalFunction for the duration of a
/// particular scope, e.g. for unit tests
class LL_COMMON_API OverrideFatalFunction
@@ -151,13 +154,22 @@ namespace LLError
bool wantsLevel();
bool wantsLocation();
bool wantsFunctionName();
+ bool wantsMultiline();
+
+ void showTime(bool show);
+ void showTags(bool show);
+ void showLevel(bool show);
+ void showLocation(bool show);
+ void showFunctionName(bool show);
+ void showMultiline(bool show);
protected:
- bool mWantsTime,
- mWantsTags,
- mWantsLevel,
- mWantsLocation,
- mWantsFunctionName;
+ bool mWantsTime;
+ bool mWantsTags;
+ bool mWantsLevel;
+ bool mWantsLocation;
+ bool mWantsFunctionName;
+ bool mWantsMultiline;
};
typedef boost::shared_ptr RecorderPtr;
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index a828a354b6..95aaaeb58b 100644
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
@@ -554,10 +554,8 @@ bool LLEventStream::post(const LLSD& event)
*****************************************************************************/
bool LLEventMailDrop::post(const LLSD& event)
{
- bool posted = false;
-
- if (!mSignal->empty())
- posted = LLEventStream::post(event);
+ // forward the call to our base class
+ bool posted = LLEventStream::post(event);
if (!posted)
{ // if the event was not handled we will save it for later so that it can
@@ -573,16 +571,25 @@ LLBoundListener LLEventMailDrop::listen_impl(const std::string& name,
const NameList& after,
const NameList& before)
{
- if (!mEventHistory.empty())
+ // Before actually connecting this listener for subsequent post() calls,
+ // first feed each of the saved events, in order, to the new listener.
+ // Remove any that this listener consumes -- Effective STL, Item 9.
+ for (auto hi(mEventHistory.begin()), hend(mEventHistory.end()); hi != hend; )
{
- if (listener(mEventHistory.front()))
+ if (listener(*hi))
{
- mEventHistory.pop_front();
+ // new listener consumed this event, erase it
+ hi = mEventHistory.erase(hi);
+ }
+ else
+ {
+ // listener did not consume this event, just move along
+ ++hi;
}
}
+ // let base class perform the actual connection
return LLEventStream::listen_impl(name, listener, after, before);
-
}
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 1d51c660ed..5d60c63810 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -650,15 +650,21 @@ public:
* LLEventMailDrop
*****************************************************************************/
/**
- * LLEventMailDrop is a specialization of LLEventStream. Events are posted normally,
- * however if no listeners return that they have handled the event it is placed in
- * a queue. Subsequent attaching listeners will receive stored events from the queue
- * until a listener indicates that the event has been handled. In order to receive
- * multiple events from a mail drop the listener must disconnect and reconnect.
+ * LLEventMailDrop is a specialization of LLEventStream. Events are posted
+ * normally, however if no listener returns that it has handled the event
+ * (returns true), it is placed in a queue. Subsequent attaching listeners
+ * will receive stored events from the queue until some listener indicates
+ * that the event has been handled.
+ *
+ * LLEventMailDrop completely decouples the timing of post() calls from
+ * listen() calls: every event posted to an LLEventMailDrop is eventually seen
+ * by all listeners, until some listener consumes it. The caveat is that each
+ * event *must* eventually reach a listener that will consume it, else the
+ * queue will grow to arbitrary length.
*
* @NOTE: When using an LLEventMailDrop (or LLEventQueue) with a LLEventTimeout or
- * LLEventFilter attaching the filter downstream using Timeout's constructor will
- * cause the MailDrop to discharge any of it's stored events. The timeout should
+ * LLEventFilter attaching the filter downstream, using Timeout's constructor will
+ * cause the MailDrop to discharge any of its stored events. The timeout should
* instead be connected upstream using its listen() method.
* See llcoro::suspendUntilEventOnWithTimeout() for an example.
*/
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 1fb3f2f381..b400ea070b 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -30,6 +30,7 @@
#if LL_WINDOWS
#include "llwin32headerslean.h"
#include // Windows errno
+#include
#else
#include
#endif
@@ -134,8 +135,10 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc
{
// Only do any of this stuff (before LL_ENDL) if it will be logged.
LL_DEBUGS("LLFile") << empty;
- const char* TEMP = getenv("TEMP");
- if (! TEMP)
+ // would be nice to use LLDir for this, but dependency goes the
+ // wrong way
+ const char* TEMP = LLFile::tmpdir();
+ if (! (TEMP && *TEMP))
{
LL_CONT << "No $TEMP, not running 'handle'";
}
@@ -385,17 +388,13 @@ const char *LLFile::tmpdir()
#if LL_WINDOWS
sep = '\\';
- DWORD len = GetTempPathW(0, L"");
- llutf16string utf16path;
- utf16path.resize(len + 1);
- len = GetTempPathW(static_cast(utf16path.size()), &utf16path[0]);
- utf8path = utf16str_to_utf8str(utf16path);
+ std::vector utf16path(MAX_PATH + 1);
+ GetTempPathW(utf16path.size(), &utf16path[0]);
+ utf8path = ll_convert_wide_to_string(&utf16path[0]);
#else
sep = '/';
- char *env = getenv("TMPDIR");
-
- utf8path = env ? env : "/tmp/";
+ utf8path = LLStringUtil::getenv("TMPDIR", "/tmp/");
#endif
if (utf8path[utf8path.size() - 1] != sep)
{
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index f1f4226c40..7f5b9b4ac2 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -2115,6 +2115,9 @@ namespace LLInitParam
typedef typename super_t::iterator iterator;
typedef typename super_t::const_iterator const_iterator;
+ using super_t::operator();
+ using super_t::operator const container_t&;
+
explicit Multiple(const char* name = "")
: super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
{}
diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp
index c87d2a3e58..cf8f8cc6a5 100644
--- a/indra/llcommon/llleap.cpp
+++ b/indra/llcommon/llleap.cpp
@@ -47,9 +47,9 @@ class LLLeapImpl: public LLLeap
LOG_CLASS(LLLeap);
public:
// Called only by LLLeap::create()
- LLLeapImpl(const std::string& desc, const std::vector& plugin):
+ LLLeapImpl(const LLProcess::Params& cparams):
// We might reassign mDesc in the constructor body if it's empty here.
- mDesc(desc),
+ mDesc(cparams.desc),
// We expect multiple LLLeapImpl instances. Definitely tweak
// mDonePump's name for uniqueness.
mDonePump("LLLeap", true),
@@ -67,17 +67,17 @@ public:
// this class or method name.
mListener(new LLLeapListener(boost::bind(&LLLeapImpl::connect, this, _1, _2)))
{
- // Rule out empty vector
- if (plugin.empty())
+ // Rule out unpopulated Params block
+ if (! cparams.executable.isProvided())
{
LLTHROW(Error("no plugin command"));
}
// Don't leave desc empty either, but in this case, if we weren't
// given one, we'll fake one.
- if (desc.empty())
+ if (mDesc.empty())
{
- mDesc = LLProcess::basename(plugin[0]);
+ mDesc = LLProcess::basename(cparams.executable);
// how about a toLower() variant that returns the transformed string?!
std::string desclower(mDesc);
LLStringUtil::toLower(desclower);
@@ -87,9 +87,9 @@ public:
// notice Python specially: we provide Python LLSD serialization
// support, so there's a pretty good reason to implement plugins
// in that language.
- if (plugin.size() >= 2 && (desclower == "python" || desclower == "python.exe"))
+ if (cparams.args.size() && (desclower == "python" || desclower == "python.exe"))
{
- mDesc = LLProcess::basename(plugin[1]);
+ mDesc = LLProcess::basename(cparams.args()[0]);
}
}
@@ -97,14 +97,10 @@ public:
mDonePump.listen("LLLeap", boost::bind(&LLLeapImpl::bad_launch, this, _1));
// Okay, launch child.
- LLProcess::Params params;
+ // Get a modifiable copy of params block to set files and postend.
+ LLProcess::Params params(cparams);
+ // copy our deduced mDesc back into the params block
params.desc = mDesc;
- std::vector::const_iterator pi(plugin.begin()), pend(plugin.end());
- params.executable = *pi++;
- for ( ; pi != pend; ++pi)
- {
- params.args.add(*pi);
- }
params.files.add(LLProcess::FileParam("pipe")); // stdin
params.files.add(LLProcess::FileParam("pipe")); // stdout
params.files.add(LLProcess::FileParam("pipe")); // stderr
@@ -429,17 +425,17 @@ private:
boost::scoped_ptr mListener;
};
-// This must follow the declaration of LLLeapImpl, so it may as well be last.
-LLLeap* LLLeap::create(const std::string& desc, const std::vector& plugin, bool exc)
+// These must follow the declaration of LLLeapImpl, so they may as well be last.
+LLLeap* LLLeap::create(const LLProcess::Params& params, bool exc)
{
// If caller is willing to permit exceptions, just instantiate.
if (exc)
- return new LLLeapImpl(desc, plugin);
+ return new LLLeapImpl(params);
// Caller insists on suppressing LLLeap::Error. Very well, catch it.
try
{
- return new LLLeapImpl(desc, plugin);
+ return new LLLeapImpl(params);
}
catch (const LLLeap::Error&)
{
@@ -447,6 +443,23 @@ LLLeap* LLLeap::create(const std::string& desc, const std::vector&
}
}
+LLLeap* LLLeap::create(const std::string& desc, const std::vector& plugin, bool exc)
+{
+ LLProcess::Params params;
+ params.desc = desc;
+ std::vector::const_iterator pi(plugin.begin()), pend(plugin.end());
+ // could validate here, but let's rely on LLLeapImpl's constructor
+ if (pi != pend)
+ {
+ params.executable = *pi++;
+ }
+ for ( ; pi != pend; ++pi)
+ {
+ params.args.add(*pi);
+ }
+ return create(params, exc);
+}
+
LLLeap* LLLeap::create(const std::string& desc, const std::string& plugin, bool exc)
{
// Use LLStringUtil::getTokens() to parse the command line
diff --git a/indra/llcommon/llleap.h b/indra/llcommon/llleap.h
index 8aac8a64c5..7cecdf2f8f 100644
--- a/indra/llcommon/llleap.h
+++ b/indra/llcommon/llleap.h
@@ -14,6 +14,7 @@
#include "llinstancetracker.h"
#include "llexception.h"
+#include "llprocess.h"
#include
#include
@@ -61,6 +62,19 @@ public:
static LLLeap* create(const std::string& desc, const std::string& plugin,
bool exc=true);
+ /**
+ * Pass an LLProcess::Params instance to specify desc, executable, args et al.
+ *
+ * Note that files and postend are set implicitly; any values you set in
+ * those fields will be disregarded.
+ *
+ * Pass exc=false to suppress LLLeap::Error exception. Obviously in that
+ * case the caller cannot discover the nature of the error, merely that an
+ * error of some kind occurred (because create() returned NULL). Either
+ * way, the error is logged.
+ */
+ static LLLeap* create(const LLProcess::Params& params, bool exc=true);
+
/**
* Exception thrown for invalid create() arguments, e.g. no plugin
* program. This is more resiliant than an LL_ERRS failure, because the
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 6958feffd1..6ad90db244 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -111,6 +111,9 @@
#endif
+// Although thread_local is now a standard storage class, we can't just
+// #define LL_THREAD_LOCAL as thread_local because the *usage* is different.
+// We'll have to take the time to change LL_THREAD_LOCAL declarations by hand.
#if LL_WINDOWS
# define LL_THREAD_LOCAL __declspec(thread)
#else
@@ -187,6 +190,24 @@
#define LL_DLLIMPORT
#endif // LL_WINDOWS
+#if ! defined(LL_WINDOWS)
+#define LL_WCHAR_T_NATIVE 1
+#else // LL_WINDOWS
+// https://docs.microsoft.com/en-us/cpp/preprocessor/predefined-macros
+// _WCHAR_T_DEFINED is defined if wchar_t is provided at all.
+// Specifically, it has value 1 if wchar_t is an intrinsic type, else empty.
+// _NATIVE_WCHAR_T_DEFINED has value 1 if wchar_t is intrinsic, else undefined.
+// For years we have compiled with /Zc:wchar_t-, meaning that wchar_t is a
+// typedef for unsigned short (in stddef.h). Lore has it that one of our
+// proprietary binary-only libraries has traditionally been built that way and
+// therefore EVERYTHING ELSE requires it. Therefore, in a typical Linden
+// Windows build, _WCHAR_T_DEFINED is defined but empty, while
+// _NATIVE_WCHAR_T_DEFINED is undefined.
+# if defined(_NATIVE_WCHAR_T_DEFINED)
+# define LL_WCHAR_T_NATIVE 1
+# endif // _NATIVE_WCHAR_T_DEFINED
+#endif // LL_WINDOWS
+
#if LL_COMMON_LINK_SHARED
// CMake automagically defines llcommon_EXPORTS only when building llcommon
// sources, and only when llcommon is a shared library (i.e. when
@@ -208,6 +229,8 @@
#define LL_TO_STRING_HELPER(x) #x
#define LL_TO_STRING(x) LL_TO_STRING_HELPER(x)
+#define LL_TO_WSTRING_HELPER(x) L#x
+#define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x)
#define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg
#define LL_GLUE_IMPL(x, y) x##y
#define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y)
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
index 5753efdc59..1fa53f322b 100644
--- a/indra/llcommon/llprocess.cpp
+++ b/indra/llcommon/llprocess.cpp
@@ -1205,30 +1205,9 @@ static LLProcess::Status interpret_status(int status)
/// GetLastError()/FormatMessage() boilerplate
static std::string WindowsErrorString(const std::string& operation)
{
- int result = GetLastError();
-
- LPTSTR error_str = 0;
- if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- result,
- 0,
- (LPTSTR)&error_str,
- 0,
- NULL)
- != 0)
- {
- // convert from wide-char string to multi-byte string
- char message[256];
- wcstombs(message, error_str, sizeof(message));
- message[sizeof(message)-1] = 0;
- LocalFree(error_str);
- // convert to std::string to trim trailing whitespace
- std::string mbsstr(message);
- mbsstr.erase(mbsstr.find_last_not_of(" \t\r\n"));
- return STRINGIZE(operation << " failed (" << result << "): " << mbsstr);
- }
- return STRINGIZE(operation << " failed (" << result
- << "), but FormatMessage() did not explain");
+ auto result = GetLastError();
+ return STRINGIZE(operation << " failed (" << result << "): "
+ << windows_message(result));
}
/*****************************************************************************
diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp
index e246d8b1a0..08551a3955 100644
--- a/indra/llcommon/llstring.cpp
+++ b/indra/llcommon/llstring.cpp
@@ -30,6 +30,7 @@
#include "llerror.h"
#include "llfasttimer.h"
#include "llsd.h"
+#include
#if LL_WINDOWS
#include "llwin32headerslean.h"
@@ -744,6 +745,11 @@ namespace snprintf_hack
}
}
+std::string ll_convert_wide_to_string(const wchar_t* in)
+{
+ return ll_convert_wide_to_string(in, CP_UTF8);
+}
+
std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
{
std::string out;
@@ -781,7 +787,12 @@ std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
return out;
}
-wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
+std::wstring ll_convert_string_to_wide(const std::string& in)
+{
+ return ll_convert_string_to_wide(in, CP_UTF8);
+}
+
+std::wstring ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
{
// From review:
// We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input,
@@ -791,28 +802,148 @@ wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page
// but we *are* seeing string operations taking a bunch of time, especially when constructing widgets.
// int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0);
- // reserve place to NULL terminator
- int output_str_len = in.length();
- wchar_t* w_out = new wchar_t[output_str_len + 1];
+ // reserve an output buffer that will be destroyed on exit, with a place
+ // to put NULL terminator
+ std::vector w_out(in.length() + 1);
- memset(w_out, 0, output_str_len + 1);
- int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len);
+ memset(&w_out[0], 0, w_out.size());
+ int real_output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(),
+ &w_out[0], w_out.size() - 1);
//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858.
w_out[real_output_str_len] = 0;
- return w_out;
+ // construct string from our temporary output buffer
+ return {&w_out[0]};
+}
+
+LLWString ll_convert_wide_to_wstring(const std::wstring& in)
+{
+ // This function, like its converse, is a placeholder, encapsulating a
+ // guilty little hack: the only "official" way nat has found to convert
+ // between std::wstring (16 bits on Windows) and LLWString (UTF-32) is
+ // by using iconv, which we've avoided so far. It kinda sorta works to
+ // just copy individual characters...
+ // The point is that if/when we DO introduce some more official way to
+ // perform such conversions, we should only have to call it here.
+ return { in.begin(), in.end() };
+}
+
+std::wstring ll_convert_wstring_to_wide(const LLWString& in)
+{
+ // See comments in ll_convert_wide_to_wstring()
+ return { in.begin(), in.end() };
}
std::string ll_convert_string_to_utf8_string(const std::string& in)
{
- wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP);
- std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8));
- delete[] w_mesg;
+ auto w_mesg = ll_convert_string_to_wide(in, CP_ACP);
+ std::string out_utf8(ll_convert_wide_to_string(w_mesg.c_str(), CP_UTF8));
return out_utf8;
}
-#endif // LL_WINDOWS
+
+namespace
+{
+
+void HeapFree_deleter(void* ptr)
+{
+ // instead of LocalFree(), per https://stackoverflow.com/a/31541205
+ HeapFree(GetProcessHeap(), NULL, ptr);
+}
+
+} // anonymous namespace
+
+template<>
+std::wstring windows_message(DWORD error)
+{
+ // derived from https://stackoverflow.com/a/455533
+ wchar_t* rawptr = nullptr;
+ auto okay = FormatMessageW(
+ // use system message tables for GetLastError() codes
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ // internally allocate buffer and return its pointer
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ // you cannot pass insertion parameters (thanks Gandalf)
+ FORMAT_MESSAGE_IGNORE_INSERTS |
+ // ignore line breaks in message definition text
+ FORMAT_MESSAGE_MAX_WIDTH_MASK,
+ NULL, // lpSource, unused with FORMAT_MESSAGE_FROM_SYSTEM
+ error, // dwMessageId
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // dwLanguageId
+ (LPWSTR)&rawptr, // lpBuffer: force-cast wchar_t** to wchar_t*
+ 0, // nSize, unused with FORMAT_MESSAGE_ALLOCATE_BUFFER
+ NULL); // Arguments, unused
+
+ // make a unique_ptr from rawptr so it gets cleaned up properly
+ std::unique_ptr bufferptr(rawptr, HeapFree_deleter);
+
+ if (okay && bufferptr)
+ {
+ // got the message, return it ('okay' is length in characters)
+ return { bufferptr.get(), okay };
+ }
+
+ // did not get the message, synthesize one
+ auto format_message_error = GetLastError();
+ std::wostringstream out;
+ out << L"GetLastError() " << error << L" (FormatMessageW() failed with "
+ << format_message_error << L")";
+ return out.str();
+}
+
+boost::optional llstring_getoptenv(const std::string& key)
+{
+ auto wkey = ll_convert_string_to_wide(key);
+ // Take a wild guess as to how big the buffer should be.
+ std::vector buffer(1024);
+ auto n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
+ // If our initial guess was too short, n will indicate the size (in
+ // wchar_t's) that buffer should have been, including the terminating nul.
+ if (n > (buffer.size() - 1))
+ {
+ // make it big enough
+ buffer.resize(n);
+ // and try again
+ n = GetEnvironmentVariableW(wkey.c_str(), &buffer[0], buffer.size());
+ }
+ // did that (ultimately) succeed?
+ if (n)
+ {
+ // great, return populated boost::optional
+ return boost::optional(&buffer[0]);
+ }
+
+ // not successful
+ auto last_error = GetLastError();
+ // Don't bother warning for NOT_FOUND; that's an expected case
+ if (last_error != ERROR_ENVVAR_NOT_FOUND)
+ {
+ LL_WARNS() << "GetEnvironmentVariableW('" << key << "') failed: "
+ << windows_message(last_error) << LL_ENDL;
+ }
+ // return empty boost::optional
+ return {};
+}
+
+#else // ! LL_WINDOWS
+
+boost::optional llstring_getoptenv(const std::string& key)
+{
+ auto found = getenv(key.c_str());
+ if (found)
+ {
+ // return populated boost::optional
+ return boost::optional(found);
+ }
+ else
+ {
+ // return empty boost::optional
+ return {};
+ }
+}
+
+#endif // ! LL_WINDOWS
long LLStringOps::sPacificTimeOffset = 0;
long LLStringOps::sLocalTimeOffset = 0;
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index 9c030473fb..ab35612430 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -27,6 +27,7 @@
#ifndef LL_LLSTRING_H
#define LL_LLSTRING_H
+#include
#include
#include
//#include
@@ -341,6 +342,19 @@ public:
const string_type& string,
const string_type& substr);
+ /**
+ * get environment string value with proper Unicode handling
+ * (key is always UTF-8)
+ * detect absence by return value == dflt
+ */
+ static string_type getenv(const std::string& key, const string_type& dflt="");
+ /**
+ * get optional environment string value with proper Unicode handling
+ * (key is always UTF-8)
+ * detect absence by (! return value)
+ */
+ static boost::optional getoptenv(const std::string& key);
+
static void addCRLF(string_type& string);
static void removeCRLF(string_type& string);
static void removeWindowsCR(string_type& string);
@@ -500,6 +514,37 @@ LL_COMMON_API bool iswindividual(llwchar elem);
* Unicode support
*/
+/// generic conversion aliases
+template
+struct ll_convert_impl
+{
+ // Don't even provide a generic implementation. We specialize for every
+ // combination we do support.
+ TO operator()(const FROM& in) const;
+};
+
+// Use a function template to get the nice ll_convert(from_value) API.
+template
+TO ll_convert(const FROM& in)
+{
+ return ll_convert_impl()(in);
+}
+
+// degenerate case
+template
+struct ll_convert_impl
+{
+ T operator()(const T& in) const { return in; }
+};
+
+// specialize ll_convert_impl to return EXPR
+#define ll_convert_alias(TO, FROM, EXPR) \
+template<> \
+struct ll_convert_impl \
+{ \
+ TO operator()(const FROM& in) const { return EXPR; } \
+}
+
// Make the incoming string a utf8 string. Replaces any unknown glyph
// with the UNKNOWN_CHARACTER. Once any unknown glyph is found, the rest
// of the data may not be recovered.
@@ -507,30 +552,88 @@ LL_COMMON_API std::string rawstr_to_utf8(const std::string& raw);
//
// We should never use UTF16 except when communicating with Win32!
+// https://docs.microsoft.com/en-us/cpp/cpp/char-wchar-t-char16-t-char32-t
+// nat 2018-12-14: I consider the whole llutf16string thing a mistake, because
+// the Windows APIs we want to call are all defined in terms of wchar_t*
+// (or worse, LPCTSTR).
+// https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types
+
+// While there is no point coding for an ASCII-only world (! defined(UNICODE)),
+// use of U16 and llutf16string for Windows APIs locks in /Zc:wchar_t-. Going
+// forward, we should code in terms of wchar_t and std::wstring so as to
+// support either setting of /Zc:wchar_t.
+
+// The first link above states that char can be used to hold ASCII or any
+// multi-byte character set, and distinguishes wchar_t (UTF-16LE), char16_t
+// (UTF-16) and char32_t (UTF-32). Nonetheless, within this code base:
+// * char and std::string always hold UTF-8 (of which ASCII is a subset). It
+// is a BUG if they are used to pass strings in any other multi-byte
+// encoding.
+// * wchar_t and std::wstring should be our interface to Windows wide-string
+// APIs, and therefore hold UTF-16LE.
+// * U16 and llutf16string are the previous but DEPRECATED UTF-16LE type. Do
+// not introduce new uses of U16 or llutf16string for string data.
+// * llwchar and LLWString hold UTF-32 strings.
+// * Do not introduce char16_t or std::u16string.
+// * Do not introduce char32_t or std::u32string.
//
+// This typedef may or may not be identical to std::wstring, depending on
+// LL_WCHAR_T_NATIVE.
typedef std::basic_string llutf16string;
+#if ! defined(LL_WCHAR_T_NATIVE)
+// wchar_t is identical to U16, and std::wstring is identical to llutf16string.
+// Defining an ll_convert alias involving llutf16string would collide with the
+// comparable preferred alias involving std::wstring. (In this scenario, if
+// you pass llutf16string, it will engage the std::wstring specialization.)
+#define ll_convert_u16_alias(TO, FROM, EXPR) // nothing
+#else // defined(LL_WCHAR_T_NATIVE)
+// wchar_t is a distinct native type, so llutf16string is also a distinct
+// type, and there IS a point to converting separately to/from llutf16string.
+// (But why? Windows APIs are still defined in terms of wchar_t, and
+// in this scenario llutf16string won't work for them!)
+#define ll_convert_u16_alias(TO, FROM, EXPR) ll_convert_alias(TO, FROM, EXPR)
+
+#if LL_WINDOWS
+// LL_WCHAR_T_NATIVE is defined on non-Windows systems because, in fact,
+// wchar_t is native. Everywhere but Windows, we use it for llwchar (see
+// stdtypes.h). That makes LLWString identical to std::wstring, so these
+// aliases for std::wstring would collide with those for LLWString. Only
+// define on Windows, where converting between std::wstring and llutf16string
+// means copying chars.
+ll_convert_alias(llutf16string, std::wstring, llutf16string(in.begin(), in.end()));
+ll_convert_alias(std::wstring, llutf16string, std::wstring(in.begin(), in.end()));
+#endif // LL_WINDOWS
+#endif // defined(LL_WCHAR_T_NATIVE)
+
LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str, S32 len);
LL_COMMON_API LLWString utf16str_to_wstring(const llutf16string &utf16str);
+ll_convert_u16_alias(LLWString, llutf16string, utf16str_to_wstring(in));
LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str, S32 len);
LL_COMMON_API llutf16string wstring_to_utf16str(const LLWString &utf32str);
+ll_convert_u16_alias(llutf16string, LLWString, wstring_to_utf16str(in));
LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str, S32 len);
LL_COMMON_API llutf16string utf8str_to_utf16str ( const std::string& utf8str );
+ll_convert_u16_alias(llutf16string, std::string, utf8str_to_utf16str(in));
LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str, S32 len);
LL_COMMON_API LLWString utf8str_to_wstring(const std::string &utf8str);
// Same function, better name. JC
inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); }
+// best name of all
+ll_convert_alias(LLWString, std::string, utf8string_to_wstring(in));
//
LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars);
LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str, S32 len);
LL_COMMON_API std::string wstring_to_utf8str(const LLWString &utf32str);
+ll_convert_alias(std::string, LLWString, wstring_to_utf8str(in));
LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str, S32 len);
LL_COMMON_API std::string utf16str_to_utf8str(const llutf16string &utf16str);
+ll_convert_u16_alias(std::string, llutf16string, utf16str_to_utf8str(in));
#if LL_WINDOWS
inline std::string wstring_to_utf8str(const llutf16string &utf16str) { return utf16str_to_utf8str(utf16str);}
@@ -644,22 +747,77 @@ using snprintf_hack::snprintf;
* This replaces the unsafe W2A macro from ATL.
*/
LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page);
+LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in); // default CP_UTF8
+inline std::string ll_convert_wide_to_string(const std::wstring& in, unsigned int code_page)
+{
+ return ll_convert_wide_to_string(in.c_str(), code_page);
+}
+inline std::string ll_convert_wide_to_string(const std::wstring& in)
+{
+ return ll_convert_wide_to_string(in.c_str());
+}
+ll_convert_alias(std::string, std::wstring, ll_convert_wide_to_string(in));
/**
* Converts a string to wide string.
- *
- * It will allocate memory for result string with "new []". Don't forget to release it with "delete []".
*/
-LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page);
+LL_COMMON_API std::wstring ll_convert_string_to_wide(const std::string& in,
+ unsigned int code_page);
+LL_COMMON_API std::wstring ll_convert_string_to_wide(const std::string& in);
+ // default CP_UTF8
+ll_convert_alias(std::wstring, std::string, ll_convert_string_to_wide(in));
/**
- * Converts incoming string into urf8 string
+ * Convert a Windows wide string to our LLWString
+ */
+LL_COMMON_API LLWString ll_convert_wide_to_wstring(const std::wstring& in);
+ll_convert_alias(LLWString, std::wstring, ll_convert_wide_to_wstring(in));
+
+/**
+ * Convert LLWString to Windows wide string
+ */
+LL_COMMON_API std::wstring ll_convert_wstring_to_wide(const LLWString& in);
+ll_convert_alias(std::wstring, LLWString, ll_convert_wstring_to_wide(in));
+
+/**
+ * Converts incoming string into utf8 string
*
*/
LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in);
+/// Get Windows message string for passed GetLastError() code
+// VS 2013 doesn't let us forward-declare this template, which is what we
+// started with, so the implementation could reference the specialization we
+// haven't yet declared. Somewhat weirdly, just stating the generic
+// implementation in terms of the specialization works, even in this order...
+
+// the general case is just a conversion from the sole implementation
+// Microsoft says DWORD is a typedef for unsigned long
+// https://docs.microsoft.com/en-us/windows/desktop/winprog/windows-data-types
+// so rather than drag windows.h into everybody's include space...
+template
+STRING windows_message(unsigned long error)
+{
+ return ll_convert(windows_message(error));
+}
+
+/// There's only one real implementation
+template<>
+LL_COMMON_API std::wstring windows_message(unsigned long error);
+
+/// Get Windows message string, implicitly calling GetLastError()
+template
+STRING windows_message() { return windows_message(GetLastError()); }
+
//@}
-#endif // LL_WINDOWS
+
+LL_COMMON_API boost::optional llstring_getoptenv(const std::string& key);
+
+#else // ! LL_WINDOWS
+
+LL_COMMON_API boost::optional llstring_getoptenv(const std::string& key);
+
+#endif // ! LL_WINDOWS
/**
* Many of the 'strip' and 'replace' methods of LLStringUtilBase need
@@ -1602,6 +1760,37 @@ bool LLStringUtilBase::endsWith(
return (idx == (string.size() - substr.size()));
}
+// static
+template
+auto LLStringUtilBase::getoptenv(const std::string& key) -> boost::optional
+{
+ auto found(llstring_getoptenv(key));
+ if (found)
+ {
+ // return populated boost::optional
+ return { ll_convert(*found) };
+ }
+ else
+ {
+ // empty boost::optional
+ return {};
+ }
+}
+
+// static
+template
+auto LLStringUtilBase::getenv(const std::string& key, const string_type& dflt) -> string_type
+{
+ auto found(getoptenv(key));
+ if (found)
+ {
+ return *found;
+ }
+ else
+ {
+ return dflt;
+ }
+}
template
BOOL LLStringUtilBase::convertToBOOL(const string_type& string, BOOL& value)
diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h
index bf3f3f9ee8..6c9871e76c 100644
--- a/indra/llcommon/stdtypes.h
+++ b/indra/llcommon/stdtypes.h
@@ -37,7 +37,12 @@ typedef signed int S32;
typedef unsigned int U32;
#if LL_WINDOWS
-// Windows wchar_t is 16-bit
+// https://docs.microsoft.com/en-us/cpp/build/reference/zc-wchar-t-wchar-t-is-native-type
+// https://docs.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp
+// Windows wchar_t is 16-bit, whichever way /Zc:wchar_t is set. In effect,
+// Windows wchar_t is always a typedef, either for unsigned short or __wchar_t.
+// (__wchar_t, available either way, is Microsoft's native 2-byte wchar_t type.)
+// In any case, llwchar should be a UTF-32 type.
typedef U32 llwchar;
#else
typedef wchar_t llwchar;
diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index a5a90d7297..38dd198ad3 100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -30,7 +30,6 @@
#define LL_STRINGIZE_H
#include
-#include
#include
/**
@@ -53,12 +52,7 @@ std::basic_string gstringize(const T& item)
*/
inline std::string stringize(const std::wstring& item)
{
- LL_WARNS() << "WARNING: Possible narrowing" << LL_ENDL;
-
- std::string s;
-
- s = wstring_to_utf8str(item);
- return gstringize(s);
+ return wstring_to_utf8str(item);
}
/**
@@ -76,7 +70,10 @@ std::string stringize(const T& item)
*/
inline std::wstring wstringize(const std::string& item)
{
- return gstringize(item.c_str());
+ // utf8str_to_wstring() returns LLWString, which isn't necessarily the
+ // same as std::wstring
+ LLWString s(utf8str_to_wstring(item));
+ return std::wstring(s.begin(), s.end());
}
/**
@@ -91,10 +88,10 @@ std::wstring wstringize(const T& item)
/**
* stringize_f(functor)
*/
-template
-std::string stringize_f(Functor const & f)
+template
+std::basic_string stringize_f(Functor const & f)
{
- std::ostringstream out;
+ std::basic_ostringstream out;
f(out);
return out.str();
}
@@ -108,31 +105,37 @@ std::string stringize_f(Functor const & f)
* return out.str();
* @endcode
*/
-#define STRINGIZE(EXPRESSION) (stringize_f(boost::phoenix::placeholders::arg1 << EXPRESSION))
+#define STRINGIZE(EXPRESSION) (stringize_f([&](std::ostream& out){ out << EXPRESSION; }))
+/**
+ * WSTRINGIZE() is the wstring equivalent of STRINGIZE()
+ */
+#define WSTRINGIZE(EXPRESSION) (stringize_f([&](std::wostream& out){ out << EXPRESSION; }))
/**
* destringize(str)
* defined for symmetry with stringize
- * *NOTE - this has distinct behavior from boost::lexical_cast regarding
+ * @NOTE - this has distinct behavior from boost::lexical_cast regarding
* leading/trailing whitespace and handling of bad_lexical_cast exceptions
+ * @NOTE - no need for dewstringize(), since passing std::wstring will Do The
+ * Right Thing
*/
-template
-T destringize(std::string const & str)
+template
+T destringize(std::basic_string const & str)
{
- T val;
- std::istringstream in(str);
- in >> val;
+ T val;
+ std::basic_istringstream in(str);
+ in >> val;
return val;
}
/**
* destringize_f(str, functor)
*/
-template
-void destringize_f(std::string const & str, Functor const & f)
+template
+void destringize_f(std::basic_string const & str, Functor const & f)
{
- std::istringstream in(str);
+ std::basic_istringstream in(str);
f(in);
}
@@ -143,8 +146,11 @@ void destringize_f(std::string const & str, Functor const & f)
* std::istringstream in(str);
* in >> item1 >> item2 >> item3 ... ;
* @endcode
+ * @NOTE - once we get generic lambdas, we shouldn't need DEWSTRINGIZE() any
+ * more since DESTRINGIZE() should do the right thing with a std::wstring. But
+ * until then, the lambda we pass must accept the right std::basic_istream.
*/
-#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), (boost::phoenix::placeholders::arg1 >> EXPRESSION)))
-
+#define DESTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::istream& in){in >> EXPRESSION;}))
+#define DEWSTRINGIZE(STR, EXPRESSION) (destringize_f((STR), [&](std::wistream& in){in >> EXPRESSION;}))
#endif /* ! defined(LL_STRINGIZE_H) */
diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index ce0dbce075..8e1f4c14ac 100644
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
@@ -78,8 +78,12 @@ namespace tut
class TestRecorder : public LLError::Recorder
{
public:
- TestRecorder() { mWantsTime = false; mWantsTags = true; }
- virtual ~TestRecorder() { }
+ TestRecorder()
+ {
+ showTime(false);
+ }
+ virtual ~TestRecorder()
+ {}
virtual void recordMessage(LLError::ELevel level,
const std::string& message)
@@ -90,8 +94,6 @@ namespace tut
int countMessages() { return (int) mMessages.size(); }
void clearMessages() { mMessages.clear(); }
- void setWantsTime(bool t) { mWantsTime = t; }
-
std::string message(int n)
{
std::ostringstream test_name;
@@ -139,9 +141,14 @@ namespace tut
}
void setWantsTime(bool t)
- {
- boost::dynamic_pointer_cast(mRecorder)->setWantsTime(t);
- }
+ {
+ boost::dynamic_pointer_cast(mRecorder)->showTime(t);
+ }
+
+ void setWantsMultiline(bool t)
+ {
+ boost::dynamic_pointer_cast(mRecorder)->showMultiline(t);
+ }
std::string message(int n)
{
@@ -378,27 +385,6 @@ namespace
}
}
-namespace tut
-{
- template<> template<>
- void ErrorTestObject::test<5>()
- // file and line information in log messages
- {
- std::string location = writeReturningLocation();
- // expecting default to not print location information
-
- LLError::setPrintLocation(true);
- writeReturningLocation();
-
- LLError::setPrintLocation(false);
- writeReturningLocation();
-
- ensure_message_does_not_contain(0, location);
- ensure_message_field_equals(1, LOCATION_FIELD, location);
- ensure_message_does_not_contain(2, location);
- }
-}
-
/* The following helper functions and class members all log a simple message
from some particular function scope. Each function takes a bool argument
that indicates if it should log its own name or not (in the manner that
@@ -512,6 +498,39 @@ namespace
}
}
+namespace
+{
+ void writeMsgNeedsEscaping()
+ {
+ LL_DEBUGS("WriteTag") << "backslash\\" << LL_ENDL;
+ LL_INFOS("WriteTag") << "newline\nafternewline" << LL_ENDL;
+ LL_WARNS("WriteTag") << "return\rafterreturn" << LL_ENDL;
+
+ LL_DEBUGS("WriteTag") << "backslash\\backslash\\" << LL_ENDL;
+ LL_INFOS("WriteTag") << "backslash\\newline\nanothernewline\nafternewline" << LL_ENDL;
+ LL_WARNS("WriteTag") << "backslash\\returnnewline\r\n\\afterbackslash" << LL_ENDL;
+ }
+};
+
+namespace tut
+{
+ template<> template<>
+ void ErrorTestObject::test<5>()
+ // backslash, return, and newline are not escaped with backslashes
+ {
+ LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+ setWantsMultiline(true);
+ writeMsgNeedsEscaping(); // but should not be now
+ ensure_message_field_equals(0, MSG_FIELD, "backslash\\");
+ ensure_message_field_equals(1, MSG_FIELD, "newline\nafternewline");
+ ensure_message_field_equals(2, MSG_FIELD, "return\rafterreturn");
+ ensure_message_field_equals(3, MSG_FIELD, "backslash\\backslash\\");
+ ensure_message_field_equals(4, MSG_FIELD, "backslash\\newline\nanothernewline\nafternewline");
+ ensure_message_field_equals(5, MSG_FIELD, "backslash\\returnnewline\r\n\\afterbackslash");
+ ensure_message_count(6);
+ }
+}
+
namespace tut
{
template<> template<>
@@ -583,7 +602,6 @@ namespace tut
// special handling of LL_ERRS() calls
void ErrorTestObject::test<8>()
{
- LLError::setPrintLocation(false);
std::string location = errorReturningLocation();
ensure_message_field_equals(0, LOCATION_FIELD, location);
@@ -630,15 +648,15 @@ namespace tut
// output order
void ErrorTestObject::test<10>()
{
- LLError::setPrintLocation(true);
LLError::setTimeFunction(roswell);
setWantsTime(true);
+
std::string location,
function;
writeReturningLocationAndFunction(location, function);
ensure_equals("order is time level tags location function message",
- message(0),
+ message(0),
roswell() + " INFO " + "# " /* no tag */ + location + " " + function + " : " + "apple");
}
@@ -658,7 +676,7 @@ namespace tut
LLError::setTimeFunction(roswell);
LLError::RecorderPtr anotherRecorder(new TestRecorder());
- boost::dynamic_pointer_cast(anotherRecorder)->setWantsTime(true);
+ boost::dynamic_pointer_cast(anotherRecorder)->showTime(true);
LLError::addRecorder(anotherRecorder);
LL_INFOS() << "baz" << LL_ENDL;
@@ -835,20 +853,6 @@ namespace tut
}
}
-namespace
-{
- void writeMsgNeedsEscaping()
- {
- LL_DEBUGS("WriteTag") << "backslash\\" << LL_ENDL;
- LL_INFOS("WriteTag") << "newline\nafternewline" << LL_ENDL;
- LL_WARNS("WriteTag") << "return\rafterreturn" << LL_ENDL;
-
- LL_DEBUGS("WriteTag") << "backslash\\backslash\\" << LL_ENDL;
- LL_INFOS("WriteTag") << "backslash\\newline\nanothernewline\nafternewline" << LL_ENDL;
- LL_WARNS("WriteTag") << "backslash\\returnnewline\r\n\\afterbackslash" << LL_ENDL;
- }
-};
-
namespace tut
{
template<> template<>
diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
index c387da6c48..45648536c4 100644
--- a/indra/llcommon/tests/llleap_test.cpp
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -26,6 +26,7 @@
#include "wrapllerrs.h"
#include "llevents.h"
#include "llprocess.h"
+#include "llstring.h"
#include "stringize.h"
#include "StringVec.h"
#include
@@ -198,14 +199,12 @@ namespace tut
// basename.
reader_module(LLProcess::basename(
reader.getName().substr(0, reader.getName().length()-3))),
- pPYTHON(getenv("PYTHON")),
- PYTHON(pPYTHON? pPYTHON : "")
+ PYTHON(LLStringUtil::getenv("PYTHON"))
{
- ensure("Set PYTHON to interpreter pathname", pPYTHON);
+ ensure("Set PYTHON to interpreter pathname", !PYTHON.empty());
}
NamedExtTempFile reader;
const std::string reader_module;
- const char* pPYTHON;
const std::string PYTHON;
};
typedef test_group llleap_group;
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index b27e125d2e..5c87cdabd9 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -34,6 +34,7 @@
#include "stringize.h"
#include "llsdutil.h"
#include "llevents.h"
+#include "llstring.h"
#include "wrapllerrs.h"
#if defined(LL_WINDOWS)
@@ -142,8 +143,8 @@ struct PythonProcessLauncher
mDesc(desc),
mScript("py", script)
{
- const char* PYTHON(getenv("PYTHON"));
- tut::ensure("Set $PYTHON to the Python interpreter", PYTHON);
+ auto PYTHON(LLStringUtil::getenv("PYTHON"));
+ tut::ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
mParams.desc = desc + " script";
mParams.executable = PYTHON;
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index 745e3a168c..6ac974e659 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -41,6 +41,7 @@ typedef U32 uint32_t;
#include
#include
#include "llprocess.h"
+#include "llstring.h"
#endif
#include "boost/range.hpp"
@@ -1705,8 +1706,8 @@ namespace tut
template
void python(const std::string& desc, const CONTENT& script, int expect=0)
{
- const char* PYTHON(getenv("PYTHON"));
- ensure("Set $PYTHON to the Python interpreter", PYTHON);
+ auto PYTHON(LLStringUtil::getenv("PYTHON"));
+ ensure("Set $PYTHON to the Python interpreter", !PYTHON.empty());
NamedTempFile scriptfile("py", script);
@@ -1714,7 +1715,7 @@ namespace tut
std::string q("\"");
std::string qPYTHON(q + PYTHON + q);
std::string qscript(q + scriptfile.getName() + q);
- int rc = _spawnl(_P_WAIT, PYTHON, qPYTHON.c_str(), qscript.c_str(), NULL);
+ int rc = _spawnl(_P_WAIT, PYTHON.c_str(), qPYTHON.c_str(), qscript.c_str(), NULL);
if (rc == -1)
{
char buffer[256];
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index 9a4bbbd630..08fbf19b1c 100644
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
@@ -109,6 +109,12 @@ public:
mMessages.push_back(message);
}
+ friend inline
+ std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
+ {
+ return log.streamto(out);
+ }
+
/// Don't assume the message we want is necessarily the LAST log message
/// emitted by the underlying code; search backwards through all messages
/// for the sought string.
@@ -126,7 +132,7 @@ public:
throw tut::failure(STRINGIZE("failed to find '" << search
<< "' in captured log messages:\n"
- << boost::ref(*this)));
+ << *this));
}
std::ostream& streamto(std::ostream& out) const
@@ -200,10 +206,4 @@ private:
LLError::RecorderPtr mRecorder;
};
-inline
-std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log)
-{
- return log.streamto(out);
-}
-
#endif /* ! defined(LL_WRAPLLERRS_H) */
diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt
index 97d22cf86a..c9423d50dd 100644
--- a/indra/llimagej2coj/CMakeLists.txt
+++ b/indra/llimagej2coj/CMakeLists.txt
@@ -29,7 +29,9 @@ set_source_files_properties(${llimagej2coj_HEADER_FILES}
list(APPEND llimagej2coj_SOURCE_FILES ${llimagej2coj_HEADER_FILES})
add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES})
+
target_link_libraries(
llimagej2coj
${OPENJPEG_LIBRARIES}
)
+
diff --git a/indra/llmessage/tests/commtest.h b/indra/llmessage/tests/commtest.h
index 7c8f27bbd2..0359eba803 100644
--- a/indra/llmessage/tests/commtest.h
+++ b/indra/llmessage/tests/commtest.h
@@ -34,6 +34,7 @@
#include "llsd.h"
#include "llhost.h"
#include "llexception.h"
+#include "llstring.h"
#include "stringize.h"
#include
#include
@@ -46,12 +47,7 @@ struct CommtestError: public LLException
static bool query_verbose()
{
- const char* cbose = getenv("INTEGRATION_TEST_VERBOSE");
- if (! cbose)
- {
- cbose = "1";
- }
- std::string strbose(cbose);
+ std::string strbose(LLStringUtil::getenv("INTEGRATION_TEST_VERBOSE", "1"));
return (! (strbose == "0" || strbose == "off" ||
strbose == "false" || strbose == "quiet"));
}
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index 9356a14f1f..78faa66a0d 100644
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -41,6 +41,7 @@
#include "llpumpio.h"
#include "lliosocket.h"
+#include "llstring.h"
#include "stringize.h"
#include "llcleanup.h"
@@ -50,13 +51,13 @@ namespace tut
{
public:
HTTPClientTestData():
- PORT(getenv("PORT")),
+ PORT(LLStringUtil::getenv("PORT")),
// Turning NULL PORT into empty string doesn't make things work;
// that's just to keep this initializer from blowing up. We test
// PORT separately in the constructor body.
- local_server(STRINGIZE("http://127.0.0.1:" << (PORT? PORT : "") << "/"))
+ local_server(STRINGIZE("http://127.0.0.1:" << PORT << "/"))
{
- ensure("Set environment variable PORT to local test server port", PORT);
+ ensure("Set environment variable PORT to local test server port", !PORT.empty());
apr_pool_create(&mPool, NULL);
LLCurl::initClass(false);
mClientPump = new LLPumpIO(mPool);
@@ -87,7 +88,7 @@ namespace tut
}
}
- const char* const PORT;
+ const std::string PORT;
const std::string local_server;
private:
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index e0c688c6c9..2d9198d037 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -48,7 +48,7 @@ add_executable(SLPlugin
WIN32
MACOSX_BUNDLE
${SLPlugin_SOURCE_FILES}
-)
+ )
if (WINDOWS)
set_target_properties(SLPlugin
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 1f9a6664e1..4e95e636b6 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -40,10 +40,17 @@
#include "v4color.h"
#include "lltexture.h"
#include "lldir.h"
+#include "llstring.h"
// Third party library includes
#include
+#if LL_WINDOWS
+#include
+#include
+#include
+#endif // LL_WINDOWS
+
const S32 BOLD_OFFSET = 1;
// static class members
@@ -1156,33 +1163,33 @@ LLFontGL* LLFontGL::getFontDefault()
// static
std::string LLFontGL::getFontPathSystem()
{
- std::string system_path;
+#if LL_DARWIN
+ // HACK for Mac OS X
+ return "/System/Library/Fonts/";
- // Try to figure out where the system's font files are stored.
- char *system_root = NULL;
-#if LL_WINDOWS
- system_root = getenv("SystemRoot"); /* Flawfinder: ignore */
- if (!system_root)
- {
- LL_WARNS() << "SystemRoot not found, attempting to load fonts from default path." << LL_ENDL;
- }
+#elif LL_WINDOWS
+ auto system_root = LLStringUtil::getenv("SystemRoot");
+ if (! system_root.empty())
+ {
+ std::string fontpath(gDirUtilp->add(system_root, "fonts") + gDirUtilp->getDirDelimiter());
+ LL_INFOS() << "from SystemRoot: " << fontpath << LL_ENDL;
+ return fontpath;
+ }
+
+ wchar_t *pwstr = NULL;
+ HRESULT okay = SHGetKnownFolderPath(FOLDERID_Fonts, 0, NULL, &pwstr);
+ if (SUCCEEDED(okay) && pwstr)
+ {
+ std::string fontpath(ll_convert_wide_to_string(pwstr));
+ // SHGetKnownFolderPath() contract requires us to free pwstr
+ CoTaskMemFree(pwstr);
+ LL_INFOS() << "from SHGetKnownFolderPath(): " << fontpath << LL_ENDL;
+ return fontpath;
+ }
#endif
- if (system_root)
- {
- system_path = llformat("%s/fonts/", system_root);
- }
- else
- {
-#if LL_WINDOWS
- // HACK for windows 98/Me
- system_path = "/WINDOWS/FONTS/";
-#elif LL_DARWIN
- // HACK for Mac OS X
- system_path = "/System/Library/Fonts/";
-#endif
- }
- return system_path;
+ LL_WARNS() << "Could not determine system fonts path" << LL_ENDL;
+ return {};
}
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
index b6a32a0e78..be26416cbb 100644
--- a/indra/llui/llnotificationslistener.cpp
+++ b/indra/llui/llnotificationslistener.cpp
@@ -90,9 +90,12 @@ void LLNotificationsListener::requestAdd(const LLSD& event_data) const
{
if(event_data.has("reply"))
{
+ LLSD payload(event_data["payload"]);
+ // copy reqid, if provided, to link response with request
+ payload["reqid"] = event_data["reqid"];
mNotifications.add(event_data["name"],
event_data["substitutions"],
- event_data["payload"],
+ payload,
boost::bind(&LLNotificationsListener::NotificationResponder,
this,
event_data["reply"].asString(),
@@ -112,10 +115,12 @@ void LLNotificationsListener::NotificationResponder(const std::string& reply_pum
const LLSD& notification,
const LLSD& response) const
{
- LLSD reponse_event;
- reponse_event["notification"] = notification;
- reponse_event["response"] = response;
- LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
+ LLSD response_event;
+ response_event["notification"] = notification;
+ response_event["response"] = response;
+ // surface reqid at top level of response for request/response protocol
+ response_event["reqid"] = notification["payload"]["reqid"];
+ LLEventPumps::getInstance()->obtain(reply_pump).post(response_event);
}
void LLNotificationsListener::listChannels(const LLSD& params) const
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 7037265c17..8905cef552 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -42,6 +42,7 @@
#include "lldiriterator.h"
#include "stringize.h"
+#include "llstring.h"
#include
#include
#include
@@ -323,9 +324,9 @@ const std::string& LLDir::getChatLogsDir() const
void LLDir::setDumpDir( const std::string& path )
{
LLDir::sDumpDir = path;
- if (! sDumpDir.empty() && sDumpDir.rbegin() == mDirDelimiter.rbegin() )
+ if (LLStringUtil::endsWith(sDumpDir, mDirDelimiter))
{
- sDumpDir.erase(sDumpDir.size() -1);
+ sDumpDir.erase(sDumpDir.size() - mDirDelimiter.size());
}
}
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index f357210022..2e92e13bfd 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -29,6 +29,7 @@
#include "lldir_linux.h"
#include "llerror.h"
#include "llrand.h"
+#include "llstring.h"
#include
#include
#include
@@ -40,28 +41,24 @@ static std::string getCurrentUserHome(char* fallback)
{
const uid_t uid = getuid();
struct passwd *pw;
- char *result_cstr = fallback;
-
+
pw = getpwuid(uid);
if ((pw != NULL) && (pw->pw_dir != NULL))
{
- result_cstr = (char*) pw->pw_dir;
+ return pw->pw_dir;
+ }
+
+ LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
+ auto home_env = LLStringUtil::getoptenv("HOME");
+ if (home_env)
+ {
+ return *home_env;
}
else
{
- LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
- const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */
- if (home_env)
- {
- result_cstr = (char*) home_env;
- }
- else
- {
- LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL;
- }
+ LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL;
+ return fallback;
}
-
- return std::string(result_cstr);
}
@@ -156,18 +153,18 @@ void LLDir_Linux::initAppDirs(const std::string &app_name,
if (!app_read_only_data_dir.empty())
{
mAppRODataDir = app_read_only_data_dir;
- mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+ mSkinBaseDir = add(mAppRODataDir, "skins");
}
mAppName = app_name;
std::string upper_app_name(app_name);
LLStringUtil::toUpper(upper_app_name);
- char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */
+ auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR"));
if (app_home_env)
{
// user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
- mOSUserAppDir = app_home_env;
+ mOSUserAppDir = *app_home_env;
}
else
{
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index fc27e11e35..0b1fc3b6a5 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -187,9 +187,9 @@ void LLDir_Mac::initAppDirs(const std::string &app_name,
if (!app_read_only_data_dir.empty())
{
mAppRODataDir = app_read_only_data_dir;
- mSkinBaseDir = mAppRODataDir + mDirDelimiter + "skins";
+ mSkinBaseDir = add(mAppRODataDir, "skins");
}
- mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "../Resources", "ca-bundle.crt");
+ mCAFile = add(mAppRODataDir, "ca-bundle.crt");
}
// Used by LGG's selection beams
diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp
index d3536a12ee..f18560ff20 100644
--- a/indra/llvfs/lldir_solaris.cpp
+++ b/indra/llvfs/lldir_solaris.cpp
@@ -29,6 +29,7 @@
#include "lldir_solaris.h"
#include "llerror.h"
#include "llrand.h"
+#include "llstring.h"
#include
#include
#include
@@ -41,30 +42,28 @@
static std::string getCurrentUserHome(char* fallback)
{
+ // fwiw this exactly duplicates getCurrentUserHome() in lldir_linux.cpp...
+ // we should either derive both from LLDir_Posix or just axe Solaris.
const uid_t uid = getuid();
struct passwd *pw;
- char *result_cstr = fallback;
-
+
pw = getpwuid(uid);
if ((pw != NULL) && (pw->pw_dir != NULL))
{
- result_cstr = (char*) pw->pw_dir;
+ return pw->pw_dir;
+ }
+
+ LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
+ auto home_env = LLStringUtil::getoptenv("HOME");
+ if (home_env)
+ {
+ return *home_env;
}
else
{
- LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
- const char *const home_env = getenv("HOME"); /* Flawfinder: ignore */
- if (home_env)
- {
- result_cstr = (char*) home_env;
- }
- else
- {
- LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL;
- }
+ LL_WARNS() << "Couldn't detect home directory! Falling back to " << fallback << LL_ENDL;
+ return fallback;
}
-
- return std::string(result_cstr);
}
@@ -135,27 +134,15 @@ LLDir_Solaris::LLDir_Solaris()
//NOTE: Why force people to cd into the package directory?
// Look for SECONDLIFE env variable and use it, if set.
- char *dcf = getenv("SECONDLIFE");
- if(dcf != NULL){
- (void)strcpy(path, dcf);
- (void)strcat(path, "/bin"); //NOTE: make sure we point at the bin
- mExecutableDir = strdup(path);
+ auto SECONDLIFE(LLDirUtil::getoptenv("SECONDLIFE"));
+ if(SECONDLIFE){
+ mExecutableDir = add(*SECONDLIFE, "bin"); //NOTE: make sure we point at the bin
}else{
- // plunk a null at last '/' to get exec dir
- char *s = execpath + strlen(execpath) -1;
- while(*s != '/' && s != execpath){
- --s;
- }
-
- if(s != execpath){
- *s = (char)NULL;
-
- mExecutableDir = strdup(execpath);
- LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL;
- }
+ mExecutableDir = getDirName(execpath);
+ LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL;
}
-
- mLLPluginDir = mExecutableDir + mDirDelimiter + "llplugin";
+
+ mLLPluginDir = add(mExecutableDir, "llplugin");
// *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
mTempDir = "/tmp";
@@ -175,17 +162,18 @@ void LLDir_Solaris::initAppDirs(const std::string &app_name,
if (!app_read_only_data_dir.empty())
{
mAppRODataDir = app_read_only_data_dir;
+ mSkinBaseDir = add(mAppRODataDir, "skins");
}
mAppName = app_name;
std::string upper_app_name(app_name);
LLStringUtil::toUpper(upper_app_name);
- char* app_home_env = getenv((upper_app_name + "_USER_DIR").c_str()); /* Flawfinder: ignore */
+ auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR"));
if (app_home_env)
{
// user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
- mOSUserAppDir = app_home_env;
+ mOSUserAppDir = *app_home_env;
}
else
{
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 2c2f14e6b1..699b6f5f83 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -30,14 +30,10 @@
#include "lldir_win32.h"
#include "llerror.h"
-#include "llrand.h" // for gLindenLabRandomNumber
+#include "llstring.h"
+#include "stringize.h"
+#include "llfile.h"
#include
-// Remove VMP
-#include
-#include
-#include
-#include // CoTaskMemFree()
-// Remove VMP
#include
#include
@@ -49,55 +45,87 @@
#define PACKVERSION(major,minor) MAKELONG(minor,major)
DWORD GetDllVersion(LPCTSTR lpszDllName);
-// Remove VMP
-namespace {
+namespace
+{ // anonymous
+ enum class prst { INIT, OPEN, SKIP } state = prst::INIT;
+ // This is called so early that we can't count on static objects being
+ // properly constructed yet, so declare a pointer instead of an instance.
+ std::ofstream* prelogf = nullptr;
-std::string getKnownFolderPath(const std::string& desc, REFKNOWNFOLDERID folderid)
-{
- // https://msdn.microsoft.com/en-us/library/windows/desktop/bb762188(v=vs.85).aspx
- PWSTR wstrptr = 0;
- HRESULT result = SHGetKnownFolderPath(
- folderid,
- KF_FLAG_DEFAULT, // no flags
- NULL, // current user, no impersonation
- &wstrptr);
- if (result == S_OK)
+ void prelog(const std::string& message)
{
- std::string utf8 = utf16str_to_utf8str(llutf16string(wstrptr));
- // have to free the returned pointer after copying its data
- CoTaskMemFree(wstrptr);
- return utf8;
+ boost::optional prelog_name;
+
+ switch (state)
+ {
+ case prst::INIT:
+ // assume we failed, until we succeed
+ state = prst::SKIP;
+
+ prelog_name = LLStringUtil::getoptenv("PRELOG");
+ if (! prelog_name)
+ // no PRELOG variable set, carry on
+ return;
+ prelogf = new llofstream(*prelog_name, std::ios_base::app);
+ if (! (prelogf && prelogf->is_open()))
+ // can't complain to anybody; how?
+ return;
+ // got the log file open, cool!
+ state = prst::OPEN;
+ (*prelogf) << "========================================================================"
+ << std::endl;
+ // fall through, don't break
+
+ case prst::OPEN:
+ (*prelogf) << message << std::endl;
+ break;
+
+ case prst::SKIP:
+ // either PRELOG isn't set, or we failed to open that pathname
+ break;
+ }
}
-
- // gack, no logging yet!
- // at least say something to a developer trying to debug this...
- static std::map codes
- {
- { E_FAIL, "E_FAIL; known folder does not have a path?" },
- { E_INVALIDARG, "E_INVALIDARG; not present on system?" }
- };
- auto found = codes.find(result);
- const char* text = (found == codes.end())? "unknown" : found->second;
- std::cout << "*** SHGetKnownFolderPath(" << desc << ") failed with "
- << result << " (" << text << ")\n";
- return {};
-}
-
} // anonymous namespace
-// Remove VMP
+
+#define PRELOG(expression) prelog(STRINGIZE(expression))
LLDir_Win32::LLDir_Win32()
{
// set this first: used by append() and add() methods
mDirDelimiter = "\\";
+ WCHAR w_str[MAX_PATH];
// Application Data is where user settings go. We rely on $APPDATA being
- // correct; in fact the VMP makes a point of setting it properly, since
- // Windows itself botches the job for non-ASCII usernames (MAINT-8087).
- // Remove VMP
- //mOSUserDir = ll_safe_string(getenv("APPDATA"));
- mOSUserDir = getKnownFolderPath("RoamingAppData", FOLDERID_RoamingAppData);
- // Remove VMP
+ // correct.
+ auto APPDATA = LLStringUtil::getoptenv("APPDATA");
+ if (APPDATA)
+ {
+ mOSUserDir = *APPDATA;
+ }
+ PRELOG("APPDATA='" << mOSUserDir << "'");
+ // On Windows, we could have received a plain-ASCII pathname in which
+ // non-ASCII characters have been munged to '?', or the pathname could
+ // have been badly encoded and decoded such that we now have garbage
+ // instead of a valid path. Check that mOSUserDir actually exists.
+ if (mOSUserDir.empty() || ! fileExists(mOSUserDir))
+ {
+ PRELOG("APPDATA does not exist");
+ //HRESULT okay = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, w_str);
+ wchar_t *pwstr = NULL;
+ HRESULT okay = SHGetKnownFolderPath(FOLDERID_RoamingAppData, 0, NULL, &pwstr);
+ PRELOG("SHGetKnownFolderPath(FOLDERID_RoamingAppData) returned " << okay);
+ if (SUCCEEDED(okay) && pwstr)
+ {
+ // But of course, only update mOSUserDir if SHGetKnownFolderPath() works.
+ mOSUserDir = ll_convert_wide_to_string(pwstr);
+ // Not only that: update our environment so that child processes
+ // will see a reasonable value as well.
+ _wputenv_s(L"APPDATA", pwstr);
+ // SHGetKnownFolderPath() contract requires us to free pwstr
+ CoTaskMemFree(pwstr);
+ PRELOG("mOSUserDir='" << mOSUserDir << "'");
+ }
+ }
// We want cache files to go on the local disk, even if the
// user is on a network with a "roaming profile".
@@ -107,12 +135,34 @@ LLDir_Win32::LLDir_Win32()
//
// We used to store the cache in AppData\Roaming, and the installer
// cleans up that version on upgrade. JC
- // Remove VMP
- //mOSCacheDir = ll_safe_string(getenv("LOCALAPPDATA"));
- mOSCacheDir = getKnownFolderPath("LocalAppData", FOLDERID_LocalAppData);
- // Remove VMP
+ auto LOCALAPPDATA = LLStringUtil::getoptenv("LOCALAPPDATA");
+ if (LOCALAPPDATA)
+ {
+ mOSCacheDir = *LOCALAPPDATA;
+ }
+ PRELOG("LOCALAPPDATA='" << mOSCacheDir << "'");
+ // Windows really does not deal well with pathnames containing non-ASCII
+ // characters. See above remarks about APPDATA.
+ if (mOSCacheDir.empty() || ! fileExists(mOSCacheDir))
+ {
+ PRELOG("LOCALAPPDATA does not exist");
+ //HRESULT okay = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, w_str);
+ wchar_t *pwstr = NULL;
+ HRESULT okay = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, NULL, &pwstr);
+ PRELOG("SHGetKnownFolderPath(FOLDERID_LocalAppData) returned " << okay);
+ if (SUCCEEDED(okay) && pwstr)
+ {
+ // But of course, only update mOSCacheDir if SHGetKnownFolderPath() works.
+ mOSCacheDir = ll_convert_wide_to_string(pwstr);
+ // Update our environment so that child processes will see a
+ // reasonable value as well.
+ _wputenv_s(L"LOCALAPPDATA", pwstr);
+ // SHGetKnownFolderPath() contract requires us to free pwstr
+ CoTaskMemFree(pwstr);
+ PRELOG("mOSCacheDir='" << mOSCacheDir << "'");
+ }
+ }
- WCHAR w_str[MAX_PATH];
if (GetTempPath(MAX_PATH, w_str))
{
if (wcslen(w_str)) /* Flawfinder: ignore */
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index c9f040f2e4..b8556fd749 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1459,12 +1459,10 @@ static CursorRef gCursors[UI_CURSOR_COUNT];
static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY)
{
// cursors are in /Contents/Resources/cursors_mac/UI_CURSOR_FOO.tif
- std::string fullpath = gDirUtilp->getAppRODataDir();
- fullpath += gDirUtilp->getDirDelimiter();
- fullpath += "cursors_mac";
- fullpath += gDirUtilp->getDirDelimiter();
- fullpath += cursorIDToName(cursorid);
- fullpath += ".tif";
+ std::string fullpath = gDirUtilp->add(
+ gDirUtilp->getAppRODataDir(),
+ "cursors_mac",
+ cursorIDToName(cursorid) + std::string(".tif"));
gCursors[cursorid] = createImageCursor(fullpath.c_str(), hotspotX, hotspotY);
}
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index f79e95b159..8410c2f2a5 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -3349,17 +3349,10 @@ S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 t
break;
}
- // HACK! Doesn't properly handle wide strings!
-
- // Convert to wchar_t, then use MessageBoxW
-
- // int retval_win = MessageBoxA(NULL, text.c_str(), caption.c_str(), uType);
- llutf16string textW = utf8str_to_utf16str( text );
- llutf16string captionW = utf8str_to_utf16str( caption );
- int retval_win = MessageBoxW(NULL, textW.c_str(), captionW.c_str(), uType);
-
- //
-
+ int retval_win = MessageBoxW(NULL, // HWND
+ ll_convert_string_to_wide(text).c_str(),
+ ll_convert_string_to_wide(caption).c_str(),
+ uType);
S32 retval;
switch(retval_win)
diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp
index 2b691ffbb1..f7e43d6def 100644
--- a/indra/llxml/tests/llcontrol_test.cpp
+++ b/indra/llxml/tests/llcontrol_test.cpp
@@ -27,43 +27,31 @@
#include "linden_common.h"
#include "llsdserialize.h"
+#include "llfile.h"
+#include "stringize.h"
#include "../llcontrol.h"
#include "../test/lltut.h"
+#include
+#include
namespace tut
{
-
struct control_group
{
- LLControlGroup* mCG;
+ std::unique_ptr mCG;
std::string mTestConfigDir;
std::string mTestConfigFile;
+ std::vector mCleanups;
static bool mListenerFired;
control_group()
{
- mCG = new LLControlGroup("foo");
+ mCG.reset(new LLControlGroup("foo"));
LLUUID random;
random.generate();
// generate temp dir
- std::ostringstream oStr;
-
-#ifdef LL_WINDOWS
- char* tmp_dir = getenv("TMP");
- if(tmp_dir)
- {
- oStr << tmp_dir << "/llcontrol-test-" << random << "/";
- }
- else
- {
- oStr << "c:/tmp/llcontrol-test-" << random << "/";
- }
-#else
- oStr << "/tmp/llcontrol-test-" << random << "/";
-#endif
-
- mTestConfigDir = oStr.str();
+ mTestConfigDir = STRINGIZE(LLFile::tmpdir() << "llcontrol-test-" << random << "/");
mTestConfigFile = mTestConfigDir + "settings.xml";
LLFile::mkdir(mTestConfigDir);
LLSD config;
@@ -76,7 +64,12 @@ namespace tut
~control_group()
{
//Remove test files
- delete mCG;
+ for (auto filename : mCleanups)
+ {
+ LLFile::remove(filename);
+ }
+ LLFile::remove(mTestConfigFile);
+ LLFile::rmdir(mTestConfigDir);
}
void writeSettingsFile(const LLSD& config)
{
@@ -118,6 +111,7 @@ namespace tut
ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13);
LLControlGroup test_cg("foo2");
std::string temp_test_file = (mTestConfigDir + "setting_llsd_temp.xml");
+ mCleanups.push_back(temp_test_file);
mCG->saveToFile(temp_test_file.c_str(), TRUE);
results = test_cg.loadFromFile(temp_test_file.c_str());
ensure("number of changed settings loaded", (results == 1));
@@ -139,6 +133,7 @@ namespace tut
ensure_equals("value of changed setting", mCG->getU32("TestSetting"), 13);
LLControlGroup test_cg("foo3");
std::string temp_test_file = (mTestConfigDir + "setting_llsd_persist_temp.xml");
+ mCleanups.push_back(temp_test_file);
mCG->saveToFile(temp_test_file.c_str(), TRUE);
results = test_cg.loadFromFile(temp_test_file.c_str());
//If we haven't changed any settings, then we shouldn't have any settings to load
@@ -153,7 +148,7 @@ namespace tut
ensure("number of settings", (results == 1));
mCG->getControl("TestSetting")->getSignal()->connect(boost::bind(&this->handleListenerTest));
mCG->setU32("TestSetting", 13);
- ensure("listener fired on changed setting", mListenerFired);
+ ensure("listener fired on changed setting", mListenerFired);
}
}
diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt
index 70c81d4023..7f2b82ffdd 100644
--- a/indra/media_plugins/base/CMakeLists.txt
+++ b/indra/media_plugins/base/CMakeLists.txt
@@ -48,5 +48,5 @@ set(media_plugin_base_HEADER_FILES
add_library(media_plugin_base
${media_plugin_base_SOURCE_FILES}
-)
+ )
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index e0acc941dc..d53252f198 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -83,7 +83,7 @@ list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES})
add_library(media_plugin_cef
SHARED
${media_plugin_cef_SOURCE_FILES}
-)
+ )
#add_dependencies(media_plugin_cef
# ${MEDIA_PLUGIN_BASE_LIBRARIES}
diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt
index 5366de68e7..081302c3ed 100644
--- a/indra/media_plugins/example/CMakeLists.txt
+++ b/indra/media_plugins/example/CMakeLists.txt
@@ -47,7 +47,7 @@ set(media_plugin_example_SOURCE_FILES
add_library(media_plugin_example
SHARED
${media_plugin_example_SOURCE_FILES}
-)
+ )
target_link_libraries(media_plugin_example
${LLPLUGIN_LIBRARIES}
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
index 6d18814b1e..571eb57b24 100644
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -56,7 +56,7 @@ set(media_plugin_gstreamer010_HEADER_FILES
add_library(media_plugin_gstreamer010
SHARED
${media_plugin_gstreamer010_SOURCE_FILES}
-)
+ )
target_link_libraries(media_plugin_gstreamer010
${LLPLUGIN_LIBRARIES}
diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt
index 3090e6d468..723ffe57af 100644
--- a/indra/media_plugins/libvlc/CMakeLists.txt
+++ b/indra/media_plugins/libvlc/CMakeLists.txt
@@ -48,7 +48,7 @@ set(media_plugin_libvlc_SOURCE_FILES
add_library(media_plugin_libvlc
SHARED
${media_plugin_libvlc_SOURCE_FILES}
-)
+ )
target_link_libraries(media_plugin_libvlc
${LLPLUGIN_LIBRARIES}
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3ac42a839e..3545ef620b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -3,7 +3,14 @@
project(viewer)
include(00-Common)
+# DON'T move Linking.cmake to its place in the alphabetized list below: it
+# sets variables on which the 3p .cmake files depend.
+include(Linking)
+
include(Boost)
+if (BUGSPLAT_DB)
+ include(bugsplat)
+endif (BUGSPLAT_DB)
include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
@@ -17,7 +24,6 @@ include(GLOD)
include(Hunspell)
include(JsonCpp)
include(LLAppearance)
-include(LLBase)
include(LLAudio)
include(LLCA)
include(LLCharacter)
@@ -38,14 +44,12 @@ include(LLUI)
include(LLVFS)
include(LLWindow)
include(LLXML)
-include(Linking)
include(NDOF)
include(NVAPI)
include(OPENAL)
include(OpenGL)
include(OpenSSL)
include(PNG)
-include(Requests)
include(TemplateCheck)
include(UI)
include(UnixInstall)
@@ -55,6 +59,7 @@ include(VisualLeakDetector)
include(URIPARSER)
include(Growl)
include(ColladaDom)
+include(jemalloc)
# if using ndPhysicsstub this variable will be unset, we don't need to build any stub code viewer side in that case
if( LLPHYSICSEXTENSIONS_SRC_DIR )
@@ -110,6 +115,12 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}
)
+if (BUGSPLAT_DB)
+ include_directories(
+ ${BUGSPLAT_INCLUDE_DIR}
+ )
+endif (BUGSPLAT_DB)
+
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLXML_SYSTEM_INCLUDE_DIRS}
@@ -1656,6 +1667,14 @@ if (DARWIN)
# This should be compiled with the viewer.
LIST(APPEND viewer_SOURCE_FILES llappdelegate-objc.mm)
+ set_source_files_properties(
+ llappdelegate-objc.mm
+ PROPERTIES
+ COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+ # BugsplatMac is a module, imported with @import. That language feature
+ # demands these switches.
+ COMPILE_FLAGS "-fmodules -fcxx-modules"
+ )
# [FS] Growl libs
LIST(APPEND viewer_SOURCE_FILES
@@ -1682,6 +1701,12 @@ if (DARWIN)
${COREAUDIO_LIBRARY}
)
+ if (BUGSPLAT_DB)
+ list(APPEND viewer_LIBRARIES
+ ${BUGSPLAT_LIBRARIES}
+ )
+ endif (BUGSPLAT_DB)
+
# Add resource files to the project.
set(viewer_RESOURCE_FILES
firestorm_icon.icns
@@ -1707,6 +1732,11 @@ endif (DARWIN)
if (LINUX)
LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
+ set_source_files_properties(
+ llappviewerlinux.cpp
+ PROPERTIES
+ COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+ )
LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
# [FS] Growl support
LIST(APPEND viewer_HEADER_FILES desktopnotifierlinux.h growlmanager.h)
@@ -1741,6 +1771,11 @@ if (WINDOWS)
llappviewerwin32.cpp
llwindebug.cpp
)
+ set_source_files_properties(
+ llappviewerwin32.cpp
+ PROPERTIES
+ COMPILE_DEFINITIONS "${VIEWER_CHANNEL_VERSION_DEFINES}"
+ )
list(APPEND viewer_HEADER_FILES
llappviewerwin32.h
@@ -1884,7 +1919,6 @@ if (WINDOWS)
kernel32
odbc32
odbccp32
- ole32
oleaut32
shell32
Vfw32
@@ -2079,6 +2113,11 @@ if (SDL_FOUND)
)
endif (SDL_FOUND)
+if (BUGSPLAT_DB)
+ set_property(TARGET ${VIEWER_BINARY_NAME}
+ PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
+endif (BUGSPLAT_DB)
+
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -2207,15 +2246,16 @@ if (WINDOWS)
--actions=copy
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
+ "--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
+ "--channel=${VIEWER_CHANNEL}"
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
--grid=${GRID}
- "--channel=${VIEWER_CHANNEL}"
- --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
stage_third_party_libs
@@ -2236,6 +2276,7 @@ if (WINDOWS)
windows-crash-logger
)
+ # No Teamcity -> allow unattended
# sets the 'working directory' for debugging from visual studio.
if (NOT UNATTENDED)
add_custom_command(
@@ -2250,6 +2291,7 @@ if (WINDOWS)
COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
)
endif (NOT UNATTENDED)
+ #
if (PACKAGE)
add_custom_command(
@@ -2273,15 +2315,16 @@ if (WINDOWS)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
+ "--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
- --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
--grid=${GRID}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--viewer_flavor=${ND_VIEWER_FLAVOR}
DEPENDS
${VIEWER_BINARY_NAME}
@@ -2313,8 +2356,8 @@ else (WINDOWS)
endif (WINDOWS)
# *NOTE: - this list is very sensitive to ordering, test carefully on all
-# platforms if you change the releative order of the entries here.
-# In particular, cmake 2.6.4 (when buidling with linux/makefile generators)
+# platforms if you change the relative order of the entries here.
+# In particular, cmake 2.6.4 (when building with linux/makefile generators)
# appears to sometimes de-duplicate redundantly listed dependencies improperly.
# To work around this, higher level modules should be listed before the modules
# that they depend upon. -brad
@@ -2388,6 +2431,12 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLAPPEARANCE_LIBRARIES}
${GROWL_LIBRARY}
)
+
+if (BUGSPLAT_DB)
+ target_link_libraries(${VIEWER_BINARY_NAME}
+ ${BUGSPLAT_LIBRARIES}
+ )
+endif (BUGSPLAT_DB)
if (WINDOWS)
target_link_libraries(${VIEWER_BINARY_NAME}
@@ -2434,15 +2483,16 @@ endif (NOT ENABLE_MEDIA_PLUGINS)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
+ "--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
"--channel=${VIEWER_CHANNEL}"
- --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
--grid=${GRID}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--viewer_flavor=${ND_VIEWER_FLAVOR}
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -2455,17 +2505,18 @@ endif (NOT ENABLE_MEDIA_PLUGINS)
COMMAND ${PYTHON_EXECUTABLE}
ARGS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
- --arch=${ARCH}
--actions=copy
+ --arch=${ARCH}
--artwork=${ARTWORK_DIR}
+ "--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
+ "--channel=${VIEWER_CHANNEL}"
--configuration=${CMAKE_CFG_INTDIR}
--dest=${CMAKE_CURRENT_BINARY_DIR}/packaged
--grid=${GRID}
- "--channel=${VIEWER_CHANNEL}"
- --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--source=${CMAKE_CURRENT_SOURCE_DIR}
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
DEPENDS
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
${COPY_INPUT_DEPENDENCIES}
@@ -2483,36 +2534,50 @@ endif (NOT ENABLE_MEDIA_PLUGINS)
endif (LINUX)
if (DARWIN)
- # These all get set with PROPERTIES
- set(product "Firestorm")
- # this is the setting for the Python wrapper, see SL-322 and WRAPPER line in Info-SecondLife.plist
- set(MACOSX_WRAPPER_EXECUTABLE_NAME "SL_Launcher")
- set(MACOSX_BUNDLE_INFO_STRING "Firestorm Viewer")
+ # These all get set with PROPERTIES. It's not that the property names are
+ # magically known to CMake -- it's that these names are referenced in the
+ # Info-SecondLife.plist file in the configure_file() directive below.
+ set(product "${VIEWER_CHANNEL}")
+ set(MACOSX_EXECUTABLE_NAME "${VIEWER_CHANNEL}")
+ set(MACOSX_BUNDLE_INFO_STRING "${VIEWER_CHANNEL}")
set(MACOSX_BUNDLE_ICON_FILE "firestorm_icon.icns")
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.phoenixviewer.firestorm.viewer-${ND_VIEWER_FLAVOR}")
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${VIEWER_CHANNEL} ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
set(MACOSX_BUNDLE_BUNDLE_NAME "Firestorm")
- set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}")
+ set(MACOSX_BUNDLE_SHORT_VERSION_STRING "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
set(MACOSX_BUNDLE_BUNDLE_VERSION "${VIEWER_SHORT_VERSION}${VIEWER_MACOSX_PHASE}${VIEWER_REVISION}")
set(MACOSX_BUNDLE_COPYRIGHT "Copyright 2010-2019 The Phoenix Firestorm Project, Inc.")
set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "Firestorm.nib")
set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "LLNSApplication")
+ # https://blog.kitware.com/upcoming-in-cmake-2-8-12-osx-rpath-support/
+ set(CMAKE_MACOSX_RPATH 1)
+
set_target_properties(
${VIEWER_BINARY_NAME}
PROPERTIES
OUTPUT_NAME "${product}"
+ # From Contents/MacOS/SecondLife, look in Contents/Frameworks
+ INSTALL_RPATH "@loader_path/../Frameworks"
+ # SIGH, as of 2018-05-24 (cmake 3.11.1) the INSTALL_RPATH property simply
+ # does not work. Try this:
+ LINK_FLAGS "-rpath @loader_path/../Frameworks"
MACOSX_BUNDLE_INFO_PLIST
# Use Firestorm plist
#"${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
"${CMAKE_CURRENT_SOURCE_DIR}/Info-Firestorm.plist"
)
+ set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
+ set(VIEWER_APP_EXE "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}")
+ set(VIEWER_APP_DSYM "${VIEWER_APP_EXE}.dSYM")
+ set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
+
configure_file(
# Use Firestorm plist
#"${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"
"${CMAKE_CURRENT_SOURCE_DIR}/Info-Firestorm.plist"
- "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app/Contents/Info.plist"
+ "${VIEWER_APP_BUNDLE}/Contents/Info.plist"
)
add_custom_command(
@@ -2523,15 +2588,16 @@ if (DARWIN)
--actions=copy
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
+ "--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
- --configuration=${CMAKE_CFG_INTDIR}
- --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
- --grid=${GRID}
- "--channel=${VIEWER_CHANNEL}"
- --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
+ "--channel=${VIEWER_CHANNEL}"
+ --configuration=${CMAKE_CFG_INTDIR}
+ --dest=${VIEWER_APP_BUNDLE}
+ --grid=${GRID}
--source=${CMAKE_CURRENT_SOURCE_DIR}
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
DEPENDS
${VIEWER_BINARY_NAME}
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -2556,15 +2622,16 @@ if (DARWIN)
${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
--arch=${ARCH}
--artwork=${ARTWORK_DIR}
+ "--bugsplat=${BUGSPLAT_DB}"
--build=${CMAKE_CURRENT_BINARY_DIR}
--buildtype=${CMAKE_BUILD_TYPE}
- --configuration=${CMAKE_CFG_INTDIR}
- --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
- --grid=${GRID}
"--channel=${VIEWER_CHANNEL}"
- --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
+ --configuration=${CMAKE_CFG_INTDIR}
+ --dest=${VIEWER_APP_BUNDLE}
+ --grid=${GRID}
--source=${CMAKE_CURRENT_SOURCE_DIR}
--touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
+ --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
--viewer_flavor=${ND_VIEWER_FLAVOR}
${SIGNING_SETTING}
DEPENDS
@@ -2577,67 +2644,153 @@ if (INSTALL)
include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
endif (INSTALL)
-if (PACKAGE)
- set(SYMBOL_SEARCH_DIRS "")
- # Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
- if (WINDOWS)
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
- set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/firestorm-symbols-windows-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
- # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
- # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
- set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
- set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}")
- set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
- endif (WINDOWS)
- if (DARWIN)
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
- # *TODO: Generate these search dirs in the cmake files related to each binary.
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
- set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/firestorm-symbols-darwin-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
-## set(VIEWER_EXE_GLOBS "'Second Life' SLPlugin mac-crash-logger")
- set(VIEWER_EXE_GLOBS "'Firestorm' mac-crash-logger")
- set(VIEWER_LIB_GLOB "*.dylib")
- endif (DARWIN)
- if (LINUX)
- list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
- set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/firestorm-symbols-linux-$ENV{AUTOBUILD_ADDRSIZE}.tar.bz2")
-## set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
- set(VIEWER_EXE_GLOBS "do-not-directly-run-firestorm-bin SLPlugin")
- set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
- set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
- endif (LINUX)
+# Note that the conventional VIEWER_SYMBOL_FILE is set by ../../build.sh
+if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND VIEWER_SYMBOL_FILE)
+ if (NOT BUGSPLAT_DB)
+ # Breakpad symbol-file generation
+ set(SYMBOL_SEARCH_DIRS "")
+ if (WINDOWS)
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
+ # slplugin.exe failing symbols dump - need to debug, might have to do with updated version of google breakpad
+ # set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX} slplugin.exe")
+ set(VIEWER_EXE_GLOBS "${VIEWER_BINARY_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
+ set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}")
+ set(VIEWER_COPY_MANIFEST copy_w_viewer_manifest)
+ endif (WINDOWS)
+ if (DARWIN)
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
+ # *TODO: Generate these search dirs in the cmake files related to each binary.
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/mac_crash_logger/${CMAKE_CFG_INTDIR}")
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
+## set(VIEWER_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
+ set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
+ set(VIEWER_LIB_GLOB "*.dylib")
+ endif (DARWIN)
+ if (LINUX)
+ list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/packaged")
+## set(VIEWER_EXE_GLOBS "do-not-directly-run-secondlife-bin SLPlugin")
+ set(VIEWER_EXE_GLOBS "do-not-directly-run-firestorm-bin")
+ set(VIEWER_LIB_GLOB "*${CMAKE_SHARED_MODULE_SUFFIX}*")
+ set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
+ endif (LINUX)
- if( RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING )
- if(CMAKE_CFG_INTDIR STREQUAL ".")
- set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
- else(CMAKE_CFG_INTDIR STREQUAL ".")
- # set LLBUILD_CONFIG to be a shell variable evaluated at build time
- # reflecting the configuration we are currently building.
- set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
- endif(CMAKE_CFG_INTDIR STREQUAL ".")
- add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
- COMMAND "${PYTHON_EXECUTABLE}"
- ARGS
- "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
- "${LLBUILD_CONFIG}"
- "${SYMBOL_SEARCH_DIRS}"
- "${VIEWER_EXE_GLOBS}"
- "${VIEWER_LIB_GLOB}"
- "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
- "${VIEWER_SYMBOL_FILE}"
- DEPENDS generate_breakpad_symbols.py
- VERBATIM)
+ if(CMAKE_CFG_INTDIR STREQUAL ".")
+ set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
+ else(CMAKE_CFG_INTDIR STREQUAL ".")
+ # set LLBUILD_CONFIG to be a shell variable evaluated at build time
+ # reflecting the configuration we are currently building.
+ set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
+ endif(CMAKE_CFG_INTDIR STREQUAL ".")
+ add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+ COMMAND "${PYTHON_EXECUTABLE}"
+ ARGS
+ "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
+ "${LLBUILD_CONFIG}"
+ "${SYMBOL_SEARCH_DIRS}"
+ "${VIEWER_EXE_GLOBS}"
+ "${VIEWER_LIB_GLOB}"
+ "${AUTOBUILD_INSTALL_DIR}/bin/dump_syms"
+ "${VIEWER_SYMBOL_FILE}"
+ DEPENDS generate_breakpad_symbols.py
+ VERBATIM)
- add_custom_target(generate_breakpad_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
- add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}")
- if (WINDOWS OR LINUX)
- add_dependencies(generate_breakpad_symbols "${VIEWER_COPY_MANIFEST}")
- endif (WINDOWS OR LINUX)
- add_dependencies(llpackage generate_breakpad_symbols)
- endif(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
-endif (PACKAGE)
+## add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME} "${VIEWER_COPY_MANIFEST}")
+ add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
+ add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
+ if (WINDOWS OR LINUX)
+ add_dependencies(generate_symbols "${VIEWER_COPY_MANIFEST}")
+ endif (WINDOWS OR LINUX)
+
+ else (NOT BUGSPLAT_DB)
+ # BugSplat symbol-file generation
+ if (WINDOWS)
+ # Just pack up a tarball containing only the .pdb file for the
+ # executable. Because we intend to use cygwin tar, we must render
+ # VIEWER_SYMBOL_FILE in cygwin path syntax.
+ execute_process(COMMAND "cygpath" "-u" "${VIEWER_SYMBOL_FILE}"
+ OUTPUT_VARIABLE VIEWER_SYMBOL_FILE_CYGWIN
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(COMMAND "cygpath" "-u" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+ OUTPUT_VARIABLE PARENT_DIRECTORY_CYGWIN
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+ # Use of 'tar ...j' here assumes VIEWER_SYMBOL_FILE endswith .tar.bz2;
+ # testing a string suffix is painful enough in CMake language that
+ # we'll continue assuming it until forced to generalize.
+ COMMAND "tar"
+ ARGS
+ "cjf"
+ "${VIEWER_SYMBOL_FILE_CYGWIN}"
+ "-C"
+ "${PARENT_DIRECTORY_CYGWIN}"
+ "secondlife-bin.pdb"
+ DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-bin.pdb"
+ COMMENT "Packing viewer PDB into ${VIEWER_SYMBOL_FILE_CYGWIN}"
+ )
+ add_custom_target(generate_symbols DEPENDS "${VIEWER_SYMBOL_FILE}" ${VIEWER_BINARY_NAME})
+ add_dependencies(generate_symbols ${VIEWER_BINARY_NAME})
+ endif (WINDOWS)
+ if (DARWIN)
+ # Have to run dsymutil first, then pack up the resulting .dSYM directory
+ add_custom_command(OUTPUT "${VIEWER_APP_DSYM}"
+ COMMAND "dsymutil"
+ ARGS
+ ${VIEWER_APP_EXE}
+ COMMENT "Generating ${VIEWER_APP_DSYM}"
+ )
+ add_custom_target(dsym_generate DEPENDS "${VIEWER_APP_DSYM}")
+ add_dependencies(dsym_generate ${VIEWER_BINARY_NAME})
+ add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+ # See above comments about "tar ...j"
+ COMMAND "tar"
+ ARGS
+ "cjf"
+ "${VIEWER_SYMBOL_FILE}"
+ "-C"
+ "${VIEWER_APP_DSYM}/.."
+ "${product}.dSYM"
+ DEPENDS "${VIEWER_APP_DSYM}"
+ COMMENT "Packing dSYM into ${VIEWER_SYMBOL_FILE}"
+ )
+ add_custom_target(dsym_tarball DEPENDS "${VIEWER_SYMBOL_FILE}")
+ add_dependencies(dsym_tarball dsym_generate)
+ add_custom_command(OUTPUT "${VIEWER_APP_XCARCHIVE}"
+ COMMAND "zip"
+ ARGS
+ "-r"
+ "${VIEWER_APP_XCARCHIVE}"
+ "."
+ WORKING_DIRECTORY "${VIEWER_APP_DSYM}/.."
+ DEPENDS "${VIEWER_APP_DSYM}"
+ COMMENT "Generating xcarchive.zip for upload to BugSplat"
+ )
+ add_custom_target(dsym_xcarchive DEPENDS "${VIEWER_APP_XCARCHIVE}")
+ add_dependencies(dsym_xcarchive dsym_generate)
+ # Have to create a stamp file, and depend on it, to force CMake to run
+ # the cleanup step.
+ add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+ COMMAND rm -rf "${VIEWER_APP_DSYM}"
+ COMMAND touch "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+ DEPENDS "${VIEWER_SYMBOL_FILE}" "${VIEWER_APP_XCARCHIVE}"
+ COMMENT "Cleaning up dSYM"
+ )
+ add_custom_target(generate_symbols DEPENDS
+ "${VIEWER_APP_DSYM}"
+ "${VIEWER_SYMBOL_FILE}"
+ "${VIEWER_APP_XCARCHIVE}"
+ "${CMAKE_CURRENT_BINARY_DIR}/dsym.stamp"
+ )
+ add_dependencies(generate_symbols dsym_tarball dsym_xcarchive)
+ endif (DARWIN)
+ if (LINUX)
+ # TBD
+ endif (LINUX)
+ endif (NOT BUGSPLAT_DB)
+
+ # for both BUGSPLAT_DB and Breakpad
+ add_dependencies(llpackage generate_symbols)
+endif ()
if (LL_TESTS)
# To add a viewer unit test, just add the test .cpp file below
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index af4cf26ac6..cfe9d991c5 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -5,7 +5,7 @@
CFBundleDevelopmentRegion
English
CFBundleExecutable
- ${MACOSX_WRAPPER_EXECUTABLE_NAME}
+ ${MACOSX_EXECUTABLE_NAME}
CFBundleGetInfoString
${MACOSX_BUNDLE_INFO_STRING}
CFBundleIconFile
@@ -21,7 +21,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- ${MACOSX_BUNDLE_LONG_VERSION_STRING}
+ ${MACOSX_BUNDLE_SHORT_VERSION_STRING}
CFBundleSignature
????
CFBundleVersion
@@ -32,6 +32,8 @@
NSHumanReadableCopyright
${MACOSX_BUNDLE_COPYRIGHT}
+ NSMicrophoneUsageDescription
+ For voice chat, you must grant permission for Second Life to use the microphone.
CFBundleDocumentTypes
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 090ea9dad1..f3b5af39e4 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.0.3
+6.1.1
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
index 99276119ca..3f63cf24f8 100644
--- a/indra/newview/app_settings/logcontrol.xml
+++ b/indra/newview/app_settings/logcontrol.xml
@@ -65,6 +65,7 @@
tags
+
-
-
-
+
diff --git a/indra/newview/skins/default/xui/pl/floater_world_map.xml b/indra/newview/skins/default/xui/pl/floater_world_map.xml
index 1ce7c19e00..aa89a1b76d 100644
--- a/indra/newview/skins/default/xui/pl/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/pl/floater_world_map.xml
@@ -1,5 +1,8 @@
+
+ (nienazwana działka)
+
diff --git a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
index 0151e116c6..b3fa58ca0f 100644
--- a/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pl/panel_preferences_graphics1.xml
@@ -102,7 +102,7 @@
-
+
diff --git a/indra/newview/skins/starlight/xui/en/floater_world_map.xml b/indra/newview/skins/starlight/xui/en/floater_world_map.xml
index 7fa2db07cb..8ee390c170 100644
--- a/indra/newview/skins/starlight/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/starlight/xui/en/floater_world_map.xml
@@ -14,6 +14,7 @@
single_instance="true"
title="World Map"
width="650">
+ (Unnamed Parcel)
+ (Unnamed Parcel)
import shlex
@@ -76,7 +77,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
#
if self.is_packaging_viewer():
- with self.prefix(src="app_settings"):
+ with self.prefix(src_dst="app_settings"):
self.exclude("logcontrol.xml")
self.exclude("logcontrol-dev.xml")
self.path("*.ini")
@@ -100,7 +101,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
# Copy dictionaries to a place where the viewer can find them if ran from visual studio
# ... and the included spell checking dictionaries
# pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
-# with self.prefix(src=pkgdir,dst=""):
+# with self.prefix(src=pkgdir):
# self.path("dictionaries")
#
@@ -127,17 +128,18 @@ class ViewerManifest(LLManifest,FSViewerManifest):
Type='String',
Value=''))
settings_install = {}
- if 'sourceid' in self.args and self.args['sourceid']:
+ sourceid = self.args.get('sourceid')
+ if sourceid:
settings_install['sourceid'] = settings_template['sourceid'].copy()
- settings_install['sourceid']['Value'] = self.args['sourceid']
- print "Set sourceid in settings_install.xml to '%s'" % self.args['sourceid']
+ settings_install['sourceid']['Value'] = sourceid
+ print "Set sourceid in settings_install.xml to '%s'" % sourceid
- if 'channel_suffix' in self.args and self.args['channel_suffix']:
+ if self.args.get('channel_suffix'):
settings_install['CmdLineChannel'] = settings_template['CmdLineChannel'].copy()
settings_install['CmdLineChannel']['Value'] = self.channel_with_pkg_suffix()
print "Set CmdLineChannel in settings_install.xml to '%s'" % self.channel_with_pkg_suffix()
- if 'grid' in self.args and self.args['grid']:
+ if self.args.get('grid'):
settings_install['CmdLineGridChoice'] = settings_template['CmdLineGridChoice'].copy()
settings_install['CmdLineGridChoice']['Value'] = self.grid()
print "Set CmdLineGridChoice in settings_install.xml to '%s'" % self.grid()
@@ -149,28 +151,28 @@ class ViewerManifest(LLManifest,FSViewerManifest):
src="environment")
- with self.prefix(src="character"):
+ with self.prefix(src_dst="character"):
self.path("*.llm")
self.path("*.xml")
self.path("*.tga")
# Include our fonts
- with self.prefix(src="fonts"):
+ with self.prefix(src_dst="fonts"):
self.path("*.ttf")
self.path("*.txt")
self.path("*.xml")
# Include firestorm resources
- with self.prefix(src="fs_resources"):
+ with self.prefix(src_dst="fs_resources"):
self.path("*.txt")
self.path("*.lsl")
self.path("*.lsltxt")
# skins
- with self.prefix(src="skins"):
+ with self.prefix(src_dst="skins"):
self.path("skins.xml")
# include the entire textures directory recursively
- with self.prefix(src="*/textures"):
+ with self.prefix(src_dst="*/textures"):
self.path("*/*.tga")
self.path("*/*.j2c")
self.path("*/*.jpg")
@@ -208,7 +210,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
# local_assets dir (for pre-cached textures)
- with self.prefix(src="local_assets"):
+ with self.prefix(src_dst="local_assets"):
self.path("*.j2c")
self.path("*.tga")
@@ -224,6 +226,10 @@ class ViewerManifest(LLManifest,FSViewerManifest):
"Address Size":self.address_size,
"Update Service":"https://update.secondlife.com/update",
}
+ # Only store this if it's both present and non-empty
+ bugsplat_db = self.args.get('bugsplat')
+ if bugsplat_db:
+ build_data_dict["BugSplat DB"] = bugsplat_db
build_data_dict = self.finish_build_data_dict(build_data_dict)
with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle:
json.dump(build_data_dict,build_data_handle)
@@ -244,8 +250,9 @@ class ViewerManifest(LLManifest,FSViewerManifest):
def channel_with_pkg_suffix(self):
fullchannel=self.channel()
- if 'channel_suffix' in self.args and self.args['channel_suffix']:
- fullchannel+=' '+self.args['channel_suffix']
+ channel_suffix = self.args.get('channel_suffix')
+ if channel_suffix:
+ fullchannel+=' '+channel_suffix
return fullchannel
def channel_variant(self):
@@ -253,8 +260,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
return self.channel().replace(CHANNEL_VENDOR_BASE, "").strip()
def channel_type(self): # returns 'release', 'beta', 'project', or 'test'
- global CHANNEL_VENDOR_BASE
- channel_qualifier=self.channel().replace(CHANNEL_VENDOR_BASE, "").lower().strip()
+ channel_qualifier=self.channel_variant().lower()
if channel_qualifier.startswith('release'):
channel_type='release'
elif channel_qualifier.startswith('beta'):
@@ -277,12 +283,13 @@ class ViewerManifest(LLManifest,FSViewerManifest):
if self.channel_type() == 'release':
suffix=suffix.replace('Release', '').strip()
# for the base release viewer, suffix will now be null - for any other, append what remains
- if len(suffix) > 0:
- #suffix = "_"+ ("_".join(suffix.split()))
- suffix = "_".join(suffix.split())
+ if suffix:
+ #suffix = "_".join([''] + suffix.split())
+ suffix = "_".join(suffix.split()) # Don't prepend underscore before suffix
# the additional_packages mechanism adds more to the installer name (but not to the app name itself)
- if 'channel_suffix' in self.args and self.args['channel_suffix']:
- suffix+='_'+("_".join(self.args['channel_suffix'].split()))
+ # ''.split() produces empty list, so suffix only changes if
+ # channel_suffix is non-empty
+ suffix = "_".join([suffix] + self.args.get('channel_suffix', '').split())
return suffix
def installer_base_name(self):
@@ -486,7 +493,8 @@ class WindowsManifest(ViewerManifest):
def finish_build_data_dict(self, build_data_dict):
#MAINT-7294: Windows exe names depend on channel name, so write that in also
- build_data_dict.update({'Executable':self.final_exe()})
+ build_data_dict['Executable'] = self.final_exe()
+ build_data_dict['AppName'] = self.app_name()
return build_data_dict
def test_msvcrt_and_copy_action(self, src, dst):
@@ -532,7 +540,7 @@ class WindowsManifest(ViewerManifest):
pass
except NoMatchingAssemblyException as err:
pass
-
+
self.ccopy(src,dst)
else:
raise Exception("Directories are not supported by test_CRT_and_copy_action()")
@@ -551,34 +559,27 @@ class WindowsManifest(ViewerManifest):
self.path(src='%s/firestorm-bin.exe' % self.args['configuration'], dst=self.final_exe())
# Remove VMP
- #with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
+ #with self.prefix(src=os.path.join(pkgdir, "VMP")):
# include the compiled launcher scripts so that it gets included in the file_list
- # self.path('SL_Launcher.exe')
- #IUM is not normally executed directly, just imported. No exe needed.
- # self.path("InstallerUserMessage.py")
+ # self.path('SLVersionChecker.exe')
- #with self.prefix(src=self.icon_path(), dst="vmp_icons"):
- # self.path("secondlife.ico")
+ #with self.prefix(dst="vmp_icons"):
+ # with self.prefix(src=self.icon_path()):
+ # self.path("secondlife.ico")
+ #VMP Tkinter icons
+ # with self.prefix(src="vmp_icons"):
+ # self.path("*.png")
+ # self.path("*.gif")
- #VMP Tkinter icons
- #with self.prefix("vmp_icons"):
- # self.path("*.png")
- # self.path("*.gif")
-
- #before, we only needed llbase at build time. With VMP, we need it at run time.
- #with self.prefix(src=os.path.join(pkgdir, "lib", "python", "llbase"), dst="llbase"):
- # self.path("*.py")
- # self.path("_cllsd.so")
# Remove VMP
-
# Plugin host application
self.path2basename(os.path.join(os.pardir,
'llplugin', 'slplugin', self.args['configuration']),
"slplugin.exe")
# Get shared libs from the shared libs staging directory
- with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
- dst=""):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir,
+ 'sharedlibs', self.args['configuration'])):
# Get llcommon and deps. If missing assume static linkage and continue.
try:
@@ -655,6 +656,17 @@ class WindowsManifest(ViewerManifest):
# Hunspell
self.path("libhunspell.dll")
+ # BugSplat
+ if self.args.get('bugsplat'):
+ if(self.address_size == 64):
+ self.path("BsSndRpt64.exe")
+ self.path("BugSplat64.dll")
+ self.path("BugSplatRc64.dll")
+ else:
+ self.path("BsSndRpt.exe")
+ self.path("BugSplat.dll")
+ self.path("BugSplatRc.dll")
+
# Growl
self.path("growl.dll")
self.path("growl++.dll")
@@ -677,116 +689,119 @@ class WindowsManifest(ViewerManifest):
except:
print "Skipping libtcmalloc_minimal.dll"
-
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
- with self.prefix(src=pkgdir,dst=""):
+
+ with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
self.path("VivoxAUP.txt")
# Media plugins - CEF
- with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
- self.path("media_plugin_cef.dll")
+ with self.prefix(dst="llplugin"):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins')):
+ with self.prefix(src=os.path.join('cef', self.args['configuration'])):
+ self.path("media_plugin_cef.dll")
- # Media plugins - LibVLC
- with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration'], dst="llplugin"):
- self.path("media_plugin_libvlc.dll")
+ # Media plugins - LibVLC
+ with self.prefix(src=os.path.join('libvlc', self.args['configuration'])):
+ self.path("media_plugin_libvlc.dll")
- # Media plugins - Example (useful for debugging - not shipped with release viewer)
- if self.channel_type() != 'release':
- with self.prefix(src='../media_plugins/example/%s' % self.args['configuration'], dst="llplugin"):
- self.path("media_plugin_example.dll")
+ # Media plugins - Example (useful for debugging - not shipped with release viewer)
+ if self.channel_type() != 'release':
+ with self.prefix(src=os.path.join('example', self.args['configuration'])):
+ self.path("media_plugin_example.dll")
- # CEF runtime files - debug
- # CEF runtime files - not debug (release, relwithdebinfo etc.)
- config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
- with self.prefix(src=os.path.join(pkgdir, 'bin', config), dst="llplugin"):
- self.path("chrome_elf.dll")
- self.path("d3dcompiler_43.dll")
- self.path("d3dcompiler_47.dll")
- self.path("libcef.dll")
- self.path("libEGL.dll")
- self.path("libGLESv2.dll")
- self.path("dullahan_host.exe")
- self.path("natives_blob.bin")
- self.path("snapshot_blob.bin")
- self.path("widevinecdmadapter.dll")
+ # CEF runtime files - debug
+ # CEF runtime files - not debug (release, relwithdebinfo etc.)
+ config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
+ with self.prefix(src=os.path.join(pkgdir, 'bin', config)):
+ self.path("chrome_elf.dll")
+ self.path("d3dcompiler_43.dll")
+ self.path("d3dcompiler_47.dll")
+ self.path("libcef.dll")
+ self.path("libEGL.dll")
+ self.path("libGLESv2.dll")
+ self.path("dullahan_host.exe")
+ self.path("natives_blob.bin")
+ self.path("snapshot_blob.bin")
+ self.path("widevinecdmadapter.dll")
- # MSVC DLLs needed for CEF and have to be in same directory as plugin
- with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release'), dst="llplugin"):
- self.path("msvcp120.dll")
- self.path("msvcr120.dll")
+ # MSVC DLLs needed for CEF and have to be in same directory as plugin
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir,
+ 'sharedlibs', 'Release')):
+ self.path("msvcp120.dll")
+ self.path("msvcr120.dll")
- # CEF files common to all configurations
- with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="llplugin"):
- self.path("cef.pak")
- self.path("cef_100_percent.pak")
- self.path("cef_200_percent.pak")
- self.path("cef_extensions.pak")
- self.path("devtools_resources.pak")
- self.path("icudtl.dat")
+ # CEF files common to all configurations
+ with self.prefix(src=os.path.join(pkgdir, 'resources')):
+ self.path("cef.pak")
+ self.path("cef_100_percent.pak")
+ self.path("cef_200_percent.pak")
+ self.path("cef_extensions.pak")
+ self.path("devtools_resources.pak")
+ self.path("icudtl.dat")
- with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('llplugin', 'locales')):
- self.path("am.pak")
- self.path("ar.pak")
- self.path("bg.pak")
- self.path("bn.pak")
- self.path("ca.pak")
- self.path("cs.pak")
- self.path("da.pak")
- self.path("de.pak")
- self.path("el.pak")
- self.path("en-GB.pak")
- self.path("en-US.pak")
- self.path("es-419.pak")
- self.path("es.pak")
- self.path("et.pak")
- self.path("fa.pak")
- self.path("fi.pak")
- self.path("fil.pak")
- self.path("fr.pak")
- self.path("gu.pak")
- self.path("he.pak")
- self.path("hi.pak")
- self.path("hr.pak")
- self.path("hu.pak")
- self.path("id.pak")
- self.path("it.pak")
- self.path("ja.pak")
- self.path("kn.pak")
- self.path("ko.pak")
- self.path("lt.pak")
- self.path("lv.pak")
- self.path("ml.pak")
- self.path("mr.pak")
- self.path("ms.pak")
- self.path("nb.pak")
- self.path("nl.pak")
- self.path("pl.pak")
- self.path("pt-BR.pak")
- self.path("pt-PT.pak")
- self.path("ro.pak")
- self.path("ru.pak")
- self.path("sk.pak")
- self.path("sl.pak")
- self.path("sr.pak")
- self.path("sv.pak")
- self.path("sw.pak")
- self.path("ta.pak")
- self.path("te.pak")
- self.path("th.pak")
- self.path("tr.pak")
- self.path("uk.pak")
- self.path("vi.pak")
- self.path("zh-CN.pak")
- self.path("zh-TW.pak")
+ with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
+ self.path("am.pak")
+ self.path("ar.pak")
+ self.path("bg.pak")
+ self.path("bn.pak")
+ self.path("ca.pak")
+ self.path("cs.pak")
+ self.path("da.pak")
+ self.path("de.pak")
+ self.path("el.pak")
+ self.path("en-GB.pak")
+ self.path("en-US.pak")
+ self.path("es-419.pak")
+ self.path("es.pak")
+ self.path("et.pak")
+ self.path("fa.pak")
+ self.path("fi.pak")
+ self.path("fil.pak")
+ self.path("fr.pak")
+ self.path("gu.pak")
+ self.path("he.pak")
+ self.path("hi.pak")
+ self.path("hr.pak")
+ self.path("hu.pak")
+ self.path("id.pak")
+ self.path("it.pak")
+ self.path("ja.pak")
+ self.path("kn.pak")
+ self.path("ko.pak")
+ self.path("lt.pak")
+ self.path("lv.pak")
+ self.path("ml.pak")
+ self.path("mr.pak")
+ self.path("ms.pak")
+ self.path("nb.pak")
+ self.path("nl.pak")
+ self.path("pl.pak")
+ self.path("pt-BR.pak")
+ self.path("pt-PT.pak")
+ self.path("ro.pak")
+ self.path("ru.pak")
+ self.path("sk.pak")
+ self.path("sl.pak")
+ self.path("sr.pak")
+ self.path("sv.pak")
+ self.path("sw.pak")
+ self.path("ta.pak")
+ self.path("te.pak")
+ self.path("th.pak")
+ self.path("tr.pak")
+ self.path("uk.pak")
+ self.path("vi.pak")
+ self.path("zh-CN.pak")
+ self.path("zh-TW.pak")
- with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="llplugin"):
- self.path("libvlc.dll")
- self.path("libvlccore.dll")
- self.path("plugins/")
+ with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
+ self.path("libvlc.dll")
+ self.path("libvlccore.dll")
+ self.path("plugins/")
- # pull in the crash logger and updater from other projects
+ # pull in the crash logger from other projects
# tag:"crash-logger" here as a cue to the exporter
self.path(src='../win_crash_logger/%s/windows-crash-logger.exe' % self.args['configuration'],
dst="win_crash_logger.exe")
@@ -796,10 +811,10 @@ class WindowsManifest(ViewerManifest):
# is a 32bit process and Windows will silently copy the 32bit versions from
# the SysWOW64 folder, even if explicitly trying to copy from System32!
if (self.address_size == 64):
- with self.prefix(src=os.path.join(os.pardir, '..', 'indra', 'newview', 'installers', 'windows_x64'), dst="llplugin"):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, os.pardir, 'indra', 'newview', 'installers', 'windows_x64'), dst="llplugin"):
self.path("msvcp120.dll")
self.path("msvcr120.dll")
- with self.prefix(src=os.path.join(os.pardir, '..', 'indra', 'newview', 'installers', 'windows_x64'), dst=""):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, os.pardir, 'indra', 'newview', 'installers', 'windows_x64')):
self.path("msvcp120.dll")
self.path("msvcr120.dll")
@@ -889,7 +904,7 @@ class WindowsManifest(ViewerManifest):
substitution_strings['is64bit'] = (1 if (self.address_size == 64) else 0)
version_vars = """
- !define INSTEXE "SL_Launcher.exe"
+ !define INSTEXE "SLVersionChecker.exe"
!define VERSION "%(version_short)s"
!define VERSION_LONG "%(version)s"
!define VERSION_DASHES "%(version_dashes)s"
@@ -913,10 +928,10 @@ class WindowsManifest(ViewerManifest):
if(self.address_size == 64):
engage_registry="SetRegView 64"
- program_files="$PROGRAMFILES64"
+ program_files="!define MULTIUSER_USE_PROGRAMFILES64"
else:
engage_registry="SetRegView 32"
- program_files="$PROGRAMFILES32"
+ program_files=""
tempfile = "firestorm_setup_tmp.nsi"
@@ -937,16 +952,15 @@ class WindowsManifest(ViewerManifest):
# note that the enclosing setup exe is signed later, after the makensis makes it.
# Unlike the viewer binary, the VMP filenames are invariant with respect to version, os, etc.
#for exe in (
- # "SL_Launcher.exe",
+ # self.final_exe(),
+ # "SLVersionChecker.exe",
# ):
# self.sign(exe)
- # We use the Unicode version of NSIS, available from
- # http://www.scratchpaper.com/
# Check two paths, one for Program Files, and one for Program Files (x86).
# Yay 64bit windows.
for ProgramFiles in 'ProgramFiles', 'ProgramFiles(x86)':
- NSIS_path = os.path.expandvars(r'${%s}\NSIS\Unicode\makensis.exe' % ProgramFiles)
+ NSIS_path = os.path.expandvars(r'${%s}\NSIS\makensis.exe' % ProgramFiles)
if os.path.exists(NSIS_path):
break
installer_created=False
@@ -1007,395 +1021,328 @@ class DarwinManifest(ViewerManifest):
return True
# construct method VMP trampoline crazy VMP launcher juggling shamelessly replaced with old version
- # def construct(self):
- # # These are the names of the top-level application and the embedded
- # # applications for the VMP and for the actual viewer, respectively.
- # # These names, without the .app suffix, determine the flyover text for
- # # their corresponding Dock icons.
- # toplevel_app, toplevel_icon = "Second Life.app", "secondlife.icns"
- # launcher_app, launcher_icon = "Second Life Launcher.app", "secondlife.icns"
- # viewer_app, viewer_icon = "Second Life Viewer.app", "secondlife.icns"
+ # def is_rearranging(self):
+ # # That said, some stuff should still only be performed once.
+ # # Are either of these actions in 'actions'? Is the set intersection
+ # # non-empty?
+ # return bool(set(["package", "unpacked"]).intersection(self.args['actions']))
+ # def construct(self):
# # copy over the build result (this is a no-op if run within the xcode script)
- # self.path(os.path.join(self.args['configuration'], toplevel_app), dst="")
+ # self.path(os.path.join(self.args['configuration'], self.channel()+".app"), dst="")
# pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
# relpkgdir = os.path.join(pkgdir, "lib", "release")
# debpkgdir = os.path.join(pkgdir, "lib", "debug")
- # # -------------------- top-level Second Life.app ---------------------
- # # top-level Second Life application is only a container
# with self.prefix(src="", dst="Contents"): # everything goes in Contents
- # # top-level Info.plist is as generated by CMake
- # Info_plist = "Info.plist"
- # ## This self.path() call reports 0 files... skip?
- # self.path(Info_plist)
- # Info_plist = self.dst_path_of(Info_plist)
+ # bugsplat_db = self.args.get('bugsplat')
+ # if bugsplat_db:
+ # # Inject BugsplatServerURL into Info.plist if provided.
+ # Info_plist = self.dst_path_of("Info.plist")
+ # Info = plistlib.readPlist(Info_plist)
+ # # https://www.bugsplat.com/docs/platforms/os-x#configuration
+ # Info["BugsplatServerURL"] = \
+ # "https://{}.bugsplat.com/".format(bugsplat_db)
+ # self.put_in_file(
+ # plistlib.writePlistToString(Info),
+ # os.path.basename(Info_plist),
+ # "Info.plist")
+
+ # # CEF framework goes inside Contents/Frameworks.
+ # # Remember where we parked this car.
+ # with self.prefix(src="", dst="Frameworks"):
+ # CEF_framework = "Chromium Embedded Framework.framework"
+ # self.path2basename(relpkgdir, CEF_framework)
+ # CEF_framework = self.dst_path_of(CEF_framework)
+
+ # if self.args.get('bugsplat'):
+ # self.path2basename(relpkgdir, "BugsplatMac.framework")
- # # the one file in top-level MacOS directory is the trampoline to
- # # our nested launcher_app
# with self.prefix(dst="MacOS"):
- # toplevel_MacOS = self.get_dst_prefix()
- # trampoline = self.put_in_file("""\
-# #!/bin/bash
-# open "%s" --args "$@"
-# """ %
- # # up one directory from MacOS to its sibling Resources directory
- # os.path.join('$(dirname "$0")', os.pardir, 'Resources', launcher_app),
- # "SL_Launcher", # write this file
- # "trampoline") # flag to add to list of copied files
- # # Script must be executable
- # self.run_command(["chmod", "+x", trampoline])
+ # executable = self.dst_path_of(self.channel())
+ # if self.args.get('bugsplat'):
+ # # According to Apple Technical Note TN2206:
+ # # https://developer.apple.com/library/archive/technotes/tn2206/_index.html#//apple_ref/doc/uid/DTS40007919-CH1-TNTAG207
+ # # "If an app uses @rpath or an absolute path to link to a
+ # # dynamic library outside of the app, the app will be
+ # # rejected by Gatekeeper. ... Neither the codesign nor the
+ # # spctl tool will show the error."
+ # # (Thanks, Apple. Maybe fix spctl to warn?)
+ # # The BugsplatMac framework embeds @rpath, which is
+ # # causing scary Gatekeeper popups at viewer start. Work
+ # # around this by changing the reference baked into our
+ # # viewer. The install_name_tool -change option needs the
+ # # previous value. Instead of guessing -- which might
+ # # silently be defeated by a BugSplat SDK update that
+ # # changes their baked-in @rpath -- ask for the path
+ # # stamped into the framework.
+ # # Let exception, if any, propagate -- if this doesn't
+ # # work, we need the build to noisily fail!
+ # oldpath = subprocess.check_output(
+ # ['objdump', '-macho', '-dylib-id', '-non-verbose',
+ # os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")]
+ # ).splitlines()[-1] # take the last line of output
+ # self.run_command(
+ # ['install_name_tool', '-change', oldpath,
+ # '@executable_path/../Frameworks/BugsplatMac.framework/BugsplatMac',
+ # executable])
- # # Make a symlink to a nested app Frameworks directory that doesn't
- # # yet exist. We shouldn't need this; the only things that need
- # # Frameworks are nested apps under viewer_app, and they should
- # # simply find its Contents/Frameworks by relative pathnames. But
- # # empirically, we do: if we omit this symlink, CEF doesn't work --
- # # the login splash screen doesn't even display. SIIIIGH.
- # # We're passing a path that's already relative, hence symlinkf()
- # # rather than relsymlinkf().
- # self.symlinkf(os.path.join("Resources", viewer_app, "Contents", "Frameworks"))
+ # # NOTE: the -S argument to strip causes it to keep
+ # # enough info for annotated backtraces (i.e. function
+ # # names in the crash log). 'strip' with no arguments
+ # # yields a slightly smaller binary but makes crash
+ # # logs mostly useless. This may be desirable for the
+ # # final release. Or not.
+ # if ("package" in self.args['actions'] or
+ # "unpacked" in self.args['actions']):
+ # self.run_command(
+ # ['strip', '-S', executable])
- # with self.prefix(src="", dst="Resources"):
- # # top-level Resources directory should be pretty sparse
- # # need .icns file referenced by top-level Info.plist
+ # with self.prefix(dst="Resources"):
+ # # defer cross-platform file copies until we're in the
+ # # nested Resources directory
+ # super(DarwinManifest, self).construct()
+
+ # # need .icns file referenced by Info.plist
# with self.prefix(src=self.icon_path(), dst="") :
- # self.path(toplevel_icon)
+ # self.path("secondlife.icns")
- # # ------------------- nested launcher_app --------------------
- # with self.prefix(dst=os.path.join(launcher_app, "Contents")):
- # # Info.plist is just like top-level one...
- # Info = plistlib.readPlist(Info_plist)
- # # except for these replacements:
- # Info["CFBundleExecutable"] = "SL_Launcher"
- # Info["CFBundleIconFile"] = launcher_icon
- # self.put_in_file(
- # plistlib.writePlistToString(Info),
- # os.path.basename(Info_plist),
- # "Info.plist")
+ # # Copy in the updater script and helper modules
+ # self.path(src=os.path.join(pkgdir, 'VMP'), dst="updater")
- # # copy VMP libs to MacOS
- # with self.prefix(dst="MacOS"):
- # #this copies over the python wrapper script,
- # #associated utilities and required libraries, see
- # #SL-321, SL-322, SL-323
- # with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
- # self.path("SL_Launcher")
- # self.path("*.py")
- # # certifi will be imported by requests; this is
- # # our custom version to get our ca-bundle.crt
- # self.path("certifi")
- # with self.prefix(src=os.path.join(pkgdir, "lib", "python"), dst=""):
- # # llbase provides our llrest service layer and llsd decoding
- # with self.prefix("llbase"):
- # # (Why is llbase treated specially here? What
- # # DON'T we want to copy out of lib/python/llbase?)
- # self.path("*.py")
- # self.path("_cllsd.so")
- # #requests module needed by llbase/llrest.py
- # #this is only needed on POSIX, because in Windows
- # #we compile it into the EXE
- # for pypkg in "chardet", "idna", "requests", "urllib3":
- # self.path(pypkg)
+ # with self.prefix(src="", dst=os.path.join("updater", "icons")):
+ # self.path2basename(self.icon_path(), "secondlife.ico")
+ # with self.prefix(src="vmp_icons", dst=""):
+ # self.path("*.png")
+ # self.path("*.gif")
- # # launcher_app/Contents/Resources
- # with self.prefix(dst="Resources"):
- # with self.prefix(src=self.icon_path(), dst="") :
- # self.path(launcher_icon)
- # with self.prefix(dst="vmp_icons"):
- # self.path("secondlife.ico")
- # #VMP Tkinter icons
- # with self.prefix("vmp_icons"):
- # self.path("*.png")
- # self.path("*.gif")
+ # with self.prefix(src=relpkgdir, dst=""):
+ # self.path("libndofdev.dylib")
+ # self.path("libhunspell-1.3.0.dylib")
- # # -------------------- nested viewer_app ---------------------
- # with self.prefix(dst=os.path.join(viewer_app, "Contents")):
- # # Info.plist is just like top-level one...
- # Info = plistlib.readPlist(Info_plist)
- # # except for these replacements:
- # # (CFBundleExecutable may be moot: SL_Launcher directly
- # # runs the executable, instead of launching the app)
- # Info["CFBundleExecutable"] = "Second Life"
- # Info["CFBundleIconFile"] = viewer_icon
- # self.put_in_file(
- # plistlib.writePlistToString(Info),
- # os.path.basename(Info_plist),
- # "Info.plist")
+ # with self.prefix(src_dst="cursors_mac"):
+ # self.path("*.tif")
- # # CEF framework goes inside viewer_app/Contents/Frameworks.
- # # Remember where we parked this car.
- # with self.prefix(src="", dst="Frameworks"):
- # CEF_framework = "Chromium Embedded Framework.framework"
- # self.path2basename(relpkgdir, CEF_framework)
- # CEF_framework = self.dst_path_of(CEF_framework)
+ # self.path("licenses-mac.txt", dst="licenses.txt")
+ # self.path("featuretable_mac.txt")
+ # self.path("SecondLife.nib")
- # with self.prefix(dst="MacOS"):
- # # CMake constructs the Second Life executable in the
- # # MacOS directory belonging to the top-level Second
- # # Life.app. Move it here.
- # here = self.get_dst_prefix()
- # relbase = os.path.realpath(os.path.dirname(Info_plist))
- # self.cmakedirs(here)
- # for f in os.listdir(toplevel_MacOS):
- # if f == os.path.basename(trampoline):
- # # don't move the trampoline script we just made!
- # continue
- # fromwhere = os.path.join(toplevel_MacOS, f)
- # towhere = os.path.join(here, f)
- # print "Moving %s => %s" % \
- # (self.relpath(fromwhere, relbase),
- # self.relpath(towhere, relbase))
- # # now do it, only without relativizing paths
- # os.rename(fromwhere, towhere)
+ # with self.prefix(src=pkgdir,dst=""):
+ # self.path("ca-bundle.crt")
- # # NOTE: the -S argument to strip causes it to keep
- # # enough info for annotated backtraces (i.e. function
- # # names in the crash log). 'strip' with no arguments
- # # yields a slightly smaller binary but makes crash
- # # logs mostly useless. This may be desirable for the
- # # final release. Or not.
- # if ("package" in self.args['actions'] or
- # "unpacked" in self.args['actions']):
- # self.run_command(
- # ['strip', '-S', self.dst_path_of('Second Life')])
+ # # Translations
+ # self.path("English.lproj/language.txt")
+ # self.replace_in(src="English.lproj/InfoPlist.strings",
+ # dst="English.lproj/InfoPlist.strings",
+ # searchdict={'%%VERSION%%':'.'.join(self.args['version'])}
+ # )
+ # self.path("German.lproj")
+ # self.path("Japanese.lproj")
+ # self.path("Korean.lproj")
+ # self.path("da.lproj")
+ # self.path("es.lproj")
+ # self.path("fr.lproj")
+ # self.path("hu.lproj")
+ # self.path("it.lproj")
+ # self.path("nl.lproj")
+ # self.path("pl.lproj")
+ # self.path("pt.lproj")
+ # self.path("ru.lproj")
+ # self.path("tr.lproj")
+ # self.path("uk.lproj")
+ # self.path("zh-Hans.lproj")
- # with self.prefix(dst="Resources"):
- # # defer cross-platform file copies until we're in the right
- # # nested Resources directory
- # super(DarwinManifest, self).construct()
+ # def path_optional(src, dst):
+ # """
+ # For a number of our self.path() calls, not only do we want
+ # to deal with the absence of src, we also want to remember
+ # which were present. Return either an empty list (absent)
+ # or a list containing dst (present). Concatenate these
+ # return values to get a list of all libs that are present.
+ # """
+ # # This was simple before we started needing to pass
+ # # wildcards. Fortunately, self.path() ends up appending a
+ # # (source, dest) pair to self.file_list for every expanded
+ # # file processed. Remember its size before the call.
+ # oldlen = len(self.file_list)
+ # self.path(src, dst)
+ # # The dest appended to self.file_list has been prepended
+ # # with self.get_dst_prefix(). Strip it off again.
+ # added = [os.path.relpath(d, self.get_dst_prefix())
+ # for s, d in self.file_list[oldlen:]]
+ # if not added:
+ # print "Skipping %s" % dst
+ # return added
- # with self.prefix(src=self.icon_path(), dst="") :
- # self.path(viewer_icon)
+ # # dylibs is a list of all the .dylib files we expect to need
+ # # in our bundled sub-apps. For each of these we'll create a
+ # # symlink from sub-app/Contents/Resources to the real .dylib.
+ # # Need to get the llcommon dll from any of the build directories as well.
+ # libfile_parent = self.get_dst_prefix()
+ # libfile = "libllcommon.dylib"
+ # dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
+ # "llcommon",
+ # self.args['configuration'],
+ # libfile),
+ # os.path.join(relpkgdir, libfile)),
+ # dst=libfile)
- # with self.prefix(src=relpkgdir, dst=""):
- # self.path("libndofdev.dylib")
- # self.path("libhunspell-1.3.0.dylib")
+ # for libfile in (
+ # "libapr-1.0.dylib",
+ # "libaprutil-1.0.dylib",
+ # "libcollada14dom.dylib",
+ # "libexpat.1.dylib",
+ # "libexception_handler.dylib",
+ # "libGLOD.dylib",
+ # # libnghttp2.dylib is a symlink to
+ # # libnghttp2.major.dylib, which is a symlink to
+ # # libnghttp2.version.dylib. Get all of them.
+ # "libnghttp2.*dylib",
+ # ):
+ # dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
- # with self.prefix("cursors_mac"):
- # self.path("*.tif")
+ # # SLVoice and vivox lols, no symlinks needed
+ # for libfile in (
+ # 'libortp.dylib',
+ # 'libsndfile.dylib',
+ # 'libvivoxoal.dylib',
+ # 'libvivoxsdk.dylib',
+ # 'libvivoxplatform.dylib',
+ # 'SLVoice',
+ # ):
+ # self.path2basename(relpkgdir, libfile)
- # self.path("licenses-mac.txt", dst="licenses.txt")
- # self.path("featuretable_mac.txt")
- # self.path("SecondLife.nib")
+ # # dylibs that vary based on configuration
+ # if self.args['configuration'].lower() == 'debug':
+ # for libfile in (
+ # "libfmodexL.dylib",
+ # ):
+ # dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile)
+ # else:
+ # for libfile in (
+ # "libfmodex.dylib",
+ # ):
+ # dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
- # with self.prefix(src=pkgdir,dst=""):
- # self.path("ca-bundle.crt")
+ # # our apps
+ # executable_path = {}
+ # for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
+ # # plugin launcher
+ # (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
+ # ):
+ # self.path2basename(os.path.join(os.pardir,
+ # app_bld_dir, self.args['configuration']),
+ # app)
+ # executable_path[app] = \
+ # self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
- # self.path("SecondLife.nib")
+ # # our apps dependencies on shared libs
+ # # for each app, for each dylib we collected in dylibs,
+ # # create a symlink to the real copy of the dylib.
+ # with self.prefix(dst=os.path.join(app, "Contents", "Resources")):
+ # for libfile in dylibs:
+ # self.relsymlinkf(os.path.join(libfile_parent, libfile))
- # # Translations
- # self.path("English.lproj/language.txt")
- # self.replace_in(src="English.lproj/InfoPlist.strings",
- # dst="English.lproj/InfoPlist.strings",
- # searchdict={'%%VERSION%%':'.'.join(self.args['version'])}
- # )
- # self.path("German.lproj")
- # self.path("Japanese.lproj")
- # self.path("Korean.lproj")
- # self.path("da.lproj")
- # self.path("es.lproj")
- # self.path("fr.lproj")
- # self.path("hu.lproj")
- # self.path("it.lproj")
- # self.path("nl.lproj")
- # self.path("pl.lproj")
- # self.path("pt.lproj")
- # self.path("ru.lproj")
- # self.path("tr.lproj")
- # self.path("uk.lproj")
- # self.path("zh-Hans.lproj")
+ # # Dullahan helper apps go inside SLPlugin.app
+ # with self.prefix(dst=os.path.join(
+ # "SLPlugin.app", "Contents", "Frameworks")):
- # def path_optional(src, dst):
- # """
- # For a number of our self.path() calls, not only do we want
- # to deal with the absence of src, we also want to remember
- # which were present. Return either an empty list (absent)
- # or a list containing dst (present). Concatenate these
- # return values to get a list of all libs that are present.
- # """
- # # This was simple before we started needing to pass
- # # wildcards. Fortunately, self.path() ends up appending a
- # # (source, dest) pair to self.file_list for every expanded
- # # file processed. Remember its size before the call.
- # oldlen = len(self.file_list)
- # self.path(src, dst)
- # # The dest appended to self.file_list has been prepended
- # # with self.get_dst_prefix(). Strip it off again.
- # added = [os.path.relpath(d, self.get_dst_prefix())
- # for s, d in self.file_list[oldlen:]]
- # if not added:
- # print "Skipping %s" % dst
- # return added
+ # frameworkname = 'Chromium Embedded Framework'
- # # dylibs is a list of all the .dylib files we expect to need
- # # in our bundled sub-apps. For each of these we'll create a
- # # symlink from sub-app/Contents/Resources to the real .dylib.
- # # Need to get the llcommon dll from any of the build directories as well.
- # libfile_parent = self.get_dst_prefix()
- # libfile = "libllcommon.dylib"
- # dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
- # "llcommon",
- # self.args['configuration'],
- # libfile),
- # os.path.join(relpkgdir, libfile)),
- # dst=libfile)
+ # # This code constructs a relative symlink from the
+ # # target framework folder back to the real CEF framework.
+ # # It needs to be relative so that the symlink still works when
+ # # (as is normal) the user moves the app bundle out of the DMG
+ # # and into the /Applications folder. Note we pass catch=False,
+ # # letting the uncaught exception terminate the process, since
+ # # without this symlink, Second Life web media can't possibly work.
- # for libfile in (
- # "libapr-1.0.dylib",
- # "libaprutil-1.0.dylib",
- # "libcollada14dom.dylib",
- # "libexpat.1.dylib",
- # "libexception_handler.dylib",
- # "libGLOD.dylib",
- # # libnghttp2.dylib is a symlink to
- # # libnghttp2.major.dylib, which is a symlink to
- # # libnghttp2.version.dylib. Get all of them.
- # "libnghttp2.*dylib",
- # ):
- # dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
+ # # It might seem simpler just to symlink Frameworks back to
+ # # the parent of Chromimum Embedded Framework.framework. But
+ # # that would create a symlink cycle, which breaks our
+ # # packaging step. So make a symlink from Chromium Embedded
+ # # Framework.framework to the directory of the same name, which
+ # # is NOT an ancestor of the symlink.
- # # SLVoice and vivox lols, no symlinks needed
- # for libfile in (
- # 'libortp.dylib',
- # 'libsndfile.dylib',
- # 'libvivoxoal.dylib',
- # 'libvivoxsdk.dylib',
- # 'libvivoxplatform.dylib',
- # 'SLVoice',
- # ):
- # self.path2basename(relpkgdir, libfile)
+ # # from SLPlugin.app/Contents/Frameworks/Chromium Embedded
+ # # Framework.framework back to
+ # # $viewer_app/Contents/Frameworks/Chromium Embedded Framework.framework
+ # SLPlugin_framework = self.relsymlinkf(CEF_framework, catch=False)
- # # dylibs that vary based on configuration
- # if self.args['configuration'].lower() == 'debug':
- # for libfile in (
- # "libfmodexL.dylib",
- # ):
- # dylibs += path_optional(os.path.join(debpkgdir, libfile), libfile)
- # else:
- # for libfile in (
- # "libfmodex.dylib",
- # ):
- # dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
+ # # copy DullahanHelper.app
+ # self.path2basename(relpkgdir, 'DullahanHelper.app')
- # # our apps
- # executable_path = {}
- # for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
- # # plugin launcher
- # (os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
- # ):
- # self.path2basename(os.path.join(os.pardir,
- # app_bld_dir, self.args['configuration']),
- # app)
- # executable_path[app] = \
- # self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
+ # # and fix that up with a Frameworks/CEF symlink too
+ # with self.prefix(dst=os.path.join(
+ # 'DullahanHelper.app', 'Contents', 'Frameworks')):
+ # # from Dullahan Helper.app/Contents/Frameworks/Chromium Embedded
+ # # Framework.framework back to
+ # # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework
+ # # Since SLPlugin_framework is itself a
+ # # symlink, don't let relsymlinkf() resolve --
+ # # explicitly call relpath(symlink=True) and
+ # # create that symlink here.
+ # DullahanHelper_framework = \
+ # self.symlinkf(self.relpath(SLPlugin_framework, symlink=True),
+ # catch=False)
- # # our apps dependencies on shared libs
- # # for each app, for each dylib we collected in dylibs,
- # # create a symlink to the real copy of the dylib.
- # with self.prefix(dst=os.path.join(app, "Contents", "Resources")):
- # for libfile in dylibs:
- # self.relsymlinkf(os.path.join(libfile_parent, libfile))
+ # # change_command includes install_name_tool, the
+ # # -change subcommand and the old framework rpath
+ # # stamped into the executable. To use it with
+ # # run_command(), we must still append the new
+ # # framework path and the pathname of the
+ # # executable to change.
+ # change_command = [
+ # 'install_name_tool', '-change',
+ # '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework']
- # # Dullahan helper apps go inside SLPlugin.app
- # with self.prefix(dst=os.path.join(
- # "SLPlugin.app", "Contents", "Frameworks")):
+ # with self.prefix(dst=os.path.join(
+ # 'DullahanHelper.app', 'Contents', 'MacOS')):
+ # # Now self.get_dst_prefix() is, at runtime,
+ # # @executable_path. Locate the helper app
+ # # framework (which is a symlink) from here.
+ # newpath = os.path.join(
+ # '@executable_path',
+ # self.relpath(DullahanHelper_framework, symlink=True),
+ # frameworkname)
+ # # and restamp the DullahanHelper executable
+ # self.run_command(
+ # change_command +
+ # [newpath, self.dst_path_of('DullahanHelper')])
- # frameworkname = 'Chromium Embedded Framework'
+ # # SLPlugin plugins
+ # with self.prefix(dst="llplugin"):
+ # dylibexecutable = 'media_plugin_cef.dylib'
+ # self.path2basename("../media_plugins/cef/" + self.args['configuration'],
+ # dylibexecutable)
- # # This code constructs a relative symlink from the
- # # target framework folder back to the real CEF framework.
- # # It needs to be relative so that the symlink still works when
- # # (as is normal) the user moves the app bundle out of the DMG
- # # and into the /Applications folder. Note we pass catch=False,
- # # letting the uncaught exception terminate the process, since
- # # without this symlink, Second Life web media can't possibly work.
+ # # Do this install_name_tool *after* media plugin is copied over.
+ # # Locate the framework lib executable -- relative to
+ # # SLPlugin.app/Contents/MacOS, which will be our
+ # # @executable_path at runtime!
+ # newpath = os.path.join(
+ # '@executable_path',
+ # self.relpath(SLPlugin_framework, executable_path["SLPlugin.app"],
+ # symlink=True),
+ # frameworkname)
+ # # restamp media_plugin_cef.dylib
+ # self.run_command(
+ # change_command +
+ # [newpath, self.dst_path_of(dylibexecutable)])
- # # It might seem simpler just to symlink Frameworks back to
- # # the parent of Chromimum Embedded Framework.framework. But
- # # that would create a symlink cycle, which breaks our
- # # packaging step. So make a symlink from Chromium Embedded
- # # Framework.framework to the directory of the same name, which
- # # is NOT an ancestor of the symlink.
+ # # copy LibVLC plugin itself
+ # self.path2basename("../media_plugins/libvlc/" + self.args['configuration'],
+ # "media_plugin_libvlc.dylib")
- # # from SLPlugin.app/Contents/Frameworks/Chromium Embedded
- # # Framework.framework back to
- # # $viewer_app/Contents/Frameworks/Chromium Embedded Framework.framework
- # SLPlugin_framework = self.relsymlinkf(CEF_framework, catch=False)
+ # # copy LibVLC dynamic libraries
+ # with self.prefix(src=relpkgdir, dst="lib"):
+ # self.path( "libvlc*.dylib*" )
+ # # copy LibVLC plugins folder
+ # with self.prefix(src='plugins', dst=""):
+ # self.path( "*.dylib" )
+ # self.path( "plugins.dat" )
- # # copy DullahanHelper.app
- # self.path2basename(relpkgdir, 'DullahanHelper.app')
-
- # # and fix that up with a Frameworks/CEF symlink too
- # with self.prefix(dst=os.path.join(
- # 'DullahanHelper.app', 'Contents', 'Frameworks')):
- # # from Dullahan Helper.app/Contents/Frameworks/Chromium Embedded
- # # Framework.framework back to
- # # SLPlugin.app/Contents/Frameworks/Chromium Embedded Framework.framework
- # # Since SLPlugin_framework is itself a
- # # symlink, don't let relsymlinkf() resolve --
- # # explicitly call relpath(symlink=True) and
- # # create that symlink here.
- # DullahanHelper_framework = \
- # self.symlinkf(self.relpath(SLPlugin_framework, symlink=True),
- # catch=False)
-
- # # change_command includes install_name_tool, the
- # # -change subcommand and the old framework rpath
- # # stamped into the executable. To use it with
- # # run_command(), we must still append the new
- # # framework path and the pathname of the
- # # executable to change.
- # change_command = [
- # 'install_name_tool', '-change',
- # '@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework']
-
- # with self.prefix(dst=os.path.join(
- # 'DullahanHelper.app', 'Contents', 'MacOS')):
- # # Now self.get_dst_prefix() is, at runtime,
- # # @executable_path. Locate the helper app
- # # framework (which is a symlink) from here.
- # newpath = os.path.join(
- # '@executable_path',
- # self.relpath(DullahanHelper_framework, symlink=True),
- # frameworkname)
- # # and restamp the DullahanHelper executable
- # self.run_command(
- # change_command +
- # [newpath, self.dst_path_of('DullahanHelper')])
-
- # # SLPlugin plugins
- # with self.prefix(dst="llplugin"):
- # dylibexecutable = 'media_plugin_cef.dylib'
- # self.path2basename("../media_plugins/cef/" + self.args['configuration'],
- # dylibexecutable)
-
- # # Do this install_name_tool *after* media plugin is copied over.
- # # Locate the framework lib executable -- relative to
- # # SLPlugin.app/Contents/MacOS, which will be our
- # # @executable_path at runtime!
- # newpath = os.path.join(
- # '@executable_path',
- # self.relpath(SLPlugin_framework, executable_path["SLPlugin.app"],
- # symlink=True),
- # frameworkname)
- # # restamp media_plugin_cef.dylib
- # self.run_command(
- # change_command +
- # [newpath, self.dst_path_of(dylibexecutable)])
-
- # # copy LibVLC plugin itself
- # self.path2basename("../media_plugins/libvlc/" + self.args['configuration'],
- # "media_plugin_libvlc.dylib")
-
- # # copy LibVLC dynamic libraries
- # with self.prefix(src=relpkgdir, dst="lib"):
- # self.path( "libvlc*.dylib*" )
- # # copy LibVLC plugins folder
- # with self.prefix(src='plugins', dst=""):
- # self.path( "*.dylib" )
- # self.path( "plugins.dat" )
def construct(self):
# copy over the build result (this is a no-op if run within the xcode script)
self.path(self.args['configuration'] + "/Firestorm.app", dst="")
@@ -1408,7 +1355,7 @@ class DarwinManifest(ViewerManifest):
chardetdir = os.path.join(pkgdir, "lib", "python", "chardet")
idnadir = os.path.join(pkgdir, "lib", "python", "idna")
- with self.prefix(src="", dst="Contents"): # everything goes in Contents
+ with self.prefix(dst="Contents"): # everything goes in Contents
self.path("Info.plist", dst="Info.plist")
# copy additional libs in /Contents/MacOS/
@@ -1419,10 +1366,10 @@ class DarwinManifest(ViewerManifest):
self.path("../packages/Frameworks/Growl", dst="Frameworks/Growl")
# most everything goes in the Resources directory
- with self.prefix(src="", dst="Resources"):
+ with self.prefix(dst="Resources"):
super(DarwinManifest, self).construct()
- with self.prefix("cursors_mac"):
+ with self.prefix(src_dst="cursors_mac"):
self.path("*.tif")
self.path("licenses-mac.txt", dst="licenses.txt")
@@ -1433,11 +1380,10 @@ class DarwinManifest(ViewerManifest):
self.path("ca-bundle.crt")
icon_path = self.icon_path()
- with self.prefix(src=icon_path, dst="") :
+ with self.prefix(src=icon_path) :
self.path("firestorm_icon.icns")
self.path("Firestorm.nib")
-
# Translations
self.path("English.lproj/language.txt")
self.replace_in(src="English.lproj/InfoPlist.strings",
@@ -1564,6 +1510,7 @@ class DarwinManifest(ViewerManifest):
dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
# our apps
+ executable_path = {}
for app_bld_dir, app in (("mac_crash_logger", "mac-crash-logger.app"),
# plugin launcher
(os.path.join("llplugin", "slplugin"), "SLPlugin.app"),
@@ -1571,6 +1518,8 @@ class DarwinManifest(ViewerManifest):
self.path2basename(os.path.join(os.pardir,
app_bld_dir, self.args['configuration']),
app)
+ executable_path[app] = \
+ self.dst_path_of(os.path.join(app, "Contents", "MacOS"))
# our apps dependencies on shared libs
# for each app, for each dylib we collected in dylibs,
@@ -1586,15 +1535,15 @@ class DarwinManifest(ViewerManifest):
# Moved from the x86_64 specific version because code
# below that does symlinking and path fixup depends on it.
- with self.prefix(src="../packages/bin_x86", dst=""):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'bin_x86')):
self.path("SLPlugin.app", "SLPlugin.app")
- with self.prefix(src = "llplugin", dst="llplugin"):
+ with self.prefix(src_dst="llplugin"):
self.path("media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
self.path("media_plugin_cef.dylib", "media_plugin_cef.dylib")
# Dullahan helper apps go inside SLPlugin.app
- with self.prefix(src="", dst="SLPlugin.app/Contents/Frameworks"):
+ with self.prefix(dst="SLPlugin.app/Contents/Frameworks"):
helperappfile = 'DullahanHelper.app'
self.path2basename(relpkgdir, helperappfile)
@@ -1610,30 +1559,29 @@ class DarwinManifest(ViewerManifest):
self.dst_path_of('DullahanHelper.app/Contents/MacOS/'
'Frameworks/Chromium Embedded Framework.framework')
-
helperexecutablepath = self.dst_path_of('SLPlugin.app/Contents/Frameworks/DullahanHelper.app/Contents/MacOS/DullahanHelper')
self.run_command_shell('install_name_tool -change '
'"@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" '
'"@executable_path/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" "%s"' % helperexecutablepath)
# SLPlugin plugins
- with self.prefix(src="", dst="llplugin"):
+ with self.prefix(dst="llplugin"):
+ dylibexecutable = 'media_plugin_cef.dylib'
self.path2basename("../media_plugins/cef/" + self.args['configuration'],
- "media_plugin_cef.dylib")
+ dylibexecutable)
# copy LibVLC plugin itself
self.path2basename("../media_plugins/libvlc/" + self.args['configuration'],
"media_plugin_libvlc.dylib")
# copy LibVLC dynamic libraries
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release' ), dst="lib"):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'lib', 'release' ), dst="lib"):
self.path( "libvlc*.dylib*" )
# copy LibVLC plugins folder
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release', 'plugins' ), dst="lib"):
- self.path( "*.dylib" )
- self.path( "plugins.dat" )
-
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'lib', 'release', 'plugins' ), dst="lib"):
+ self.path("*.dylib")
+ self.path("plugins.dat")
# do this install_name_tool *after* media plugin is copied over
dylibexecutablepath = self.dst_path_of('llplugin/media_plugin_cef.dylib')
@@ -1641,13 +1589,12 @@ class DarwinManifest(ViewerManifest):
'"@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" '
'"@executable_path/../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" "%s"' % dylibexecutablepath)
-
# Copy in prebuilt framework if it's there
- with self.prefix(src="../packages/bin_x86/Frameworks", dst="Frameworks"):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'bin_x86', 'Frameworks'), dst="Frameworks"):
self.path("Chromium Embedded Framework.framework")
# CEF framework goes inside Second Life.app/Contents/Frameworks
- with self.prefix(src="", dst="Frameworks"):
+ with self.prefix(dst="Frameworks"):
frameworkfile="Chromium Embedded Framework.framework"
self.path2basename(relpkgdir, frameworkfile)
@@ -1876,10 +1823,7 @@ class DarwinManifest(ViewerManifest):
else:
print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
raise
- self.run_command(['spctl', '-a', '-texec', '-vv', app_in_dmg])
-
- imagename="SecondLife_" + '_'.join(self.args['version'])
-
+ self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
finally:
# Unmount the image even if exceptions from any of the above
@@ -1920,31 +1864,27 @@ class LinuxManifest(ViewerManifest):
self.path("licenses-linux.txt","licenses.txt")
self.path("VivoxAUP.txt")
self.path("res/firestorm_icon.png","firestorm_icon.png")
- with self.prefix("linux_tools", dst=""):
+ with self.prefix("linux_tools"):
self.path("client-readme.txt","README-linux.txt")
self.path("FIRESTORM_DESKTOPINSTALL.txt","FIRESTORM_DESKTOPINSTALL.txt")
self.path("client-readme-voice.txt","README-linux-voice.txt")
self.path("client-readme-joystick.txt","README-linux-joystick.txt")
self.path("wrapper.sh","firestorm")
- with self.prefix(src="", dst="etc"):
+ with self.prefix(dst="etc"):
self.path("handle_secondlifeprotocol.sh")
self.path("register_secondlifeprotocol.sh")
self.path("refresh_desktop_app_entry.sh")
self.path("launch_url.sh")
self.path("install.sh")
- with self.prefix(src="", dst="bin"):
+ with self.prefix(dst="bin"):
self.path("firestorm-bin","do-not-directly-run-firestorm-bin")
self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
self.path2basename("../llplugin/slplugin", "SLPlugin")
#this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
# Remove VMP
- #with self.prefix(src="../viewer_components/manager", dst=""):
- # self.path("SL_Launcher")
- # self.path("*.py")
- #with self.prefix(src=os.path.join("lib", "python", "llbase"), dst="llbase"):
- # self.path("*.py")
- # self.path("_cllsd.so")
+ # with self.prefix(src="../viewer_components/manager", dst=""):
+ # self.path("*.py")
# Remove VMP
# recurses, packaged again
@@ -1953,24 +1893,24 @@ class LinuxManifest(ViewerManifest):
# Get the icons based on the channel type
icon_path = self.icon_path()
print "DEBUG: icon_path '%s'" % icon_path
- with self.prefix(src=icon_path, dst="") :
+ with self.prefix(src=icon_path) :
self.path("firestorm_256.png","firestorm_48.png")
- with self.prefix(src="",dst="res-sdl") :
+ with self.prefix(dst="res-sdl") :
self.path("firestorm_256.BMP","ll_icon.BMP")
# plugins
- with self.prefix(src="../media_plugins", dst="bin/llplugin"):
+ with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins'), dst="bin/llplugin"):
self.path("gstreamer010/libmedia_plugin_gstreamer010.so",
"libmedia_plugin_gstreamer.so")
self.path2basename("libvlc", "libmedia_plugin_libvlc.so")
self.path("cef/libmedia_plugin_cef.so", "libmedia_plugin_cef.so" )
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
self.path( "plugins.dat" )
self.path( "*/*.so" )
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib' ), dst="lib"):
+ with self.prefix(src=os.path.join(pkgdir, 'lib' ), dst="lib"):
self.path( "libvlc*.so*" )
with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
@@ -1981,14 +1921,14 @@ class LinuxManifest(ViewerManifest):
self.path( "libvlc*.so*" )
# CEF files
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'), dst="lib"):
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path( "libcef.so" )
self.path( "libllceflib.so" )
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release', 'swiftshader'), dst=os.path.join("bin", "swiftshader") ):
+ with self.prefix(src=os.path.join(pkgdir, 'release', 'swiftshader'), dst=os.path.join("bin", "swiftshader") ):
self.path( "*.so" )
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="bin"):
+ with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="bin"):
self.path( "chrome-sandbox" )
self.path( "dullahan_host" )
self.path( "natives_blob.bin" )
@@ -1996,7 +1936,7 @@ class LinuxManifest(ViewerManifest):
self.path( "v8_context_snapshot.bin" )
self.path( "libffmpegsumo.so" )
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'resources'), dst="bin"):
+ with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="bin"):
self.path( "cef.pak" )
self.path( "cef_extensions.pak" )
self.path( "cef_100_percent.pak" )
@@ -2004,7 +1944,7 @@ class LinuxManifest(ViewerManifest):
self.path( "devtools_resources.pak" )
self.path( "icudtl.dat" )
- with self.prefix(src=os.path.join(os.pardir, 'packages', 'resources', 'locales'), dst=os.path.join('bin', 'locales')):
+ with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('bin', 'locales')):
self.path("am.pak")
self.path("ar.pak")
self.path("bg.pak")
@@ -2065,11 +2005,11 @@ class LinuxManifest(ViewerManifest):
self.path("featuretable_linux.txt")
- with self.prefix(src=pkgdir,dst="bin"):
+ with self.prefix(src=pkgdir, dst="bin"):
self.path("ca-bundle.crt")
if self.is_packaging_viewer():
- with self.prefix("../packages/lib/release", dst="lib"):
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libapr-1.so*")
self.path("libaprutil-1.so*")
self.path("libboost_context-mt.so*")
@@ -2129,13 +2069,18 @@ class LinuxManifest(ViewerManifest):
print "tcmalloc files not found, skipping"
pass
+ try:
+ self.path("libjemalloc.so*")
+ except:
+ pass
+
# Vivox runtimes
# Currentelly, the 32-bit ones will work with a 64-bit client.
- with self.prefix(src="../packages/lib/release", dst="bin"):
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="bin"):
self.path("SLVoice")
self.path("win32")
- with self.prefix(src="../packages/lib/release", dst="lib"):
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libortp.so")
self.path("libsndfile.so.1")
# Vivox wants this library even if it's present already in the viewer
@@ -2191,7 +2136,7 @@ class LinuxManifest(ViewerManifest):
["find"] +
[os.path.join(self.get_dst_prefix(), dir) for dir in ('bin', 'lib')] +
# Remove VMP
- #['-type', 'f', '!', '-name', '*.py', '!', '-name', 'SL_Launcher',
+ # ['-type', 'f', '!', '-name', '*.py',
['-type', 'f', "!", "-name", "*.dat", "!", "-name", "*.pak", "!", "-name", "*.bin",
# Remove VMP
'!', '-name', 'update_install', '-exec', 'strip', '-S', '{}', ';'])
@@ -2206,7 +2151,7 @@ class Linux_i686_Manifest(LinuxManifest):
relpkgdir = os.path.join(pkgdir, "lib", "release")
debpkgdir = os.path.join(pkgdir, "lib", "debug")
- with self.prefix(relpkgdir, dst="lib"):
+ with self.prefix(src=relpkgdir, dst="lib"):
self.path("libapr-1.so")
self.path("libapr-1.so.0")
self.path("libapr-1.so.0.4.5")
@@ -2301,8 +2246,12 @@ class Linux_x86_64_Manifest(LinuxManifest):
def construct(self):
super(Linux_x86_64_Manifest, self).construct()
+ pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
+ relpkgdir = os.path.join(pkgdir, "lib", "release")
+ debpkgdir = os.path.join(pkgdir, "lib", "debug")
+
if self.is_packaging_viewer():
- with self.prefix("../packages/lib/release", dst="lib"):
+ with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libffi*.so*")
# vivox 32-bit hack.
# one has to extract libopenal.so from the 32-bit openal package, or official LL viewer, and rename it to libopenal32.so
@@ -2328,18 +2277,18 @@ class Linux_x86_64_Manifest(LinuxManifest):
print "Skipping libfmod.so - not found"
pass
- self.prefix(src="../packages/lib/release/x64", dst="lib")
+ self.prefix(src=os.path.join(pkgdir, 'lib', 'release', 'x64'), dst="lib")
try:
self.path("libLeap.so")
except:
print "Leap Motion library not found"
self.end_prefix("lib")
- with self.prefix(src="", dst="bin"):
+ with self.prefix(dst="bin"):
self.path2basename("../llplugin/slplugin", "SLPlugin")
# plugins
- with self.prefix(src="", dst="bin/llplugin"):
+ with self.prefix(dst="bin/llplugin"):
self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so")
self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")
@@ -2390,4 +2339,8 @@ def symlinkf(src, dst):
# Added back for Mac compatibility reason
if __name__ == "__main__":
- main()
+ extra_arguments = [
+ dict(name='bugsplat', description="""BugSplat database to which to post crashes,
+ if BugSplat crash reporting is desired""", default=''),
+ ]
+ main(extra=extra_arguments)
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 87764df220..ba75d4ef3d 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -75,9 +75,6 @@ if (NOT WINDOWS)
list(APPEND test_SOURCE_FILES
llmessagetemplateparser_tut.cpp
)
- set(EXTRA_WINDOWS_LIBRARIES "")
-else (NOT WINDOWS)
- set(EXTRA_WINDOWS_LIBRARIES ole32)
endif (NOT WINDOWS)
set_source_files_properties(${test_HEADER_FILES}
@@ -101,7 +98,6 @@ target_link_libraries(lltest
${GOOGLEMOCK_LIBRARIES}
${PTHREAD_LIBRARY}
${WINDOWS_LIBRARIES}
- ${EXTRA_WINDOWS_LIBRARIES}
${BOOST_PROGRAM_OPTIONS_LIBRARY}
${BOOST_REGEX_LIBRARY}
${BOOST_COROUTINE_LIBRARY}
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index ed21b046fb..d9d366c14b 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -547,7 +547,6 @@ int main(int argc, char **argv)
LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
}
LLError::setFatalFunction(wouldHaveCrashed);
- LLError::setPrintLocation(true);
std::string test_app_name(argv[0]);
std::string test_log = test_app_name + ".log";
LLFile::remove(test_log);
diff --git a/indra/viewer_components/login/lllogin.cpp b/indra/viewer_components/login/lllogin.cpp
index c767d52c7b..e3390f33c6 100644
--- a/indra/viewer_components/login/lllogin.cpp
+++ b/indra/viewer_components/login/lllogin.cpp
@@ -128,6 +128,15 @@ void LLLogin::Impl::connect(const std::string& uri, const LLSD& login_params)
LL_DEBUGS("LLLogin") << " connected with uri '" << uri << "', login_params " << login_params << LL_ENDL;
}
+namespace {
+// Instantiate this rendezvous point at namespace scope so it's already
+// present no matter how early the updater might post to it.
+// Use an LLEventMailDrop, which has future-like semantics: regardless of the
+// relative order in which post() or listen() are called, it delivers each
+// post() event to its listener(s) until one of them consumes that event.
+static LLEventMailDrop sSyncPoint("LoginSync");
+}
+
void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
{
LLSD printable_params = login_params;
@@ -219,7 +228,47 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
}
else
{
+ // Synchronize here with the updater. We synchronize here rather
+ // than in the fail.login handler, which actually examines the
+ // response from login.cgi, because here we are definitely in a
+ // coroutine and can definitely use suspendUntilBlah(). Whoever's
+ // listening for fail.login might not be.
+
+ // If the reason for login failure is that we must install a
+ // required update, we definitely want to pass control to the
+ // updater to manage that for us. We'll handle any other login
+ // failure ourselves, as usual. We figure that no matter where you
+ // are in the world, or what kind of network you're on, we can
+ // reasonably expect the Viewer Version Manager to respond more or
+ // less as quickly as login.cgi. This synchronization is only
+ // intended to smooth out minor races between the two services.
+ // But what if the updater crashes? Use a timeout so that
+ // eventually we'll tire of waiting for it and carry on as usual.
+ // Given the above, it can be a fairly short timeout, at least
+ // from a human point of view.
+
+ // Since sSyncPoint is an LLEventMailDrop, we DEFINITELY want to
+ // consume the posted event.
+ // Disable updater
+ //LLCoros::OverrideConsuming oc(true);
+ //// Timeout should produce the isUndefined() object passed here.
+ //LL_DEBUGS("LLLogin") << "Login failure, waiting for sync from updater" << LL_ENDL;
+ //LLSD updater = llcoro::suspendUntilEventOnWithTimeout(sSyncPoint, 10, LLSD());
+ //if (updater.isUndefined())
+ //{
+ // LL_WARNS("LLLogin") << "Failed to hear from updater, proceeding with fail.login"
+ // << LL_ENDL;
+ //}
+ //else
+ //{
+ // LL_DEBUGS("LLLogin") << "Got responses from updater and login.cgi" << LL_ENDL;
+ //}
+ //// Let the fail.login handler deal with empty updater response.
+ //LLSD responses(mAuthResponse["responses"]);
+ //responses["updater"] = updater;
+ //sendProgressEvent("offline", "fail.login", responses);
sendProgressEvent("offline", "fail.login", mAuthResponse["responses"]);
+ //
}
return; // Done!
}
@@ -249,10 +298,10 @@ void LLLogin::Impl::loginCoro(std::string uri, LLSD login_params)
// *NOTE: The response from LLXMLRPCListener's Poller::poll method returns an
// llsd with no "responses" node. To make the output from an incomplete login symmetrical
// to success, add a data/message and data/reason fields.
- LLSD error_response;
- error_response["reason"] = mAuthResponse["status"];
- error_response["errorcode"] = mAuthResponse["errorcode"];
- error_response["message"] = mAuthResponse["error"];
+ LLSD error_response(LLSDMap
+ ("reason", mAuthResponse["status"])
+ ("errorcode", mAuthResponse["errorcode"])
+ ("message", mAuthResponse["error"]));
if(mAuthResponse.has("certificate"))
{
error_response["certificate"] = mAuthResponse["certificate"];
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 151421567d..21dd2a0734 100644
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -95,7 +95,6 @@ target_link_libraries(windows-crash-logger
${GOOGLE_PERFTOOLS_LIBRARIES}
user32
gdi32
- ole32
oleaut32
wininet
Wldap32
diff --git a/scripts/configure_firestorm.sh b/scripts/configure_firestorm.sh
index 3cf6041aa1..734d17e60e 100755
--- a/scripts/configure_firestorm.sh
+++ b/scripts/configure_firestorm.sh
@@ -12,9 +12,8 @@ FALSE=1
# args ../indra
# -DCMAKE_BUILD_TYPE:STRING=Release
-# -DWORD_SIZE:STRING=32
+# -DADDRESS_SIZE:STRING=32
# -DROOT_PROJECT_NAME:STRING=SecondLife
-# -DINSTALL_PROPRIETARY=FALSE
# -DUSE_KDU=TRUE
# -DFMODSTUDIO:BOOL=ON
# -DFMODEX:BOOL=ON
@@ -37,17 +36,20 @@ WANTS_KDU=$FALSE
WANTS_FMODSTUDIO=$FALSE
WANTS_FMODEX=$FALSE
WANTS_OPENSIM=$TRUE
+WANTS_SINGLEGRID=$FALSE
WANTS_AVX=$FALSE
WANTS_AVX2=$FALSE
WANTS_TESTBUILD=$FALSE
WANTS_BUILD=$FALSE
-PLATFORM="darwin" # darwin, win32, win64, linux32, linux64
+WANTS_CRASHREPORTING=$FALSE
+PLATFORM="darwin" # darwin, windows, linux
BTYPE="Release"
CHANNEL="" # will be overwritten later with platform-specific values unless manually specified.
LL_ARGS_PASSTHRU=""
JOBS="0"
WANTS_NINJA=$FALSE
TESTBUILD_PERIOD="0"
+SINGLEGRID_URI=""
###
### Helper Functions
@@ -59,26 +61,28 @@ showUsage()
echo "Usage: "
echo "========================"
echo
- echo " --clean : Remove past builds & configuration"
- echo " --config : General a new architecture-specific config"
- echo " --build : build firestorm"
- echo " --version : Update version number"
+ echo " --clean : Remove past builds & configuration"
+ echo " --config : Generate a new architecture-specific config"
+ echo " --build : Build Firestorm"
+ echo " --version : Update version number"
echo " --chan [Release|Beta|Private] : Private is the default, sets channel"
echo " --btype [Release|RelWithDebInfo] : Release is default, whether to use symbols"
- echo " --kdu : Build with KDU"
- echo " --package : Build installer"
- echo " --no-package : Build without installer (Overrides --package)"
- echo " --fmodstudio : Build with FMOD Studio"
- echo " --fmodex : Build with FMOD Ex"
- echo " --opensim : Build with OpenSim support (Disables Havok features)"
- echo " --no-opensim : Build without OpenSim support (Overrides --opensim)"
- echo " --avx : Build with Advanced Vector Extensions"
- echo " --avx2 : Build with Advanced Vector Extensions 2"
- echo " --testbuild : Create time-limited test build"
- echo " --platform : darwin | win32 | win64 | linux32 | linux64"
- echo " --jobs : Build with jobs in parallel (Linux and Darwin only)"
+ echo " --kdu : Build with KDU"
+ echo " --package : Build installer"
+ echo " --no-package : Build without installer (Overrides --package)"
+ echo " --fmodstudio : Build with FMOD Studio"
+ echo " --fmodex : Build with FMOD Ex"
+ echo " --opensim : Build with OpenSim support (Disables Havok features)"
+ echo " --no-opensim : Build without OpenSim support (Overrides --opensim)"
+ echo " --singlegrid : Build for single grid usage (Requires --opensim)"
+ echo " --avx : Build with Advanced Vector Extensions"
+ echo " --avx2 : Build with Advanced Vector Extensions 2"
+ echo " --crashreporting : Build with crash reporting enabled"
+ echo " --testbuild : Create time-limited test build (build date + )"
+ echo " --platform : Build for specified platform (darwin | windows | linux)"
+ echo " --jobs : Build with jobs in parallel (Linux and Darwin only)"
echo
- echo "All arguments not in the above list will be passed through to LL's configure/build"
+ echo "All arguments not in the above list will be passed through to LL's configure/build."
echo
}
@@ -86,43 +90,48 @@ getArgs()
# $* = the options passed in from main
{
if [ $# -gt 0 ]; then
- while getoptex "clean build config version package no-package fmodstudio fmodex ninja jobs: platform: kdu opensim no-opensim avx avx2 testbuild: help chan: btype:" "$@" ; do
+ while getoptex "clean build config version package no-package fmodstudio fmodex ninja jobs: platform: kdu opensim no-opensim singlegrid: avx avx2 crashreporting testbuild: help chan: btype:" "$@" ; do
- #insure options are valid
+ #ensure options are valid
if [ -z "$OPTOPT" ] ; then
showUsage
exit 1
fi
case "$OPTOPT" in
- clean) WANTS_CLEAN=$TRUE;;
- config) WANTS_CONFIG=$TRUE;;
- version) WANTS_VERSION=$TRUE;;
- chan) CHANNEL="$OPTARG";;
- btype) if [ \( "$OPTARG" == "Release" \) -o \( "$OPTARG" == "RelWithDebInfo" \) -o \( "$OPTARG" == "Debug" \) ] ; then
- BTYPE="$OPTARG"
- fi
- ;;
- kdu) WANTS_KDU=$TRUE;;
- fmodstudio) WANTS_FMODSTUDIO=$TRUE;;
- fmodex) WANTS_FMODEX=$TRUE;;
- opensim) WANTS_OPENSIM=$TRUE;;
- no-opensim) WANTS_OPENSIM=$FALSE;;
- avx) WANTS_AVX=$TRUE;;
- avx2) WANTS_AVX2=$TRUE;;
- testbuild) WANTS_TESTBUILD=$TRUE
- TESTBUILD_PERIOD="$OPTARG";;
- package) WANTS_PACKAGE=$TRUE;;
- no-package) WANTS_PACKAGE=$FALSE;;
- build) WANTS_BUILD=$TRUE;;
- platform) PLATFORM="$OPTARG";;
- jobs) JOBS="$OPTARG";;
- ninja) WANTS_NINJA=$TRUE;;
+ clean) WANTS_CLEAN=$TRUE;;
+ config) WANTS_CONFIG=$TRUE;;
+ version) WANTS_VERSION=$TRUE;;
+ chan) CHANNEL="$OPTARG";;
+ btype) if [ \( "$OPTARG" == "Release" \) -o \( "$OPTARG" == "RelWithDebInfo" \) -o \( "$OPTARG" == "Debug" \) ] ; then
+ BTYPE="$OPTARG"
+ fi
+ ;;
+ kdu) WANTS_KDU=$TRUE;;
+ fmodstudio) WANTS_FMODSTUDIO=$TRUE;;
+ fmodex) WANTS_FMODEX=$TRUE;;
+ opensim) WANTS_OPENSIM=$TRUE;;
+ no-opensim) WANTS_OPENSIM=$FALSE;;
+ singlegrid) WANTS_SINGLEGRID=$TRUE
+ SINGLEGRID_URI="$OPTARG"
+ ;;
+ avx) WANTS_AVX=$TRUE;;
+ avx2) WANTS_AVX2=$TRUE;;
+ crashreporting) WANTS_CRASHREPORTING=$TRUE;;
+ testbuild) WANTS_TESTBUILD=$TRUE
+ TESTBUILD_PERIOD="$OPTARG"
+ ;;
+ package) WANTS_PACKAGE=$TRUE;;
+ no-package) WANTS_PACKAGE=$FALSE;;
+ build) WANTS_BUILD=$TRUE;;
+ platform) PLATFORM="$OPTARG";;
+ jobs) JOBS="$OPTARG";;
+ ninja) WANTS_NINJA=$TRUE;;
- help) showUsage && exit 0;;
+ help) showUsage && exit 0;;
- -*) showUsage && exit 1;;
- *) showUsage && exit 1;;
+ -*) showUsage && exit 1;;
+ *) showUsage && exit 1;;
esac
done
@@ -131,14 +140,15 @@ getArgs()
showUsage && exit 1
fi
fi
- if [ $WANTS_CLEAN -ne $TRUE ] && [ $WANTS_CONFIG -ne $TRUE ] && \
- [ $WANTS_VERSION -ne $TRUE ] && [ $WANTS_BUILD -ne $TRUE ] && \
- [ $WANTS_PACKAGE -ne $TRUE ] ; then
+
+ if [ $WANTS_CLEAN -ne $TRUE ] && [ $WANTS_CONFIG -ne $TRUE ] && \
+ [ $WANTS_VERSION -ne $TRUE ] && [ $WANTS_BUILD -ne $TRUE ] && \
+ [ $WANTS_PACKAGE -ne $TRUE ] ; then
# the user didn't say what to do, so assume he wants to do a basic rebuild
- WANTS_CONFIG=$TRUE
- WANTS_BUILD=$TRUE
- WANTS_VERSION=$TRUE
- fi
+ WANTS_CONFIG=$TRUE
+ WANTS_BUILD=$TRUE
+ WANTS_VERSION=$TRUE
+ fi
LOG="`pwd`/logs/build_$PLATFORM.log"
if [ -r "$LOG" ] ; then
@@ -282,44 +292,54 @@ if [ ! -d `dirname "$LOG"` ] ; then
mkdir -p `dirname "$LOG"`
fi
-echo -e "configure_firestorm.py" > $LOG
-echo -e " PLATFORM: '$PLATFORM'" | tee -a $LOG
-echo -e " KDU: `b2a $WANTS_KDU`" | tee -a $LOG
-echo -e " FMODSTUDIO: `b2a $WANTS_FMODSTUDIO`" | tee -a $LOG
-echo -e " FMODEX: `b2a $WANTS_FMODEX`" | tee -a $LOG
-echo -e " OPENSIM: `b2a $WANTS_OPENSIM`" | tee -a $LOG
-echo -e " AVX: `b2a $WANTS_AVX`" | tee -a $LOG
-echo -e " AVX2: `b2a $WANTS_AVX2`" | tee -a $LOG
-echo -e " TESTBUILD: `b2a $WANTS_TESTBUILD`" | tee -a $LOG
-echo -e " PACKAGE: `b2a $WANTS_PACKAGE`" | tee -a $LOG
-echo -e " CLEAN: `b2a $WANTS_CLEAN`" | tee -a $LOG
-echo -e " BUILD: `b2a $WANTS_BUILD`" | tee -a $LOG
-echo -e " CONFIG: `b2a $WANTS_CONFIG`" | tee -a $LOG
-echo -e " NINJA: `b2a $WANTS_NINJA`" | tee -a $LOG
-echo -e " PASSTHRU: $LL_ARGS_PASSTHRU" | tee -a $LOG
-echo -e " BTYPE: $BTYPE" | tee -a $LOG
-if [ $PLATFORM == "linux32" -o $PLATFORM == "linux64" -o $PLATFORM == "darwin" ] ; then
- echo -e " JOBS: $JOBS" | tee -a $LOG
+echo -e "configure_firestorm.sh" > $LOG
+echo -e " PLATFORM: '$PLATFORM'" | tee -a $LOG
+echo -e " KDU: `b2a $WANTS_KDU`" | tee -a $LOG
+echo -e " FMODSTUDIO: `b2a $WANTS_FMODSTUDIO`" | tee -a $LOG
+echo -e " FMODEX: `b2a $WANTS_FMODEX`" | tee -a $LOG
+echo -e " OPENSIM: `b2a $WANTS_OPENSIM`" | tee -a $LOG
+if [ $WANTS_SINGLEGRID -eq $TRUE ] ; then
+ echo -e " SINGLEGRID: `b2a $WANTS_SINGLEGRID` ($SINGLEGRID_URI)" | tee -a $LOG
+else
+ echo -e " SINGLEGRID: `b2a $WANTS_SINGLEGRID`" | tee -a $LOG
+fi
+echo -e " AVX: `b2a $WANTS_AVX`" | tee -a $LOG
+echo -e " AVX2: `b2a $WANTS_AVX2`" | tee -a $LOG
+echo -e " CRASHREPORTING: `b2a $WANTS_CRASHREPORTING`" | tee -a $LOG
+if [ $WANTS_TESTBUILD -eq $TRUE ] ; then
+ echo -e " TESTBUILD: `b2a $WANTS_TESTBUILD` ($TESTBUILD_PERIOD days)" | tee -a $LOG
+else
+ echo -e " TESTBUILD: `b2a $WANTS_TESTBUILD`" | tee -a $LOG
+fi
+echo -e " PACKAGE: `b2a $WANTS_PACKAGE`" | tee -a $LOG
+echo -e " CLEAN: `b2a $WANTS_CLEAN`" | tee -a $LOG
+echo -e " BUILD: `b2a $WANTS_BUILD`" | tee -a $LOG
+echo -e " CONFIG: `b2a $WANTS_CONFIG`" | tee -a $LOG
+echo -e " NINJA: `b2a $WANTS_NINJA`" | tee -a $LOG
+echo -e " PASSTHRU: $LL_ARGS_PASSTHRU" | tee -a $LOG
+echo -e " BTYPE: $BTYPE" | tee -a $LOG
+if [ $PLATFORM == "linux" -o $PLATFORM == "darwin" ] ; then
+ echo -e " JOBS: $JOBS" | tee -a $LOG
fi
echo -e " Logging to $LOG"
-if [ $PLATFORM == "win32" ]
+if [ $PLATFORM == "windows" ]
then
if [ -z "${AUTOBUILD_VSVER}" ]
then
- echo "AUTOBUILD_VSVER not set, this can lead to autobuild picking a higher VS version than desired."
- echo "If you see this happen you should set the variable to eg 120 for Visual Studio 2013"
+ echo "AUTOBUILD_VSVER not set, this can lead to Autobuild picking a higher VS version than desired."
+ echo "If you see this happen you should set the variable to e.g. 120 for Visual Studio 2013."
fi
fi
if [ -z "$AUTOBUILD_VARIABLES_FILE" ]
then
echo "AUTOBUILD_VARIABLES_FILE not set."
- echo "In order to run autobuild it needs to be set to point to a correct variables file"
+ echo "In order to run autobuild it needs to be set to point to a correct variables file."
exit 1
fi
-if [ $PLATFORM == "win32" ] ; then
+if [ $PLATFORM == "windows" ] ; then
FIND=/usr/bin/find
else
FIND=find
@@ -352,10 +372,9 @@ if [ \( $WANTS_CLEAN -eq $TRUE \) -a \( $WANTS_BUILD -eq $FALSE \) ] ; then
mkdir -p build-darwin-i386/logs
fi
- elif [ $PLATFORM == "win32" ] ; then
+ elif [ $PLATFORM == "windows" ] ; then
rm -rf build-vc120-${AUTOBUILD_ADDRSIZE}
mkdir -p build-vc120-${AUTOBUILD_ADDRSIZE}/logs
-
elif [ $PLATFORM == "linux32" ] ; then
if [ "${AUTOBUILD_ADDRSIZE}" == "64" ]
@@ -383,7 +402,6 @@ if [ \( $WANTS_VERSION -eq $TRUE \) -o \( $WANTS_CONFIG -eq $TRUE \) ] ; then
popd
fi
-
if [ $WANTS_CONFIG -eq $TRUE ] ; then
echo "Configuring $PLATFORM..."
@@ -402,12 +420,16 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then
else
FMODEX="-DFMODEX:BOOL=OFF"
fi
-
if [ $WANTS_OPENSIM -eq $TRUE ] ; then
OPENSIM="-DOPENSIM:BOOL=ON"
else
OPENSIM="-DOPENSIM:BOOL=OFF"
fi
+ if [ $WANTS_SINGLEGRID -eq $TRUE ] ; then
+ SINGLEGRID="-DSINGLEGRID:BOOL=ON -DSINGLEGRID_URI:STRING=$SINGLEGRID_URI"
+ else
+ SINGLEGRID="-DSINGLEGRID:BOOL=OFF"
+ fi
if [ $WANTS_AVX -eq $TRUE ] ; then
AVX_OPTIMIZATION="-DUSE_AVX_OPTIMIZATION:BOOL=ON"
else
@@ -437,6 +459,23 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then
else
PACKAGE="-DPACKAGE:BOOL=OFF"
fi
+ if [ $WANTS_CRASHREPORTING -eq $TRUE ] ; then
+ if [ $PLATFORM == "windows" ] ; then
+ BUILD_DIR=`cygpath -w $(pwd)`
+ else
+ BUILD_DIR=`pwd`
+ fi
+ # This name is consumed by indra/newview/CMakeLists.txt
+ if [ $PLATFORM == "linux" ] ; then
+ VIEWER_SYMBOL_FILE="${BUILD_DIR}/newview/firestorm-symbols-${PLATFORM}-${AUTOBUILD_ADDRSIZE}.tar.bz2"
+ else
+ VIEWER_SYMBOL_FILE="${BUILD_DIR}/newview/$BTYPE/firestorm-symbols-${PLATFORM}-${AUTOBUILD_ADDRSIZE}.tar.bz2"
+ fi
+ CRASH_REPORTING="-DRELEASE_CRASH_REPORTING:BOOL=ON"
+ else
+ CRASH_REPORTING="-DRELEASE_CRASH_REPORTING:BOOL=OFF"
+ fi
+
CHANNEL="-DVIEWER_CHANNEL:STRING=$CHANNEL"
#make sure log directory exists.
@@ -447,24 +486,23 @@ if [ $WANTS_CONFIG -eq $TRUE ] ; then
if [ $PLATFORM == "darwin" ] ; then
TARGET="Xcode"
- elif [ \( $PLATFORM == "linux32" \) -o \( $PLATFORM == "linux64" \) ] ; then
+ elif [ \( $PLATFORM == "linux" \) ] ; then
if [ $WANTS_NINJA -eq $TRUE ] ; then
TARGET="Ninja"
else
TARGET="Unix Makefiles"
fi
- elif [ \( $PLATFORM == "win32" \) ] ; then
+ elif [ \( $PLATFORM == "windows" \) ] ; then
TARGET="${AUTOBUILD_WIN_CMAKE_GEN}"
UNATTENDED="-DUNATTENDED=ON"
fi
- cmake -G "$TARGET" ../indra $CHANNEL $FMODSTUDIO $FMODEX $KDU $OPENSIM $AVX_OPTIMIZATION $AVX2_OPTIMIZATION $TESTBUILD $PACKAGE $UNATTENDED -DLL_TESTS:BOOL=OFF -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DCMAKE_BUILD_TYPE:STRING=$BTYPE \
- -DROOT_PROJECT_NAME:STRING=Firestorm $LL_ARGS_PASSTHRU | tee $LOG
+ cmake -G "$TARGET" ../indra $CHANNEL $FMODSTUDIO $FMODEX $KDU $OPENSIM $SINGLEGRID $AVX_OPTIMIZATION $AVX2_OPTIMIZATION $TESTBUILD $PACKAGE $UNATTENDED -DLL_TESTS:BOOL=OFF -DADDRESS_SIZE:STRING=$AUTOBUILD_ADDRSIZE -DCMAKE_BUILD_TYPE:STRING=$BTYPE \
+ $CRASH_REPORTING -DVIEWER_SYMBOL_FILE:STRING="${VIEWER_SYMBOL_FILE:-}" -DROOT_PROJECT_NAME:STRING=Firestorm $LL_ARGS_PASSTHRU | tee $LOG
- if [ $PLATFORM == "win32" ] ; then
+ if [ $PLATFORM == "windows" ] ; then
../indra/tools/vstool/VSTool.exe --solution Firestorm.sln --startup firestorm-bin --workingdir firestorm-bin "..\\..\\indra\\newview" --config $BTYPE
fi
-
fi
if [ $WANTS_BUILD -eq $TRUE ] ; then
@@ -476,7 +514,7 @@ if [ $WANTS_BUILD -eq $TRUE ] ; then
JOBS="-jobs $JOBS"
fi
xcodebuild -configuration $BTYPE -project Firestorm.xcodeproj $JOBS 2>&1 | tee -a $LOG
- elif [ $PLATFORM == "linux32" -o $PLATFORM == "linux64" ] ; then
+ elif [ $PLATFORM == "linux" ] ; then
if [ $JOBS == "0" ] ; then
JOBS=`cat /proc/cpuinfo | grep processor | wc -l`
fi
@@ -485,16 +523,10 @@ if [ $WANTS_BUILD -eq $TRUE ] ; then
else
make -j $JOBS | tee -a $LOG
fi
- elif [ $PLATFORM == "win32" ] ; then
- SLN_PLATFORM="Win32"
- if [ "${AUTOBUILD_ADDRSIZE}" == "64" ]
- then
- SLN_PLATFORM="x64"
- fi
-
- msbuild.exe Firestorm.sln /flp:LogFile=logs\\FirestormBuild_win32.log /flp1:errorsonly;LogFile=logs\\FirestormBuild_win32.err \
- /flp:LogFile=logs\\FirestormBuild_win32.log /p:Configuration=$BTYPE /p:Platform=${SLN_PLATFORM} /t:Build /p:useenv=true \
- /verbosity:normal /toolsversion:4.0 /p:"VCBuildAdditionalOptions= /incremental"
+ elif [ $PLATFORM == "windows" ] ; then
+ msbuild.exe Firestorm.sln /p:Configuration=${BTYPE} /flp:LogFile="logs\\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log" \
+ /flp1:"errorsonly;LogFile=logs\\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err" /p:Platform=${AUTOBUILD_WIN_VSPLATFORM} /t:Build /p:useenv=true \
+ /verbosity:normal /toolsversion:12.0 /p:"VCBuildAdditionalOptions= /incremental"
fi
fi