Merge Firestorm LGPL
commit
fff9fdf9ba
3
.hgtags
3
.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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
479
autobuild.xml
479
autobuild.xml
|
|
@ -3,6 +3,36 @@
|
|||
<map>
|
||||
<key>installables</key>
|
||||
<map>
|
||||
<key>jemalloc</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (C) 2002-present Jason Evans jasone@canonware.com.</string>
|
||||
<key>description</key>
|
||||
<string>jemalloc is a general purpose malloc(3) implementation that emphasizes fragmentation avoidance and scalable concurrency support.</string>
|
||||
<key>license</key>
|
||||
<string>jemalloc (BSD derived)</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/jemalloc.txt</string>
|
||||
<key>name</key>
|
||||
<string>jemalloc</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>aa31ee4c6315cb26bf6e2191b69598f5</string>
|
||||
<key>url</key>
|
||||
<string>http://downloads.phoenixviewer.com/jemalloc-5.1.0-linux64-190582149.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>5.1.0</string>
|
||||
</map>
|
||||
<key>dullahan-gcc5</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -429,18 +459,18 @@
|
|||
<key>version</key>
|
||||
<string>1.57</string>
|
||||
</map>
|
||||
<key>chardet</key>
|
||||
<key>bugsplat</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Contributors to charset (see https://github.com/chardet/chardet)</string>
|
||||
<string>Copyright 2003-2017, BugSplat</string>
|
||||
<key>description</key>
|
||||
<string>Python Character Encoding Library</string>
|
||||
<string>Bugsplat crash reporting package</string>
|
||||
<key>license</key>
|
||||
<string>LGPL</string>
|
||||
<string>Proprietary</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/chardet.txt</string>
|
||||
<string>LICENSES/BUGSPLAT_LICENSE.txt</string>
|
||||
<key>name</key>
|
||||
<string>chardet</string>
|
||||
<string>bugsplat</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
|
|
@ -448,16 +478,40 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>0124862b6a1b88455c78a68f8b823d21</string>
|
||||
<string>c3b5e8c57bd1c92bc9e0956586908b99</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6662/23578/chardet-3.0.4-darwin64-506651.tar.bz2</string>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26330/207568/bugsplat-1.0.7.520791-darwin64-520791.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>766dfde65a5b42ea5691d41df79c43e0</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26332/207582/bugsplat-3.6.0.4.520791-windows-520791.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
<key>windows64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>afd01285e22f27d473fac6f88fac9a3b</string>
|
||||
<key>url</key>
|
||||
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/26331/207576/bugsplat-3.6.0.4.520791-windows64-520791.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>3.0.4</string>
|
||||
<string>1.0.7.520791</string>
|
||||
</map>
|
||||
<key>colladadom</key>
|
||||
<map>
|
||||
|
|
@ -1747,36 +1801,6 @@
|
|||
<key>version</key>
|
||||
<string>2012.1-2</string>
|
||||
</map>
|
||||
<key>idna</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2013-2017, Kim Davies. All rights reserved.</string>
|
||||
<key>description</key>
|
||||
<string>Python Internationalized Domain Names in Applications (IDNA) Library</string>
|
||||
<key>license</key>
|
||||
<string>see idna.rst</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/idna.rst</string>
|
||||
<key>name</key>
|
||||
<string>idna</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>7dfe9fc4023d7d4f511dd9fac7258266</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6663/23584/idna-2.5-darwin64-506652.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>2.5</string>
|
||||
</map>
|
||||
<key>jpeglib</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -2455,46 +2479,6 @@
|
|||
<key>version</key>
|
||||
<string>0.0.1</string>
|
||||
</map>
|
||||
<key>llbase</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright (c) 2010, Linden Research, Inc.</string>
|
||||
<key>license</key>
|
||||
<string>mit</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/llbase-license.txt</string>
|
||||
<key>name</key>
|
||||
<string>llbase</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e18eeb0691af053b83bd46b76c6ee86a</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6299/21982/llbase-0.9.3.506286-darwin64-506286.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>e6865670f9bca1c82fb8b91db3ea515c</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6301/21994/llbase-0.9.3.506286-windows-506286.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>0.9.3.506286</string>
|
||||
</map>
|
||||
<key>llca</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -3261,52 +3245,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>version</key>
|
||||
<string>8.35.500898</string>
|
||||
</map>
|
||||
<key>requests</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright 2016 Kenneth Reitz</string>
|
||||
<key>description</key>
|
||||
<string>Python HTTP Library</string>
|
||||
<key>license</key>
|
||||
<string>Apache</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/requests.txt</string>
|
||||
<key>name</key>
|
||||
<string>requests</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>b8d134a970261b445a3f376ba4e05ff7</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6693/23788/requests-2.18.1-darwin64-506681.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
<key>linux64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>9fe44ba82ee05363fdfa4c1b9f2ec360</string>
|
||||
<key>url</key>
|
||||
<string>http://downloads.phoenixviewer.com/requests-2.18.1-linux64-180841555.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>source</key>
|
||||
<string>https://bitbucket.org/lindenlab/p64_python-requests</string>
|
||||
<key>source_type</key>
|
||||
<string>hg</string>
|
||||
<key>version</key>
|
||||
<string>2.18.1</string>
|
||||
</map>
|
||||
<key>slvoice</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -3517,36 +3455,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>version</key>
|
||||
<string>0.8.0.1</string>
|
||||
</map>
|
||||
<key>urllib3</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
<string>Copyright 2008-2016 Andrey Petrov and contributors (see CONTRIBUTORS.txt)</string>
|
||||
<key>description</key>
|
||||
<string>Python HTTP Library</string>
|
||||
<key>license</key>
|
||||
<string>MIT</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSES/urllib3.txt</string>
|
||||
<key>name</key>
|
||||
<string>urllib3</string>
|
||||
<key>platforms</key>
|
||||
<map>
|
||||
<key>darwin64</key>
|
||||
<map>
|
||||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>22f64c7fbb6704d2e9519fd1cca8e49b</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/6659/23560/urllib3-1.21.1-darwin64-506648.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
</map>
|
||||
</map>
|
||||
<key>version</key>
|
||||
<string>1.21.1</string>
|
||||
</map>
|
||||
<key>viewer-manager</key>
|
||||
<map>
|
||||
<key>copyright</key>
|
||||
|
|
@ -3554,7 +3462,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>description</key>
|
||||
<string>Linden Lab Viewer Management Process suite.</string>
|
||||
<key>license</key>
|
||||
<string>Proprietary</string>
|
||||
<string>viewerlgpl</string>
|
||||
<key>license_file</key>
|
||||
<string>LICENSE</string>
|
||||
<key>name</key>
|
||||
|
|
@ -3566,9 +3474,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>ce95944fb842849108102263a25fc794</string>
|
||||
<string>aaf04f5ed1d28477781d976dc04871ee</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/23237/178332/viewer_manager-1.0.518840-darwin64-518840.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31904/266163/viewer_manager-2.0.524157-darwin64-524157.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin64</string>
|
||||
|
|
@ -3602,9 +3510,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>642f847a9ac45551af65a55826974334</string>
|
||||
<string>4604624f11b215b052f4a840f4da4bf8</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/23236/178338/viewer_manager-1.0.518840-windows-518840.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/31906/266177/viewer_manager-2.0.524157-windows-524157.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
@ -3615,7 +3523,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>source_type</key>
|
||||
<string>hg</string>
|
||||
<key>version</key>
|
||||
<string>1.0.518840</string>
|
||||
<string>2.0.524157</string>
|
||||
</map>
|
||||
<key>vlc-bin</key>
|
||||
<map>
|
||||
|
|
@ -3663,7 +3571,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<string>http://downloads.phoenixviewer.com/vlc_bin-2.2.3-linux-x64-201610182130-r16.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
<string>linux64</string>
|
||||
</map>
|
||||
<key>windows</key>
|
||||
<map>
|
||||
|
|
@ -4001,6 +3909,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>ReleaseFS</key>
|
||||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>bash</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<string>--build</string>
|
||||
<string>--version</string>
|
||||
<string>--opensim</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
|
|
@ -4018,6 +3938,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>ReleaseFS_AVX</key>
|
||||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>bash</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<string>--build</string>
|
||||
<string>--version</string>
|
||||
<string>--opensim</string>
|
||||
<string>--avx</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
|
|
@ -4036,6 +3969,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>ReleaseFS_AVX2</key>
|
||||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>bash</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<string>--build</string>
|
||||
<string>--version</string>
|
||||
<string>--opensim</string>
|
||||
<string>--avx2</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
|
|
@ -4054,6 +4000,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>ReleaseFS_open</key>
|
||||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>bash</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<string>--build</string>
|
||||
<string>--version</string>
|
||||
<string>--opensim</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
|
|
@ -4071,6 +4029,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>RelWithDebInfoFS</key>
|
||||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>bash</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
<string>--build</string>
|
||||
<string>--version</string>
|
||||
<string>--opensim</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
|
|
@ -4089,6 +4060,19 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
</map>
|
||||
<key>RelWithDebInfoFS_open</key>
|
||||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>bash</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
<string>--build</string>
|
||||
<string>--version</string>
|
||||
<string>--opensim</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
|
|
@ -4241,14 +4225,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--build</string>
|
||||
<string>--package</string>
|
||||
<string>--platform darwin</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
</array>
|
||||
|
|
@ -4259,7 +4239,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<array>
|
||||
<string>--platform darwin</string>
|
||||
<string>--package</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
</array>
|
||||
|
|
@ -4273,14 +4252,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--build</string>
|
||||
<string>--package</string>
|
||||
<string>--platform darwin</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -4289,7 +4264,6 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<array>
|
||||
<string>--platform darwin</string>
|
||||
<string>--package</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
|
|
@ -4299,11 +4273,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--build</string>
|
||||
<string>--platform darwin</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
|
|
@ -4457,19 +4428,14 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>name</key>
|
||||
<string>default</string>
|
||||
</map>
|
||||
|
||||
<key>RelWithDebInfoFS</key>
|
||||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--build</string>
|
||||
<string>--platform linux32</string>
|
||||
<string>--platform linux</string>
|
||||
<string>--package</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -4478,9 +4444,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<array>
|
||||
<string>--kdu</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--platform linux32</string>
|
||||
<string>--platform linux</string>
|
||||
<string>--package</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>default</key>
|
||||
|
|
@ -4492,23 +4457,18 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--build</string>
|
||||
<string>--platform linux32</string>
|
||||
<string>--platform linux</string>
|
||||
<string>--package</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--platform linux32</string>
|
||||
<string>--platform linux</string>
|
||||
<string>--package</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
|
|
@ -4518,12 +4478,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--build</string>
|
||||
<string>--platform linux32</string>
|
||||
<string>--platform linux</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -4532,7 +4490,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<array>
|
||||
<string>--kdu</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--platform linux32</string>
|
||||
<string>--platform linux</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
|
|
@ -4542,12 +4500,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>command</key>
|
||||
<string>../scripts/configure_firestorm.sh</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--build</string>
|
||||
<string>--platform linux32</string>
|
||||
<string>--platform linux</string>
|
||||
<string>--package</string>
|
||||
</array>
|
||||
</map>
|
||||
|
|
@ -4555,14 +4511,13 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--platform linux32</string>
|
||||
<string>--platform linux</string>
|
||||
<string>--package</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>ReleaseFS_open</string>
|
||||
</map>
|
||||
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -4717,23 +4672,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>Firestorm.sln</string>
|
||||
</array>
|
||||
<key>command</key>
|
||||
<string>msbuild.exe</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>/p:Configuration=RelWithDebInfo</string>
|
||||
<string>/flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log</string>
|
||||
<string>/flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err</string>
|
||||
<string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
|
||||
<string>/t:Build</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:normal</string>
|
||||
<string>/toolsversion:12.0</string>
|
||||
<string>/p:VCBuildAdditionalOptions= /incremental</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
<string>--version</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -4743,8 +4687,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
<string>--version</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
<string>--platform win32</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>default</key>
|
||||
|
|
@ -4756,23 +4699,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>Firestorm.sln</string>
|
||||
</array>
|
||||
<key>command</key>
|
||||
<string>msbuild.exe</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>/p:Configuration=RelWithDebInfo</string>
|
||||
<string>/flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log</string>
|
||||
<string>/flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err</string>
|
||||
<string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
|
||||
<string>/t:Build</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:normal</string>
|
||||
<string>/toolsversion:12.0</string>
|
||||
<string>/p:VCBuildAdditionalOptions= /incremental</string>
|
||||
<string>--version</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -4781,7 +4712,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<array>
|
||||
<string>--version</string>
|
||||
<string>--btype RelWithDebInfo</string>
|
||||
<string>--platform win32</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
|
|
@ -4791,23 +4722,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>Firestorm.sln</string>
|
||||
</array>
|
||||
<key>command</key>
|
||||
<string>msbuild.exe</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>/p:Configuration=Release</string>
|
||||
<string>/flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log</string>
|
||||
<string>/flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err</string>
|
||||
<string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
|
||||
<string>/t:Build</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:normal</string>
|
||||
<string>/toolsversion:12.0</string>
|
||||
<string>/p:VCBuildAdditionalOptions= /incremental</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
<string>--version</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -4817,7 +4737,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
<string>--version</string>
|
||||
<string>--platform win32</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
|
|
@ -4827,34 +4747,22 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>Firestorm.sln</string>
|
||||
</array>
|
||||
<key>command</key>
|
||||
<string>msbuild.exe</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>/p:Configuration=Release</string>
|
||||
<string>/flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log</string>
|
||||
<string>/flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err</string>
|
||||
<string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
|
||||
<string>/t:Build</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:normal</string>
|
||||
<string>/toolsversion:12.0</string>
|
||||
<string>/p:VCBuildAdditionalOptions= /incremental</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
<string>--version</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--avx</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
<string>--version</string>
|
||||
<string>--platform win32</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
|
|
@ -4864,34 +4772,22 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>Firestorm.sln</string>
|
||||
</array>
|
||||
<key>command</key>
|
||||
<string>msbuild.exe</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>/p:Configuration=Release</string>
|
||||
<string>/flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log</string>
|
||||
<string>/flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err</string>
|
||||
<string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
|
||||
<string>/t:Build</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:normal</string>
|
||||
<string>/toolsversion:12.0</string>
|
||||
<string>/p:VCBuildAdditionalOptions= /incremental</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
<string>--version</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
<map>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>--avx2</string>
|
||||
<string>--fmodstudio</string>
|
||||
<string>--kdu</string>
|
||||
<string>--version</string>
|
||||
<string>--platform win32</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
|
|
@ -4901,23 +4797,10 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<map>
|
||||
<key>build</key>
|
||||
<map>
|
||||
<key>arguments</key>
|
||||
<array>
|
||||
<string>Firestorm.sln</string>
|
||||
</array>
|
||||
<key>command</key>
|
||||
<string>msbuild.exe</string>
|
||||
<key>options</key>
|
||||
<array>
|
||||
<string>/p:Configuration=Release</string>
|
||||
<string>/flp:LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.log</string>
|
||||
<string>/flp1:errorsonly;LogFile=logs\FirestormBuild_win-${AUTOBUILD_ADDRSIZE}.err</string>
|
||||
<string>/p:Platform=${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
|
||||
<string>/t:Build</string>
|
||||
<string>/p:useenv=true</string>
|
||||
<string>/verbosity:minimal</string>
|
||||
<string>/toolsversion:12.0</string>
|
||||
<string>/p:VCBuildAdditionalOptions= /incremental</string>
|
||||
<string>--version</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>configure</key>
|
||||
|
|
@ -4925,7 +4808,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
|
|||
<key>options</key>
|
||||
<array>
|
||||
<string>--version</string>
|
||||
<string>--platform win32</string>
|
||||
<string>--platform windows</string>
|
||||
</array>
|
||||
</map>
|
||||
<key>name</key>
|
||||
|
|
|
|||
61
build.sh
61
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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES
|
|||
Audio.cmake
|
||||
BerkeleyDB.cmake
|
||||
Boost.cmake
|
||||
bugsplat.cmake
|
||||
BuildVersion.cmake
|
||||
CEFPlugin.cmake
|
||||
CMakeCopyIfDifferent.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)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
# -*- cmake -*-
|
||||
include(00-Common)
|
||||
include(LLTestCommand)
|
||||
|
||||
# <FS:ND> Google Mock/Test is not used
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
use_prebuilt_binary(llbase)
|
||||
|
|
@ -77,6 +77,7 @@ if (WINDOWS)
|
|||
wldap32
|
||||
gdi32
|
||||
user32
|
||||
ole32
|
||||
dbghelp
|
||||
)
|
||||
else (WINDOWS)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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.") # <FS:Ansariel> No Teamcity -> allow unattended
|
||||
|
||||
set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
|
||||
# <FS:ND> When using Havok, we have to turn OpenSim support off
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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()
|
||||
|
|
@ -40,7 +40,7 @@ add_executable(llimage_libtest
|
|||
WIN32
|
||||
MACOSX_BUNDLE
|
||||
${llimage_libtest_SOURCE_FILES}
|
||||
)
|
||||
)
|
||||
|
||||
set_target_properties(llimage_libtest
|
||||
PROPERTIES
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<LLAvatarJoint*>(*iter);
|
||||
// LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*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<LLAvatarJoint*>(*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<LLAvatarJoint*>(*iter);
|
||||
// LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
|
||||
// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
|
||||
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*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<LLAvatarJoint*>(*iter);
|
||||
// LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
|
||||
// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
|
||||
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*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<LLAvatarJoint*>(*iter);
|
||||
// LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
|
||||
// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
|
||||
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*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<LLAvatarJoint*>(*iter);
|
||||
// LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
|
||||
// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
|
||||
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
|
||||
// [/SL:KB]
|
||||
joint->dump();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -211,4 +211,3 @@ void LLLocalTextureObject::setBakedReady(BOOL ready)
|
|||
{
|
||||
mIsBakedReady = ready;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -125,6 +125,9 @@ namespace {
|
|||
public:
|
||||
RecordToFile(const std::string& filename)
|
||||
{
|
||||
// <FS:Ansariel> 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>(recordToFile)->okay())
|
||||
{
|
||||
s->mFileRecorderFileName = file_name;
|
||||
s->mFileRecorder = recordToFile;
|
||||
addRecorder(recordToFile);
|
||||
RecorderPtr recordToFile(new RecordToFile(file_name));
|
||||
if (boost::dynamic_pointer_cast<RecordToFile>(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
|
||||
{
|
||||
/* <FS:LO> 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);
|
||||
}
|
||||
} </FS:LO> */
|
||||
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<std::string, unsigned int>::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();
|
||||
}
|
||||
|
||||
// <FS:Ansriel> Fix log output - we don't need an escaped output
|
||||
//addEscapedMessage(message_stream, message);
|
||||
message_stream << message;
|
||||
// </FS:Ansariel>
|
||||
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)
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Recorder> RecorderPtr;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#if LL_WINDOWS
|
||||
#include "llwin32headerslean.h"
|
||||
#include <stdlib.h> // Windows errno
|
||||
#include <vector>
|
||||
#else
|
||||
#include <errno.h>
|
||||
#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<DWORD>(utf16path.size()), &utf16path[0]);
|
||||
utf8path = utf16str_to_utf8str(utf16path);
|
||||
std::vector<wchar_t> 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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -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<std::string>& 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<std::string>::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<LLLeapListener> 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<std::string>& 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<std::string>&
|
|||
}
|
||||
}
|
||||
|
||||
LLLeap* LLLeap::create(const std::string& desc, const std::vector<std::string>& plugin, bool exc)
|
||||
{
|
||||
LLProcess::Params params;
|
||||
params.desc = desc;
|
||||
std::vector<std::string>::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
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "llinstancetracker.h"
|
||||
#include "llexception.h"
|
||||
#include "llprocess.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<std::string>(result));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include "llerror.h"
|
||||
#include "llfasttimer.h"
|
||||
#include "llsd.h"
|
||||
#include <vector>
|
||||
|
||||
#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<wchar_t> 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<wchar_t> 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<std::wstring>(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<wchar_t, void(*)(void*)> 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<std::wstring> 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<wchar_t> 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<std::wstring>(&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<std::string>(last_error) << LL_ENDL;
|
||||
}
|
||||
// return empty boost::optional
|
||||
return {};
|
||||
}
|
||||
|
||||
#else // ! LL_WINDOWS
|
||||
|
||||
boost::optional<std::string> llstring_getoptenv(const std::string& key)
|
||||
{
|
||||
auto found = getenv(key.c_str());
|
||||
if (found)
|
||||
{
|
||||
// return populated boost::optional
|
||||
return boost::optional<std::string>(found);
|
||||
}
|
||||
else
|
||||
{
|
||||
// return empty boost::optional
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ! LL_WINDOWS
|
||||
|
||||
long LLStringOps::sPacificTimeOffset = 0;
|
||||
long LLStringOps::sLocalTimeOffset = 0;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#ifndef LL_LLSTRING_H
|
||||
#define LL_LLSTRING_H
|
||||
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
//#include <locale>
|
||||
|
|
@ -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<string_type> 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<typename TO, typename FROM, typename Enable=void>
|
||||
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<TO>(from_value) API.
|
||||
template<typename TO, typename FROM>
|
||||
TO ll_convert(const FROM& in)
|
||||
{
|
||||
return ll_convert_impl<TO, FROM>()(in);
|
||||
}
|
||||
|
||||
// degenerate case
|
||||
template<typename T>
|
||||
struct ll_convert_impl<T, T>
|
||||
{
|
||||
T operator()(const T& in) const { return in; }
|
||||
};
|
||||
|
||||
// specialize ll_convert_impl<TO, FROM> to return EXPR
|
||||
#define ll_convert_alias(TO, FROM, EXPR) \
|
||||
template<> \
|
||||
struct ll_convert_impl<TO, FROM> \
|
||||
{ \
|
||||
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<U16> 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<typename STRING>
|
||||
STRING windows_message(unsigned long error)
|
||||
{
|
||||
return ll_convert<STRING>(windows_message<std::wstring>(error));
|
||||
}
|
||||
|
||||
/// There's only one real implementation
|
||||
template<>
|
||||
LL_COMMON_API std::wstring windows_message<std::wstring>(unsigned long error);
|
||||
|
||||
/// Get Windows message string, implicitly calling GetLastError()
|
||||
template<typename STRING>
|
||||
STRING windows_message() { return windows_message<STRING>(GetLastError()); }
|
||||
|
||||
//@}
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
LL_COMMON_API boost::optional<std::wstring> llstring_getoptenv(const std::string& key);
|
||||
|
||||
#else // ! LL_WINDOWS
|
||||
|
||||
LL_COMMON_API boost::optional<std::string> 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<T>::endsWith(
|
|||
return (idx == (string.size() - substr.size()));
|
||||
}
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
auto LLStringUtilBase<T>::getoptenv(const std::string& key) -> boost::optional<string_type>
|
||||
{
|
||||
auto found(llstring_getoptenv(key));
|
||||
if (found)
|
||||
{
|
||||
// return populated boost::optional
|
||||
return { ll_convert<string_type>(*found) };
|
||||
}
|
||||
else
|
||||
{
|
||||
// empty boost::optional
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
auto LLStringUtilBase<T>::getenv(const std::string& key, const string_type& dflt) -> string_type
|
||||
{
|
||||
auto found(getoptenv(key));
|
||||
if (found)
|
||||
{
|
||||
return *found;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dflt;
|
||||
}
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToBOOL(const string_type& string, BOOL& value)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@
|
|||
#define LL_STRINGIZE_H
|
||||
|
||||
#include <sstream>
|
||||
#include <boost/phoenix/phoenix.hpp>
|
||||
#include <llstring.h>
|
||||
|
||||
/**
|
||||
|
|
@ -53,12 +52,7 @@ std::basic_string<CHARTYPE> 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<char>(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<wchar_t>(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 <typename Functor>
|
||||
std::string stringize_f(Functor const & f)
|
||||
template <typename CHARTYPE, typename Functor>
|
||||
std::basic_string<CHARTYPE> stringize_f(Functor const & f)
|
||||
{
|
||||
std::ostringstream out;
|
||||
std::basic_ostringstream<CHARTYPE> 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<char>([&](std::ostream& out){ out << EXPRESSION; }))
|
||||
|
||||
/**
|
||||
* WSTRINGIZE() is the wstring equivalent of STRINGIZE()
|
||||
*/
|
||||
#define WSTRINGIZE(EXPRESSION) (stringize_f<wchar_t>([&](std::wostream& out){ out << EXPRESSION; }))
|
||||
|
||||
/**
|
||||
* destringize(str)
|
||||
* defined for symmetry with stringize
|
||||
* *NOTE - this has distinct behavior from boost::lexical_cast<T> regarding
|
||||
* @NOTE - this has distinct behavior from boost::lexical_cast<T> 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 <typename T>
|
||||
T destringize(std::string const & str)
|
||||
template <typename T, typename CHARTYPE>
|
||||
T destringize(std::basic_string<CHARTYPE> const & str)
|
||||
{
|
||||
T val;
|
||||
std::istringstream in(str);
|
||||
in >> val;
|
||||
T val;
|
||||
std::basic_istringstream<CHARTYPE> in(str);
|
||||
in >> val;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* destringize_f(str, functor)
|
||||
*/
|
||||
template <typename Functor>
|
||||
void destringize_f(std::string const & str, Functor const & f)
|
||||
template <typename CHARTYPE, typename Functor>
|
||||
void destringize_f(std::basic_string<CHARTYPE> const & str, Functor const & f)
|
||||
{
|
||||
std::istringstream in(str);
|
||||
std::basic_istringstream<CHARTYPE> 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) */
|
||||
|
|
|
|||
|
|
@ -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<TestRecorder>(mRecorder)->setWantsTime(t);
|
||||
}
|
||||
{
|
||||
boost::dynamic_pointer_cast<TestRecorder>(mRecorder)->showTime(t);
|
||||
}
|
||||
|
||||
void setWantsMultiline(bool t)
|
||||
{
|
||||
boost::dynamic_pointer_cast<TestRecorder>(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<TestRecorder>(anotherRecorder)->setWantsTime(true);
|
||||
boost::dynamic_pointer_cast<TestRecorder>(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<>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "wrapllerrs.h"
|
||||
#include "llevents.h"
|
||||
#include "llprocess.h"
|
||||
#include "llstring.h"
|
||||
#include "stringize.h"
|
||||
#include "StringVec.h"
|
||||
#include <functional>
|
||||
|
|
@ -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_data> llleap_group;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ typedef U32 uint32_t;
|
|||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include "llprocess.h"
|
||||
#include "llstring.h"
|
||||
#endif
|
||||
|
||||
#include "boost/range.hpp"
|
||||
|
|
@ -1705,8 +1706,8 @@ namespace tut
|
|||
template <typename CONTENT>
|
||||
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];
|
||||
|
|
|
|||
|
|
@ -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) */
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "llsd.h"
|
||||
#include "llhost.h"
|
||||
#include "llexception.h"
|
||||
#include "llstring.h"
|
||||
#include "stringize.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
|
@ -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"));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ add_executable(SLPlugin
|
|||
WIN32
|
||||
MACOSX_BUNDLE
|
||||
${SLPlugin_SOURCE_FILES}
|
||||
)
|
||||
)
|
||||
|
||||
if (WINDOWS)
|
||||
set_target_properties(SLPlugin
|
||||
|
|
|
|||
|
|
@ -40,10 +40,17 @@
|
|||
#include "v4color.h"
|
||||
#include "lltexture.h"
|
||||
#include "lldir.h"
|
||||
#include "llstring.h"
|
||||
|
||||
// Third party library includes
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include <Shlobj.h>
|
||||
#include <Knownfolders.h>
|
||||
#include <Objbase.h>
|
||||
#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 {};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "lldiriterator.h"
|
||||
#include "stringize.h"
|
||||
#include "llstring.h"
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "lldir_linux.h"
|
||||
#include "llerror.h"
|
||||
#include "llrand.h"
|
||||
#include "llstring.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
//<FS:TS> Used by LGG's selection beams
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include "lldir_solaris.h"
|
||||
#include "llerror.h"
|
||||
#include "llrand.h"
|
||||
#include "llstring.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
|
@ -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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 <shlobj.h>
|
||||
// <FS:Ansariel> Remove VMP
|
||||
#include <Knownfolders.h>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <Objbase.h> // CoTaskMemFree()
|
||||
// </FS:Ansariel> Remove VMP
|
||||
#include <fstream>
|
||||
|
||||
#include <direct.h>
|
||||
|
|
@ -49,55 +45,87 @@
|
|||
#define PACKVERSION(major,minor) MAKELONG(minor,major)
|
||||
DWORD GetDllVersion(LPCTSTR lpszDllName);
|
||||
|
||||
// <FS:Ansariel> 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<std::string> 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<HRESULT, const char*> 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
|
||||
// </FS:Ansariel> 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).
|
||||
// <FS:Ansariel> Remove VMP
|
||||
//mOSUserDir = ll_safe_string(getenv("APPDATA"));
|
||||
mOSUserDir = getKnownFolderPath("RoamingAppData", FOLDERID_RoamingAppData);
|
||||
// </FS:Ansariel> 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
|
||||
// <FS:Ansariel> Remove VMP
|
||||
//mOSCacheDir = ll_safe_string(getenv("LOCALAPPDATA"));
|
||||
mOSCacheDir = getKnownFolderPath("LocalAppData", FOLDERID_LocalAppData);
|
||||
// </FS:Ansariel> 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 */
|
||||
|
|
|
|||
|
|
@ -1459,12 +1459,10 @@ static CursorRef gCursors[UI_CURSOR_COUNT];
|
|||
static void initPixmapCursor(int cursorid, int hotspotX, int hotspotY)
|
||||
{
|
||||
// cursors are in <Application Bundle>/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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3349,17 +3349,10 @@ S32 OSMessageBoxWin32(const std::string& text, const std::string& caption, U32 t
|
|||
break;
|
||||
}
|
||||
|
||||
// HACK! Doesn't properly handle wide strings!
|
||||
|
||||
// <FS:ND> 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);
|
||||
|
||||
// </FS:ND>
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -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 <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace tut
|
||||
{
|
||||
|
||||
struct control_group
|
||||
{
|
||||
LLControlGroup* mCG;
|
||||
std::unique_ptr<LLControlGroup> mCG;
|
||||
std::string mTestConfigDir;
|
||||
std::string mTestConfigFile;
|
||||
std::vector<std::string> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,5 +48,5 @@ set(media_plugin_base_HEADER_FILES
|
|||
|
||||
add_library(media_plugin_base
|
||||
${media_plugin_base_SOURCE_FILES}
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
# <FS:ND> 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
|
||||
)
|
||||
|
||||
# <FS:Ansariel> 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)
|
||||
# </FS:Ansariel>
|
||||
|
||||
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
|
||||
# <FS:CR> 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(
|
||||
# <FS:CR> 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
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${MACOSX_WRAPPER_EXECUTABLE_NAME}</string>
|
||||
<string>${MACOSX_EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string>${MACOSX_BUNDLE_INFO_STRING}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>${MACOSX_BUNDLE_LONG_VERSION_STRING}</string>
|
||||
<string>${MACOSX_BUNDLE_SHORT_VERSION_STRING}</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
|
@ -32,6 +32,8 @@
|
|||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>${MACOSX_BUNDLE_COPYRIGHT}</string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>For voice chat, you must grant permission for Second Life to use the microphone.</string>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
6.0.3
|
||||
6.1.1
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
</array>
|
||||
<key>tags</key>
|
||||
<array>
|
||||
|
||||
<!-- sample entry for debugging specific items
|
||||
<string>AnimatedObjects</string>
|
||||
<string>Avatar</string>
|
||||
|
|
|
|||
|
|
@ -6487,6 +6487,17 @@
|
|||
<key>Value</key>
|
||||
<real>96.0</real>
|
||||
</map>
|
||||
<key>ForceAddressSize</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Force Windows update to 32-bit or 64-bit viewer.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ForceAssetFail</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -16966,7 +16977,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>UpdaterServiceURL</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Default location for the updater service.</string>
|
||||
<string>Obsolete; no longer used.</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -17565,19 +17576,6 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Value</key>
|
||||
<real>1.0</real>
|
||||
</map>
|
||||
<key>VerboseLogs</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display source file and line number for each log item for debugging purposes</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
<key>Backup</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>VertexShaderEnable</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
@ -21459,7 +21457,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<string>if true, disables running the GPU benchmark at startup
|
||||
(default to class 1)</string>
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
|
|
@ -24893,7 +24891,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<integer>3.0</integer>
|
||||
<real>3.0</real>
|
||||
</map>
|
||||
<key>FSExperimentalLostAttachmentsFixReport</key>
|
||||
<map>
|
||||
|
|
|
|||
|
|
@ -152,10 +152,10 @@ class FSViewerManifest:
|
|||
from shutil import copyfile
|
||||
self.fs_strip_windows_manifest( "%s/slplugin.exe" % self.args['configuration'].lower() )
|
||||
self.fs_strip_windows_manifest( "%s/llplugin/dullahan_host.exe" % self.args['configuration'].lower() )
|
||||
if self.prefix(src=os.path.join(os.pardir, '..', 'indra', 'tools', 'manifests'), dst=""):
|
||||
if self.prefix(src=os.path.join(self.args['build'], os.pardir, os.pardir, 'indra', 'tools', 'manifests')):
|
||||
self.path( "compatibility.manifest", "slplugin.exe.manifest" )
|
||||
self.end_prefix()
|
||||
if self.prefix(src=os.path.join(os.pardir, '..', 'indra', 'tools', 'manifests'), dst="llplugin"):
|
||||
if self.prefix(src=os.path.join(self.args['build'], os.pardir, os.pardir, 'indra', 'tools', 'manifests'), dst="llplugin"):
|
||||
self.path( "compatibility.manifest", "dullahan_host.exe.manifest" )
|
||||
self.end_prefix()
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,7 @@
|
|||
;;
|
||||
;; Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
;;
|
||||
;; NSIS Unicode 2.46.5 or higher required
|
||||
;; http://www.scratchpaper.com/
|
||||
;; NSIS 3 or higher required for Unicode support
|
||||
;;
|
||||
;; Author: James Cook, TankMaster Finesmith, Don Kjer, Callum Prentice
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
@ -27,6 +26,7 @@
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Compiler flags
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Unicode true
|
||||
SetOverwrite on # Overwrite files
|
||||
SetCompress auto # Compress if saves space
|
||||
SetCompressor /solid lzma # Compress whole installer as one block
|
||||
|
|
@ -46,46 +46,51 @@ RequestExecutionLevel admin # For when we write to Program Files
|
|||
;; (these files are in the same place as the nsi template but the python script generates a new nsi file in the
|
||||
;; application directory so we have to add a path to these include files)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
!include "%%SOURCE%%\installers\windows\lang_en-us.nsi" # <FS:Ansariel> Make sure EN comes first as it will be default!
|
||||
!include "%%SOURCE%%\installers\windows\lang_da.nsi"
|
||||
;; Ansariel notes: "Under certain circumstances the installer will fall back
|
||||
;; to the first defined (aka default) language version. So you want to include
|
||||
;; en-us as first language file."
|
||||
!include "%%SOURCE%%\installers\windows\lang_en-us.nsi"
|
||||
|
||||
# Danish and Polish no longer supported by the viewer itself
|
||||
##!include "%%SOURCE%%\installers\windows\lang_da.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_de.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_es.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_fr.nsi"
|
||||
##!include "%%SOURCE%%\installers\windows\lang_fr.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_ja.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_it.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_pl.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_pt-br.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_pl.nsi" ;<FS:Ansariel> Polish is supported
|
||||
##!include "%%SOURCE%%\installers\windows\lang_pt-br.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_ru.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_tr.nsi"
|
||||
!include "%%SOURCE%%\installers\windows\lang_zh.nsi"
|
||||
##!include "%%SOURCE%%\installers\windows\lang_tr.nsi"
|
||||
##!include "%%SOURCE%%\installers\windows\lang_zh.nsi"
|
||||
|
||||
# *TODO: Move these into the language files themselves
|
||||
LangString LanguageCode ${LANG_DANISH} "da"
|
||||
##LangString LanguageCode ${LANG_DANISH} "da"
|
||||
LangString LanguageCode ${LANG_GERMAN} "de"
|
||||
LangString LanguageCode ${LANG_ENGLISH} "en"
|
||||
LangString LanguageCode ${LANG_SPANISH} "es"
|
||||
LangString LanguageCode ${LANG_FRENCH} "fr"
|
||||
##LangString LanguageCode ${LANG_FRENCH} "fr"
|
||||
LangString LanguageCode ${LANG_JAPANESE} "ja"
|
||||
LangString LanguageCode ${LANG_ITALIAN} "it"
|
||||
LangString LanguageCode ${LANG_POLISH} "pl"
|
||||
LangString LanguageCode ${LANG_PORTUGUESEBR} "pt"
|
||||
##LangString LanguageCode ${LANG_PORTUGUESEBR} "pt"
|
||||
LangString LanguageCode ${LANG_RUSSIAN} "ru"
|
||||
LangString LanguageCode ${LANG_TURKISH} "tr"
|
||||
LangString LanguageCode ${LANG_TRADCHINESE} "zh"
|
||||
##LangString LanguageCode ${LANG_TURKISH} "tr"
|
||||
##LangString LanguageCode ${LANG_TRADCHINESE} "zh"
|
||||
|
||||
# This placeholder is replaced by viewer_manifest.py
|
||||
%%INST_VARS%%
|
||||
|
||||
Name ${INSTNAME}
|
||||
|
||||
LicenseText "Vivox Voice System License Agreement"
|
||||
LicenseData "VivoxAUP.txt"
|
||||
|
||||
;SubCaption 0 $(LicenseSubTitleSetup) # Override "license agreement" text
|
||||
|
||||
!define MUI_ICON "%%SOURCE%%\installers\windows\firestorm_icon.ico"
|
||||
!define MUI_UNICON "%%SOURCE%%\installers\windows\firestorm_icon.ico"
|
||||
|
||||
BrandingText " " # Bottom of window text
|
||||
Icon %%SOURCE%%\installers\windows\firestorm_icon.ico
|
||||
UninstallIcon %%SOURCE%%\installers\windows\firestorm_icon.ico
|
||||
Icon "${MUI_ICON}"
|
||||
UninstallIcon "${MUI_UNICON}"
|
||||
WindowIcon on # Show our icon in left corner
|
||||
BGGradient off # No big background window
|
||||
CRCCheck on # Make sure CRC is OK
|
||||
|
|
@ -94,25 +99,52 @@ SetOverwrite on # Overwrite files by default
|
|||
# <FS:Ansariel> Don't auto-close so we can check details
|
||||
#AutoCloseWindow true # After all files install, close window
|
||||
|
||||
# initial location of install (default when not already installed)
|
||||
# note: Now we defer looking for existing install until onInit when we
|
||||
# are able to engage the 32/64 registry function
|
||||
InstallDir "%%PROGRAMFILES%%\${INSTNAME}"
|
||||
# Registry key paths, ours and Microsoft's
|
||||
!define LINDEN_KEY "SOFTWARE\The Phoenix Firestorm Project"
|
||||
!define INSTNAME_KEY "${LINDEN_KEY}\${INSTNAME}"
|
||||
!define MSCURRVER_KEY "SOFTWARE\Microsoft\Windows\CurrentVersion"
|
||||
!define MSNTCURRVER_KEY "SOFTWARE\Microsoft\Windows NT\CurrentVersion"
|
||||
!define MSUNINSTALL_KEY "${MSCURRVER_KEY}\Uninstall\${INSTNAME}"
|
||||
|
||||
# from http://nsis.sourceforge.net/Docs/MultiUser/Readme.html
|
||||
### Highest level permitted for user: Admin for Admin, Standard for Standard
|
||||
##!define MULTIUSER_EXECUTIONLEVEL Highest
|
||||
!define MULTIUSER_EXECUTIONLEVEL Admin
|
||||
!define MULTIUSER_MUI
|
||||
### Look for /AllUsers or /CurrentUser switches
|
||||
##!define MULTIUSER_INSTALLMODE_COMMANDLINE
|
||||
# appended to $PROGRAMFILES, as affected by MULTIUSER_USE_PROGRAMFILES64
|
||||
!define MULTIUSER_INSTALLMODE_INSTDIR "${INSTNAME}"
|
||||
# expands to !define MULTIUSER_USE_PROGRAMFILES64 or nothing
|
||||
%%PROGRAMFILES%%
|
||||
# should make MultiUser.nsh initialization read existing INSTDIR from registry
|
||||
## SL-10506: don't
|
||||
##!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${INSTNAME_KEY}"
|
||||
##!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME ""
|
||||
# Don't set MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY and
|
||||
# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME to cause the installer to
|
||||
# write $MultiUser.InstallMode to the registry, because when the user installs
|
||||
# multiple viewers with the same channel (same ${INSTNAME}, hence same
|
||||
# ${INSTNAME_KEY}), the registry entry is overwritten. Instead we'll write a
|
||||
# little file into the install directory -- see .onInstSuccess and un.onInit.
|
||||
!include MultiUser.nsh
|
||||
!include MUI2.nsh
|
||||
!define MUI_BGCOLOR FFFFFF
|
||||
!insertmacro MUI_FUNCTION_GUIINIT
|
||||
|
||||
UninstallText $(UninstallTextMsg)
|
||||
DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup)
|
||||
|
||||
Page license
|
||||
# <FS:Ansariel> Optional start menu entry
|
||||
#Page directory dirPre
|
||||
Page directory dirPre "" dirPost
|
||||
# </FS:Ansariel>
|
||||
Page instfiles
|
||||
!insertmacro MUI_PAGE_LICENSE "VivoxAUP.txt"
|
||||
##!insertmacro MULTIUSER_PAGE_INSTALLMODE
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_PRE dirPre
|
||||
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE dirLeave # <FS:Ansariel> Optional start menu entry
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Variables
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Var INSTPROG
|
||||
Var INSTNAME
|
||||
Var INSTEXE
|
||||
Var VIEWER_EXE
|
||||
Var INSTSHORTCUT
|
||||
|
|
@ -148,7 +180,7 @@ FunctionEnd
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Post-directory page callback
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function dirPost
|
||||
Function dirLeave
|
||||
StrCmp $SKIP_DIALOGS "true" label_create_start_menu
|
||||
|
||||
MessageBox MB_YESNO|MB_ICONQUESTION $(CreateStartMenuEntry) IDYES label_create_start_menu
|
||||
|
|
@ -167,17 +199,21 @@ FunctionEnd
|
|||
;; entry to the language ID selector below
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function .onInit
|
||||
!insertmacro MULTIUSER_INIT
|
||||
|
||||
%%ENGAGEREGISTRY%%
|
||||
|
||||
# read the current location of the install for this version
|
||||
# if $0 is empty, this is the first time for this viewer name
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\\Linden Research, Inc.\\${INSTNAME}" ""
|
||||
# SL-10506: Setting MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY and
|
||||
# MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME should
|
||||
# read the current location of the install for this version into INSTDIR.
|
||||
# However, SL-10506 complains about the resulting behavior, so the logic below
|
||||
# is adapted from before we introduced MultiUser.nsh.
|
||||
|
||||
# viewer with this name not installed before
|
||||
${If} $0 == ""
|
||||
# nothing to do here
|
||||
${Else}
|
||||
# if $0 is empty, this is the first time for this viewer name
|
||||
ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" ""
|
||||
|
||||
# viewer with this name was installed before
|
||||
${If} $0 != ""
|
||||
# use the value we got from registry as install location
|
||||
StrCpy $INSTDIR $0
|
||||
${EndIf}
|
||||
|
|
@ -213,7 +249,7 @@ Call CheckWindowsVersion # Don't install On unsupported systems
|
|||
lbl_configure_default_lang:
|
||||
# If we currently have a version of SL installed, default to the language of that install
|
||||
# Otherwise don't change $LANGUAGE and it will default to the OS UI language.
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\${INSTNAME}" "InstallerLanguage"
|
||||
ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage"
|
||||
IfErrors +2 0 # If error skip the copy instruction
|
||||
StrCpy $LANGUAGE $0
|
||||
|
||||
|
|
@ -226,8 +262,6 @@ lbl_configure_default_lang:
|
|||
# </FS:Ansariel>
|
||||
StrCmp $SKIP_DIALOGS "true" lbl_return
|
||||
|
||||
# <FS:Ansariel> Commented out; Warning in build log about not being used
|
||||
;lbl_build_menu:
|
||||
Push ""
|
||||
# Use separate file so labels can be UTF-16 but we can still merge changes into this ASCII file. JC
|
||||
!include "%%SOURCE%%\installers\windows\language_menu.nsi"
|
||||
|
|
@ -240,7 +274,7 @@ lbl_configure_default_lang:
|
|||
StrCpy $LANGUAGE $0
|
||||
|
||||
# Save language in registry
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\${INSTNAME}" "InstallerLanguage" $LANGUAGE
|
||||
WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage" $LANGUAGE
|
||||
lbl_return:
|
||||
Pop $0
|
||||
Return
|
||||
|
|
@ -251,14 +285,32 @@ FunctionEnd
|
|||
;; Prep Uninstaller Section
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function un.onInit
|
||||
# Save $INSTDIR -- it appears to have the correct value before
|
||||
# MULTIUSER_UNINIT, but then gets munged by MULTIUSER_UNINIT?!
|
||||
Push $INSTDIR
|
||||
!insertmacro MULTIUSER_UNINIT
|
||||
Pop $INSTDIR
|
||||
|
||||
# Now read InstallMode.txt from $INSTDIR
|
||||
Push $0
|
||||
ClearErrors
|
||||
FileOpen $0 "$INSTDIR\InstallMode.txt" r
|
||||
IfErrors skipread
|
||||
FileRead $0 $MultiUser.InstallMode
|
||||
FileClose $0
|
||||
skipread:
|
||||
Pop $0
|
||||
|
||||
%%ENGAGEREGISTRY%%
|
||||
|
||||
# Read language from registry and set for uninstaller. Key will be removed on successful uninstall
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\${INSTNAME}" "InstallerLanguage"
|
||||
ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" "InstallerLanguage"
|
||||
IfErrors lbl_end
|
||||
StrCpy $LANGUAGE $0
|
||||
lbl_end:
|
||||
|
||||
## MessageBox MB_OK "After restoring:$\n$$INSTDIR = '$INSTDIR'$\n$$MultiUser.InstallMode = '$MultiUser.InstallMode'$\n$$LANGUAGE = '$LANGUAGE'"
|
||||
|
||||
Return
|
||||
|
||||
FunctionEnd
|
||||
|
|
@ -308,10 +360,10 @@ FunctionEnd
|
|||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Section ""
|
||||
|
||||
SetShellVarContext all # Install for all users (if you change this, change it in the uninstall as well)
|
||||
# SetShellVarContext is set by MultiUser.nsh initialization.
|
||||
|
||||
# Start with some default values.
|
||||
StrCpy $INSTPROG "${INSTNAME}"
|
||||
StrCpy $INSTNAME "${INSTNAME}"
|
||||
StrCpy $INSTEXE "${INSTEXE}"
|
||||
StrCpy $VIEWER_EXE "${VIEWER_EXE}"
|
||||
StrCpy $INSTSHORTCUT "${SHORTCUT}"
|
||||
|
|
@ -341,7 +393,7 @@ SetOutPath "$INSTDIR"
|
|||
CreateShortCut "$SMPROGRAMS\$INSTSHORTCUT\$INSTSHORTCUT.lnk" \
|
||||
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM"
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
#"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
|
||||
|
||||
WriteINIStr "$SMPROGRAMS\$INSTSHORTCUT\SL Create Account.url" \
|
||||
|
|
@ -365,44 +417,41 @@ SetOutPath "$INSTDIR"
|
|||
CreateShortCut "$DESKTOP\$INSTSHORTCUT.lnk" \
|
||||
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM"
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
#"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
CreateShortCut "$INSTDIR\$INSTSHORTCUT.lnk" \
|
||||
"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM"
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#"$INSTDIR\$INSTEXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
#"$INSTDIR\$VIEWER_EXE" "$SHORTCUT_LANG_PARAM" "$INSTDIR\$VIEWER_EXE"
|
||||
CreateShortCut "$INSTDIR\Uninstall $INSTSHORTCUT.lnk" \
|
||||
'"$INSTDIR\uninst.exe"' ''
|
||||
|
||||
# Write registry
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "" "$INSTDIR"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "Version" "${VERSION_LONG}"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "Shortcut" "$INSTSHORTCUT"
|
||||
#WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "Exe" "$INSTEXE"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG" "Exe" "$VIEWER_EXE"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "Publisher" "The Phoenix Firestorm Project, Inc."
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "URLInfoAbout" "http://www.firestormviewer.org"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "URLUpdateInfo" "http://www.firestormviewer.org/downloads"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "HelpLink" "http://www.firestormviewer.org/support"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayName" "$INSTPROG"
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe"'
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayVersion" "${VERSION_LONG}"
|
||||
WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "" "$INSTDIR"
|
||||
WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Version" "${VERSION_LONG}"
|
||||
WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Shortcut" "$INSTSHORTCUT"
|
||||
WriteRegStr SHELL_CONTEXT "${INSTNAME_KEY}" "Exe" "$VIEWER_EXE"
|
||||
WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "Publisher" "The Phoenix Firestorm Project, Inc."
|
||||
WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "URLInfoAbout" "http://www.firestormviewer.org"
|
||||
WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "URLUpdateInfo" "http://www.firestormviewer.org/downloads"
|
||||
WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "HelpLink" "http://www.firestormviewer.org/support"
|
||||
WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayName" "$INSTNAME"
|
||||
WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "UninstallString" '"$INSTDIR\uninst.exe"'
|
||||
WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayVersion" "${VERSION_LONG}"
|
||||
# <FS:Ansariel> Separate install sizes for 32 and 64 bit
|
||||
#WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "EstimatedSize" "0x0001D500" # ~117 MB
|
||||
#WriteRegDWORD SHELL_CONTEXT "${MSUNINSTALL_KEY}" "EstimatedSize" "0x0001D500" # ~117 MB
|
||||
${If} ${IS64BIT} == "1"
|
||||
WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "EstimatedSize" "0x00064000" # 400 MB
|
||||
WriteRegDWORD SHELL_CONTEXT "${MSUNINSTALL_KEY}" "EstimatedSize" "0x00064000" # 400 MB
|
||||
${Else}
|
||||
WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "EstimatedSize" "0x00057800" # 350 MB
|
||||
WriteRegDWORD SHELL_CONTEXT "${MSUNINSTALL_KEY}" "EstimatedSize" "0x00057800" # 350 MB
|
||||
${EndIf}
|
||||
|
||||
# from FS:Ansariel
|
||||
#WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayIcon" '"$INSTDIR\$INSTEXE"'
|
||||
WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayIcon" '"$INSTDIR\$VIEWER_EXE"'
|
||||
WriteRegStr SHELL_CONTEXT "${MSUNINSTALL_KEY}" "DisplayIcon" '"$INSTDIR\$VIEWER_EXE"'
|
||||
|
||||
# BUG-2707 Disable SEHOP for installed viewer.
|
||||
#WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$INSTEXE" "DisableExceptionChainValidation" 1
|
||||
WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$VIEWER_EXE" "DisableExceptionChainValidation" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "NoModify" 1
|
||||
WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "NoRepair" 1
|
||||
WriteRegDWORD SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE" "DisableExceptionChainValidation" 1
|
||||
WriteRegDWORD SHELL_CONTEXT "${MSUNINSTALL_KEY}" "NoModify" 1
|
||||
WriteRegDWORD SHELL_CONTEXT "${MSUNINSTALL_KEY}" "NoRepair" 1
|
||||
|
||||
# Write URL registry info
|
||||
WriteRegStr HKEY_CLASSES_ROOT "${URLNAME}" "(default)" "URL:Second Life"
|
||||
|
|
@ -419,11 +468,8 @@ WriteRegStr HKEY_CLASSES_ROOT "x-grid-location-info\DefaultIcon" "" '"$INSTDIR\$
|
|||
# URL param must be last item passed to viewer, it ignores subsequent params to avoid parameter injection attacks.
|
||||
WriteRegExpandStr HKEY_CLASSES_ROOT "x-grid-location-info\shell\open\command" "" '"$INSTDIR\$VIEWER_EXE" -url "%1"'
|
||||
|
||||
# Only allow Launcher to be the icon
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#WriteRegStr HKEY_CLASSES_ROOT "Applications\$INSTEXE" "IsHostApp" ""
|
||||
#WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
|
||||
# </FS:Ansariel> Remove VMP
|
||||
WriteRegStr HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" ""
|
||||
##WriteRegStr HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}" "NoStartPage" ""
|
||||
|
||||
# <FS:CR> Register hop:// protocol registry info
|
||||
WriteRegStr HKEY_CLASSES_ROOT "hop" "(default)" "URL:Second Life"
|
||||
|
|
@ -451,31 +497,36 @@ SectionEnd
|
|||
Section Uninstall
|
||||
|
||||
# Start with some default values.
|
||||
StrCpy $INSTPROG "${INSTNAME}"
|
||||
StrCpy $INSTNAME "${INSTNAME}"
|
||||
StrCpy $INSTEXE "${INSTEXE}"
|
||||
StrCpy $VIEWER_EXE "${VIEWER_EXE}" # <FS:Ansariel> Disable VMP
|
||||
StrCpy $VIEWER_EXE "${VIEWER_EXE}"
|
||||
StrCpy $INSTSHORTCUT "${SHORTCUT}"
|
||||
|
||||
# Make sure the user can install/uninstall
|
||||
# SetShellVarContext per the mode saved at install time in registry at
|
||||
# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY
|
||||
# MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME
|
||||
# Couldn't get NSIS to expand $MultiUser.InstallMode into the function name at Call time
|
||||
# <FS:Ansariel> Replaced this with Call un.CheckIfAdministrator since there currently is no InstallMode
|
||||
##${If} $MultiUser.InstallMode == 'AllUsers'
|
||||
##MessageBox MB_OK "Uninstalling for all users"
|
||||
## Call un.MultiUser.InstallMode.AllUsers
|
||||
##${Else}
|
||||
##MessageBox MB_OK "Uninstalling for current user"
|
||||
## Call un.MultiUser.InstallMode.CurrentUser
|
||||
##${EndIf}
|
||||
Call un.CheckIfAdministrator
|
||||
|
||||
# Uninstall for all users (if you change this, change it in the install as well)
|
||||
SetShellVarContext all
|
||||
# </FS:Ansariel>
|
||||
|
||||
# Make sure we're not running
|
||||
Call un.CloseSecondLife
|
||||
|
||||
# Clean up registry keys and subkeys (these should all be !defines somewhere)
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\The Phoenix Firestorm Project\$INSTPROG"
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG"
|
||||
DeleteRegKey SHELL_CONTEXT "${INSTNAME_KEY}"
|
||||
DeleteRegKey SHELL_CONTEXT "${MSCURRVER_KEY}\Uninstall\$INSTNAME"
|
||||
# BUG-2707 Remove entry that disabled SEHOP
|
||||
# <FS:Ansariel> Disable VMP
|
||||
#DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$INSTEXE"
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$VIEWER_EXE"
|
||||
# <FS:Ansariel> Remove VMP
|
||||
#DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
|
||||
#DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
|
||||
# </FS:Ansariel> Remove VMP
|
||||
DeleteRegKey SHELL_CONTEXT "${MSNTCURRVER_KEY}\Image File Execution Options\$VIEWER_EXE"
|
||||
##DeleteRegKey HKEY_CLASSES_ROOT "Applications\$INSTEXE"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "Applications\${VIEWER_EXE}"
|
||||
|
||||
# Clean up shortcuts
|
||||
Delete "$SMPROGRAMS\$INSTSHORTCUT\*.*"
|
||||
|
|
@ -650,10 +701,10 @@ Push $2
|
|||
StrCpy $0 0 # Index number used to iterate via EnumRegKey
|
||||
|
||||
LOOP:
|
||||
EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0
|
||||
EnumRegKey $1 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList" $0
|
||||
StrCmp $1 "" DONE # No more users
|
||||
|
||||
ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath"
|
||||
ReadRegStr $2 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList\$1" "ProfileImagePath"
|
||||
StrCmp $2 "" CONTINUE 0 # "ProfileImagePath" value is missing
|
||||
|
||||
# Required since ProfileImagePath is of type REG_EXPAND_SZ
|
||||
|
|
@ -684,7 +735,7 @@ Pop $0
|
|||
|
||||
# Delete files in ProgramData\Firestorm
|
||||
Push $0
|
||||
ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData"
|
||||
ReadRegStr $0 SHELL_CONTEXT "${MSCURRVER_KEY}\Explorer\Shell Folders" "Common AppData"
|
||||
StrCmp $0 "" +2
|
||||
RMDir /r "$0\Firestorm"
|
||||
Pop $0
|
||||
|
|
@ -705,6 +756,9 @@ Function un.ProgramFiles
|
|||
# This placeholder is replaced by the complete list of files to uninstall by viewer_manifest.py
|
||||
%%DELETE_FILES%%
|
||||
|
||||
# our InstallMode.txt
|
||||
Delete "$INSTDIR\InstallMode.txt"
|
||||
|
||||
# Optional/obsolete files. Delete won't fail if they don't exist.
|
||||
Delete "$INSTDIR\autorun.bat"
|
||||
Delete "$INSTDIR\dronesettings.ini"
|
||||
|
|
@ -741,8 +795,8 @@ NOFOLDER:
|
|||
MessageBox MB_YESNO $(DeleteRegistryKeysMB) IDYES DeleteKeys IDNO NoDelete
|
||||
|
||||
DeleteKeys:
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Classes\x-grid-location-info"
|
||||
DeleteRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Classes\secondlife"
|
||||
DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\x-grid-location-info"
|
||||
DeleteRegKey SHELL_CONTEXT "SOFTWARE\Classes\secondlife"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "x-grid-location-info"
|
||||
DeleteRegKey HKEY_CLASSES_ROOT "secondlife"
|
||||
|
||||
|
|
@ -754,7 +808,12 @@ FunctionEnd
|
|||
;; After install completes, launch app
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
Function .onInstSuccess
|
||||
Call CheckWindowsServPack # Warn if not on the latest SP before asking to launch.
|
||||
Push $0
|
||||
FileOpen $0 "$INSTDIR\InstallMode.txt" w
|
||||
# No newline -- this is for our use, not for users to read.
|
||||
FileWrite $0 "$MultiUser.InstallMode"
|
||||
FileClose $0
|
||||
Pop $0
|
||||
# <FS:Ansariel> Disable VMP
|
||||
#Push $R0
|
||||
#Push $0
|
||||
|
|
@ -777,31 +836,42 @@ Call CheckWindowsServPack # Warn if not on the latest SP before asking to launc
|
|||
#Pop $0
|
||||
#Pop $R0
|
||||
# </FS:Ansariel>
|
||||
Push $R0 # Option value, unused#
|
||||
# <FS:PP> Disable autorun
|
||||
# StrCmp $SKIP_AUTORUN "true" +2;
|
||||
# Assumes SetOutPath $INSTDIR
|
||||
# Exec '"$WINDIR\explorer.exe" "$INSTDIR\$INSTEXE"'
|
||||
# Pop $R0
|
||||
StrCmp $SKIP_DIALOGS "true" label_launch
|
||||
|
||||
${GetOptions} $COMMANDLINE "/AUTOSTART" $R0
|
||||
# If parameter was there (no error) just launch
|
||||
# Otherwise ask
|
||||
IfErrors label_ask_launch label_launch
|
||||
Call CheckWindowsServPack # Warn if not on the latest SP before asking to launch.
|
||||
# <FS:PP> Disable autorun
|
||||
#StrCmp $SKIP_AUTORUN "true" +2;
|
||||
StrCmp $SKIP_DIALOGS "true" label_launch
|
||||
|
||||
${GetOptions} $COMMANDLINE "/AUTOSTART" $R0
|
||||
# If parameter was there (no error) just launch
|
||||
# Otherwise ask
|
||||
IfErrors label_ask_launch label_launch
|
||||
|
||||
label_ask_launch:
|
||||
# Don't launch by default when silent
|
||||
IfSilent label_no_launch
|
||||
MessageBox MB_YESNO $(InstSuccesssQuestion) \
|
||||
IDYES label_launch IDNO label_no_launch
|
||||
# Don't launch by default when silent
|
||||
IfSilent label_no_launch
|
||||
MessageBox MB_YESNO $(InstSuccesssQuestion) IDYES label_launch IDNO label_no_launch
|
||||
|
||||
label_launch:
|
||||
# Assumes SetOutPath $INSTDIR
|
||||
Exec '"$WINDIR\explorer.exe" "$INSTDIR\$INSTSHORTCUT.lnk"'
|
||||
# Assumes SetOutPath $INSTDIR
|
||||
# Run INSTEXE (our updater), passing VIEWER_EXE plus the command-line
|
||||
# arguments built into our shortcuts. This gives the updater a chance
|
||||
# to verify that the viewer we just installed is appropriate for the
|
||||
# running system -- or, if not, to download and install a different
|
||||
# viewer. For instance, if a user running 32-bit Windows installs a
|
||||
# 64-bit viewer, it cannot run on this system. But since the updater
|
||||
# is a 32-bit executable even in the 64-bit viewer package, the
|
||||
# updater can detect the problem and adapt accordingly.
|
||||
# Once everything is in order, the updater will run the specified
|
||||
# viewer with the specified params.
|
||||
# Quote the updater executable and the viewer executable because each
|
||||
# must be a distinct command-line token, but DO NOT quote the language
|
||||
# string because it must decompose into separate command-line tokens.
|
||||
# <FS:Ansariel> No updater, thanks!
|
||||
# Exec '"$INSTDIR\$INSTEXE" precheck "$INSTDIR\$VIEWER_EXE" $SHORTCUT_LANG_PARAM'
|
||||
Exec '"$WINDIR\explorer.exe" "$INSTDIR\$INSTSHORTCUT.lnk"'
|
||||
label_no_launch:
|
||||
Pop $R0
|
||||
# </FS:PP>
|
||||
# </FS:PP>
|
||||
FunctionEnd
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
@ -837,10 +907,10 @@ FunctionEnd
|
|||
; StrCpy $0 0 # Index number used to iterate via EnumRegKey
|
||||
;
|
||||
; LOOP:
|
||||
; EnumRegKey $1 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" $0
|
||||
; EnumRegKey $1 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList" $0
|
||||
; StrCmp $1 "" DONE # no more users
|
||||
;
|
||||
; ReadRegStr $2 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\$1" "ProfileImagePath"
|
||||
; ReadRegStr $2 SHELL_CONTEXT "${MSNTCURRVER_KEY}\ProfileList\$1" "ProfileImagePath"
|
||||
; StrCmp $2 "" CONTINUE 0 # "ProfileImagePath" value is missing
|
||||
;
|
||||
;# Required since ProfileImagePath is of type REG_EXPAND_SZ
|
||||
|
|
@ -859,7 +929,7 @@ FunctionEnd
|
|||
;
|
||||
;# Copy files in Documents and Settings\All Users\SecondLife
|
||||
;Push $0
|
||||
; ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" "Common AppData"
|
||||
; ReadRegStr $0 SHELL_CONTEXT "${MSCURRVER_KEY}\Explorer\Shell Folders" "Common AppData"
|
||||
; StrCmp $0 "" +2
|
||||
; RMDir /r "$2\Application Data\SecondLife\"
|
||||
;Pop $0
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -20,9 +20,6 @@ exportMutliArchDRIPath() {
|
|||
## These options are for self-assisted troubleshooting during this beta
|
||||
## testing phase; you should not usually need to touch them.
|
||||
|
||||
## AO: TCMALLOC Tuning as suggested by Henri Beauchamp for more aggressive garbage collection
|
||||
export TCMALLOC_RELEASE_RATE=10000
|
||||
|
||||
## - Avoids using any FMOD Ex audio driver.
|
||||
#export LL_BAD_FMODEX_DRIVER=x
|
||||
|
||||
|
|
@ -123,23 +120,6 @@ test -x ./etc/register_secondlifeprotocol.sh && ./etc/register_secondlifeprotoco
|
|||
## subprocesses that care.
|
||||
export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
|
||||
|
||||
# if [ -n "$LL_TCMALLOC" ]; then
|
||||
# tcmalloc_libs='/usr/lib/libtcmalloc.so.0 /usr/lib/libstacktrace.so.0 /lib/libpthread.so.0'
|
||||
# all=1
|
||||
# for f in $tcmalloc_libs; do
|
||||
# if [ ! -f $f ]; then
|
||||
# all=0
|
||||
# fi
|
||||
# done
|
||||
# if [ $all != 1 ]; then
|
||||
# echo 'Cannot use tcmalloc libraries: components missing' 1>&2
|
||||
# else
|
||||
# export LD_PRELOAD=$(echo $tcmalloc_libs | tr ' ' :)
|
||||
# if [ -z "$HEAPCHECK" -a -z "$HEAPPROFILE" ]; then
|
||||
# export HEAPCHECK=${HEAPCHECK:-normal}
|
||||
# fi
|
||||
# fi
|
||||
#fi
|
||||
|
||||
if ! test -f FS_No_LD_Hacks.txt; then
|
||||
|
||||
|
|
@ -158,10 +138,16 @@ if [ -f ${LLSSL} ]
|
|||
then
|
||||
export LD_PRELOAD="${LD_PRELOAD}:${LLSSL}"
|
||||
fi
|
||||
# <FS:ND> End of hack; God will kill a kitten for this :(
|
||||
|
||||
fi
|
||||
|
||||
FSJEMALLOC="$(pwd)/lib/libjemalloc.so"
|
||||
if [ -f ${FSJEMALLOC} ]
|
||||
then
|
||||
echo "Using jemalloc"
|
||||
export LD_PRELOAD="${LD_PRELOAD}:${FSJEMALLOC}"
|
||||
fi
|
||||
|
||||
export FS_CEF_PRELOAD="libcef.so"
|
||||
|
||||
# Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch.
|
||||
|
|
|
|||
|
|
@ -25,7 +25,16 @@
|
|||
*/
|
||||
|
||||
#import "llappdelegate-objc.h"
|
||||
#if defined(LL_BUGSPLAT)
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <vector>
|
||||
@import BugsplatMac;
|
||||
// derived from BugsplatMac's BugsplatTester/AppDelegate.m
|
||||
@interface LLAppDelegate () <BugsplatStartupManagerDelegate>
|
||||
@end
|
||||
#endif
|
||||
#include "llwindowmacosx-objc.h"
|
||||
#include "llappviewermacosx-for-objc.h"
|
||||
#include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported)
|
||||
|
||||
// [Cinder] We need to override sendEvent in NSApplication and force those
|
||||
|
|
@ -62,6 +71,25 @@
|
|||
|
||||
- (void) applicationDidFinishLaunching:(NSNotification *)notification
|
||||
{
|
||||
// Call constructViewer() first so our logging subsystem is in place. This
|
||||
// risks missing crashes in the LLAppViewerMacOSX constructor, but for
|
||||
// present purposes it's more important to get the startup sequence
|
||||
// properly logged.
|
||||
// Someday I would like to modify the logging system so that calls before
|
||||
// it's initialized are cached in a std::ostringstream and then, once it's
|
||||
// initialized, "played back" into whatever handlers have been set up.
|
||||
constructViewer();
|
||||
|
||||
#if defined(LL_BUGSPLAT)
|
||||
// Engage BugsplatStartupManager *before* calling initViewer() to handle
|
||||
// any crashes during initialization.
|
||||
// https://www.bugsplat.com/docs/platforms/os-x#initialization
|
||||
[BugsplatStartupManager sharedManager].autoSubmitCrashReport = YES;
|
||||
[BugsplatStartupManager sharedManager].askUserDetails = NO;
|
||||
[BugsplatStartupManager sharedManager].delegate = self;
|
||||
[[BugsplatStartupManager sharedManager] start];
|
||||
#endif
|
||||
|
||||
frameTimer = nil;
|
||||
|
||||
[self languageUpdated];
|
||||
|
|
@ -196,4 +224,138 @@
|
|||
return ret;
|
||||
}
|
||||
|
||||
#if defined(LL_BUGSPLAT)
|
||||
|
||||
- (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
{
|
||||
CrashMetadata& meta(CrashMetadata_instance());
|
||||
// As of BugsplatMac 1.0.6, userName and userEmail properties are now
|
||||
// exposed by the BugsplatStartupManager. Set them here, since the
|
||||
// defaultUserNameForBugsplatStartupManager and
|
||||
// defaultUserEmailForBugsplatStartupManager methods are called later, for
|
||||
// the *current* run, rather than for the previous crashed run whose crash
|
||||
// report we are about to send.
|
||||
infos("applicationLogForBugsplatStartupManager setting userName = '" +
|
||||
meta.agentFullname + '"');
|
||||
bugsplatStartupManager.userName =
|
||||
[NSString stringWithCString:meta.agentFullname.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
// Use the email field for OS version, just as we do on Windows, until
|
||||
// BugSplat provides more metadata fields.
|
||||
infos("applicationLogForBugsplatStartupManager setting userEmail = '" +
|
||||
meta.OSInfo + '"');
|
||||
bugsplatStartupManager.userEmail =
|
||||
[NSString stringWithCString:meta.OSInfo.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
// This strangely-named override method's return value contributes the
|
||||
// User Description metadata field.
|
||||
infos("applicationLogForBugsplatStartupManager -> '" + meta.fatalMessage + "'");
|
||||
return [NSString stringWithCString:meta.fatalMessage.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSString *)applicationKeyForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager signal:(NSString *)signal exceptionName:(NSString *)exceptionName exceptionReason:(NSString *)exceptionReason {
|
||||
// TODO: exceptionName, exceptionReason
|
||||
|
||||
// Windows sends location within region as well, but that's because
|
||||
// BugSplat for Windows intercepts crashes during the same run, and that
|
||||
// information can be queried once. On the Mac, any metadata we have is
|
||||
// written (and rewritten) to the static_debug_info.log file that we read
|
||||
// at the start of the next viewer run. It seems ridiculously expensive to
|
||||
// rewrite that file on every frame in which the avatar moves.
|
||||
std::string regionName(CrashMetadata_instance().regionName);
|
||||
infos("applicationKeyForBugsplatStartupManager -> '" + regionName + "'");
|
||||
return [NSString stringWithCString:regionName.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSString *)defaultUserNameForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
|
||||
std::string agentFullname(CrashMetadata_instance().agentFullname);
|
||||
infos("defaultUserNameForBugsplatStartupManager -> '" + agentFullname + "'");
|
||||
return [NSString stringWithCString:agentFullname.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (NSString *)defaultUserEmailForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
|
||||
// Use the email field for OS version, just as we do on Windows, until
|
||||
// BugSplat provides more metadata fields.
|
||||
std::string OSInfo(CrashMetadata_instance().OSInfo);
|
||||
infos("defaultUserEmailForBugsplatStartupManager -> '" + OSInfo + "'");
|
||||
return [NSString stringWithCString:OSInfo.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
- (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
{
|
||||
infos("bugsplatStartupManagerWillSendCrashReport");
|
||||
}
|
||||
|
||||
struct AttachmentInfo
|
||||
{
|
||||
AttachmentInfo(const std::string& path, const std::string& type):
|
||||
pathname(path),
|
||||
basename(boost::filesystem::path(path).filename().string()),
|
||||
mimetype(type)
|
||||
{}
|
||||
|
||||
std::string pathname, basename, mimetype;
|
||||
};
|
||||
|
||||
- (NSArray<BugsplatAttachment *> *)attachmentsForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
{
|
||||
const CrashMetadata& metadata(CrashMetadata_instance());
|
||||
|
||||
// Since we must do very similar processing for each of several file
|
||||
// pathnames, start by collecting them into a vector so we can iterate
|
||||
// instead of spelling out the logic for each.
|
||||
std::vector<AttachmentInfo> info{
|
||||
AttachmentInfo(metadata.logFilePathname, "text/plain"),
|
||||
AttachmentInfo(metadata.userSettingsPathname, "text/xml"),
|
||||
AttachmentInfo(metadata.staticDebugPathname, "text/xml")
|
||||
};
|
||||
|
||||
// We "happen to know" that info[0].basename is "SecondLife.old" -- due to
|
||||
// the fact that BugsplatMac only notices a crash during the viewer run
|
||||
// following the crash. Replace .old with .log to reduce confusion.
|
||||
info[0].basename =
|
||||
boost::filesystem::path(info[0].pathname).stem().string() + ".log";
|
||||
|
||||
NSMutableArray *attachments = [[NSMutableArray alloc] init];
|
||||
|
||||
// Iterate over each AttachmentInfo in info vector
|
||||
for (const AttachmentInfo& attach : info)
|
||||
{
|
||||
NSString *nspathname = [NSString stringWithCString:attach.pathname.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSString *nsbasename = [NSString stringWithCString:attach.basename.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSString *nsmimetype = [NSString stringWithCString:attach.mimetype.c_str()
|
||||
encoding:NSUTF8StringEncoding];
|
||||
NSData *nsdata = [NSData dataWithContentsOfFile:nspathname];
|
||||
|
||||
BugsplatAttachment *attachment =
|
||||
[[BugsplatAttachment alloc] initWithFilename:nsbasename
|
||||
attachmentData:nsdata
|
||||
contentType:nsmimetype];
|
||||
|
||||
[attachments addObject:attachment];
|
||||
infos("attachmentsForBugsplatStartupManager attaching " + attach.pathname);
|
||||
}
|
||||
|
||||
return attachments;
|
||||
}
|
||||
|
||||
- (void)bugsplatStartupManagerDidFinishSendingCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
|
||||
{
|
||||
infos("Sent crash report to BugSplat");
|
||||
}
|
||||
|
||||
- (void)bugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager didFailWithError:(NSError *)error
|
||||
{
|
||||
// TODO: message string from NSError
|
||||
infos("Could not send crash report to BugSplat");
|
||||
}
|
||||
|
||||
#endif // LL_BUGSPLAT
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -797,6 +797,22 @@ LLAppViewer::LLAppViewer()
|
|||
//
|
||||
|
||||
LLLoginInstance::instance().setPlatformInfo(gPlatform, LLOSInfo::instance().getOSVersionString(), LLOSInfo::instance().getOSStringSimple());
|
||||
|
||||
// Under some circumstances we want to read the static_debug_info.log file
|
||||
// from the previous viewer run between this constructor call and the
|
||||
// init() call, which will overwrite the static_debug_info.log file for
|
||||
// THIS run. So setDebugFileNames() early.
|
||||
#if LL_BUGSPLAT
|
||||
// MAINT-8917: don't create a dump directory just for the
|
||||
// static_debug_info.log file
|
||||
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "");
|
||||
#else // ! LL_BUGSPLAT
|
||||
// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
|
||||
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
|
||||
#endif // ! LL_BUGSPLAT
|
||||
mDumpPath = logdir;
|
||||
setMiniDumpDir(logdir);
|
||||
setDebugFileNames(logdir);
|
||||
}
|
||||
|
||||
LLAppViewer::~LLAppViewer()
|
||||
|
|
@ -968,13 +984,6 @@ bool LLAppViewer::init()
|
|||
initMaxHeapSize() ;
|
||||
LLCoros::instance().setStackSize(gSavedSettings.getS32("CoroutineStackSize"));
|
||||
|
||||
// write Google Breakpad minidump files to a per-run dump directory to avoid multiple viewer issues.
|
||||
std::string logdir = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "");
|
||||
mDumpPath = logdir;
|
||||
setMiniDumpDir(logdir);
|
||||
logdir += gDirUtilp->getDirDelimiter();
|
||||
setDebugFileNames(logdir);
|
||||
|
||||
|
||||
// Although initLoggingAndGetLastDuration() is the right place to mess with
|
||||
// setFatalFunction(), we can't query gSavedSettings until after
|
||||
|
|
@ -1070,11 +1079,6 @@ bool LLAppViewer::init()
|
|||
mNumSessions++;
|
||||
gSavedSettings.setS32("NumSessions", mNumSessions);
|
||||
|
||||
if (gSavedSettings.getBOOL("VerboseLogs"))
|
||||
{
|
||||
LLError::setPrintLocation(true);
|
||||
}
|
||||
|
||||
// LLKeyboard relies on LLUI to know what some accelerator keys are called.
|
||||
LLKeyboard::setStringTranslatorFunc( LLTrans::getKeyboardString );
|
||||
|
||||
|
|
@ -1285,28 +1289,6 @@ bool LLAppViewer::init()
|
|||
}
|
||||
}
|
||||
|
||||
// do not pester devs who need to run the executable directly to debug
|
||||
#if LL_RELEASE_FOR_DOWNLOAD
|
||||
// MAINT-8305: If we're processing a SLURL, skip the launcher check.
|
||||
// <FS:Ansariel> Disable VMP
|
||||
//if (gSavedSettings.getString("CmdLineLoginLocation").empty() && !beingDebugged())
|
||||
//{
|
||||
// const char* PARENT = getenv("PARENT");
|
||||
// if (! (PARENT && std::string(PARENT) == "SL_Launcher"))
|
||||
// {
|
||||
// // Don't directly run this executable. Please run the launcher, which
|
||||
// // will run the viewer itself.
|
||||
// // Naturally we do not consider this bulletproof. The point is to
|
||||
// // gently remind a user who *inadvertently* finds him/herself in this
|
||||
// // situation to do things the Right Way. Anyone who intentionally
|
||||
// // bypasses this mechanism needs no reminder that s/he's shooting
|
||||
// // him/herself in the foot.
|
||||
// LLNotificationsUtil::add("RunLauncher");
|
||||
// }
|
||||
//}
|
||||
// </FS:Ansariel>
|
||||
#endif
|
||||
|
||||
#if LL_WINDOWS
|
||||
if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
|
||||
{
|
||||
|
|
@ -1356,6 +1338,36 @@ bool LLAppViewer::init()
|
|||
|
||||
gGLActive = FALSE;
|
||||
|
||||
// <FS:Ansariel> Disable updater
|
||||
// LLProcess::Params updater;
|
||||
// updater.desc = "updater process";
|
||||
// // Because it's the updater, it MUST persist beyond the lifespan of the
|
||||
// // viewer itself.
|
||||
// updater.autokill = false;
|
||||
//#if LL_WINDOWS
|
||||
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker.exe");
|
||||
//#elif LL_DARWIN
|
||||
// // explicitly run the system Python interpreter on SLVersionChecker.py
|
||||
// updater.executable = "python";
|
||||
// updater.args.add(gDirUtilp->add(gDirUtilp->getAppRODataDir(), "updater", "SLVersionChecker.py"));
|
||||
//#else
|
||||
// updater.executable = gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "SLVersionChecker");
|
||||
//#endif
|
||||
// // add LEAP mode command-line argument to whichever of these we selected
|
||||
// updater.args.add("leap");
|
||||
// // UpdaterServiceSettings
|
||||
// updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
|
||||
// // channel
|
||||
// updater.args.add(LLVersionInfo::getChannel());
|
||||
// // testok
|
||||
// updater.args.add(gSavedSettings.getString("UpdaterServiceURL"));
|
||||
// // ForceAddressSize
|
||||
// updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize")));
|
||||
//
|
||||
// // Run the updater. An exception from launching the updater should bother us.
|
||||
// LLLeap::create(updater, true);
|
||||
// </FS:Ansariel>
|
||||
|
||||
// Iterate over --leap command-line options. But this is a bit tricky: if
|
||||
// there's only one, it won't be an array at all.
|
||||
LLSD LeapCommand(gSavedSettings.getLLSD("LeapCommand"));
|
||||
|
|
@ -1991,7 +2003,7 @@ bool LLAppViewer::cleanup()
|
|||
|
||||
release_start_screen(); // just in case
|
||||
|
||||
LLError::logToFixedBuffer(NULL);
|
||||
LLError::logToFixedBuffer(NULL); // stop the fixed buffer recorder
|
||||
|
||||
LL_INFOS() << "Cleaning Up" << LL_ENDL;
|
||||
|
||||
|
|
@ -2588,6 +2600,12 @@ void errorCallback(const std::string &error_string)
|
|||
//Set the ErrorActivated global so we know to create a marker file
|
||||
gLLErrorActivated = true;
|
||||
|
||||
gDebugInfo["FatalMessage"] = error_string;
|
||||
// We're not already crashing -- we simply *intend* to crash. Since we
|
||||
// haven't actually trashed anything yet, we can afford to write the whole
|
||||
// static info file.
|
||||
LLAppViewer::instance()->writeDebugInfo();
|
||||
|
||||
// LLError::crashAndLoop(error_string);
|
||||
// [SL:KB] - Patch: Viewer-Build | Checked: 2010-12-04 (Catznip-2.4)
|
||||
#if !LL_RELEASE_FOR_DOWNLOAD && LL_WINDOWS
|
||||
|
|
@ -3635,14 +3653,11 @@ void LLAppViewer::writeDebugInfo(bool isStatic)
|
|||
? getStaticDebugFile()
|
||||
: getDynamicDebugFile() );
|
||||
|
||||
LL_INFOS() << "Opening debug file " << *debug_filename << LL_ENDL;
|
||||
llofstream out_file(debug_filename->c_str());
|
||||
LL_INFOS() << "Writing debug file " << *debug_filename << LL_ENDL;
|
||||
llofstream out_file(debug_filename->c_str());
|
||||
|
||||
isStatic ? LLSDSerialize::toPrettyXML(gDebugInfo, out_file)
|
||||
: LLSDSerialize::toPrettyXML(gDebugInfo["Dynamic"], out_file);
|
||||
|
||||
|
||||
out_file.close();
|
||||
}
|
||||
|
||||
LLSD LLAppViewer::getViewerInfo() const
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @file llappviewermacosx-for-objc.h
|
||||
* @author Nat Goodspeed
|
||||
* @date 2018-06-15
|
||||
* @brief llappviewermacosx.h publishes the C++ API for
|
||||
* llappviewermacosx.cpp, just as
|
||||
* llappviewermacosx-objc.h publishes the Objective-C++ API for
|
||||
* llappviewermacosx-objc.mm.
|
||||
*
|
||||
* This header is intended to publish for Objective-C++ consumers a
|
||||
* subset of the C++ API presented by llappviewermacosx.cpp. It's a
|
||||
* subset because, if an Objective-C++ consumer were to #include
|
||||
* the full llappviewermacosx.h, we would almost surely run into
|
||||
* trouble due to the discrepancy between Objective-C++'s BOOL versus
|
||||
* classic Microsoft/Linden BOOL.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
|
||||
* Copyright (c) 2018, Linden Research, Inc.
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#if ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H)
|
||||
#define LL_LLAPPVIEWERMACOSX_FOR_OBJC_H
|
||||
|
||||
#include <string>
|
||||
|
||||
void constructViewer();
|
||||
bool initViewer();
|
||||
void handleUrl(const char* url_utf8);
|
||||
bool pumpMainLoop();
|
||||
void handleQuit();
|
||||
void cleanupViewer();
|
||||
void infos(const std::string& message);
|
||||
|
||||
// This struct is malleable; it only serves as a way to convey a number of
|
||||
// fields from llappviewermacosx.cpp's CrashMetadata_instance() function to the
|
||||
// consuming functions in llappdelegate-objc.mm. As long as both those sources
|
||||
// are compiled with this same header, the content and order of CrashMetadata
|
||||
// can change as needed.
|
||||
struct CrashMetadata
|
||||
{
|
||||
std::string logFilePathname;
|
||||
std::string userSettingsPathname;
|
||||
std::string staticDebugPathname;
|
||||
std::string OSInfo;
|
||||
std::string agentFullname;
|
||||
std::string regionName;
|
||||
std::string fatalMessage;
|
||||
};
|
||||
|
||||
CrashMetadata& CrashMetadata_instance();
|
||||
|
||||
#endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */
|
||||
|
|
@ -36,20 +36,25 @@
|
|||
#include "llappviewermacosx-objc.h"
|
||||
|
||||
#include "llappviewermacosx.h"
|
||||
#include "llappviewermacosx-for-objc.h"
|
||||
#include "llwindowmacosx-objc.h"
|
||||
#include "llcommandlineparser.h"
|
||||
#include "llsdserialize.h"
|
||||
|
||||
#include "llviewernetwork.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llmd5.h"
|
||||
#include "llfloaterworldmap.h"
|
||||
#include "llurldispatcher.h"
|
||||
#include "llerrorcontrol.h"
|
||||
#include "llvoavatarself.h" // for gAgentAvatarp->getFullname()
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#ifdef LL_CARBON_CRASH_HANDLER
|
||||
#include <Carbon/Carbon.h>
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <exception>
|
||||
#include <fstream>
|
||||
|
||||
#include "lldir.h"
|
||||
#include <signal.h>
|
||||
|
|
@ -81,7 +86,7 @@ static void exceptionTerminateHandler()
|
|||
gOldTerminateHandler(); // call old terminate() handler
|
||||
}
|
||||
|
||||
bool initViewer()
|
||||
void constructViewer()
|
||||
{
|
||||
// Set the working dir to <bundle>/Contents/Resources
|
||||
if (chdir(gDirUtilp->getAppRODataDir().c_str()) == -1)
|
||||
|
|
@ -97,18 +102,20 @@ bool initViewer()
|
|||
gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
|
||||
|
||||
gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
|
||||
}
|
||||
|
||||
|
||||
bool initViewer()
|
||||
{
|
||||
bool ok = gViewerAppPtr->init();
|
||||
if(!ok)
|
||||
{
|
||||
LL_WARNS() << "Application init failed." << LL_ENDL;
|
||||
}
|
||||
else if (!gHandleSLURL.empty())
|
||||
{
|
||||
dispatchUrl(gHandleSLURL);
|
||||
gHandleSLURL = "";
|
||||
}
|
||||
else if (!gHandleSLURL.empty())
|
||||
{
|
||||
dispatchUrl(gHandleSLURL);
|
||||
gHandleSLURL = "";
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
|
@ -147,6 +154,73 @@ void cleanupViewer()
|
|||
gViewerAppPtr = NULL;
|
||||
}
|
||||
|
||||
// The BugsplatMac API is structured as a number of different method
|
||||
// overrides, each returning a different piece of metadata. But since we
|
||||
// obtain such metadata by opening and parsing a file, it seems ridiculous to
|
||||
// reopen and reparse it for every individual string desired. What we want is
|
||||
// to open and parse the file once, retaining the data for subsequent
|
||||
// requests. That's why this is an LLSingleton.
|
||||
// Another approach would be to provide a function that simply returns
|
||||
// CrashMetadata, storing the struct in LLAppDelegate, but nat doesn't know
|
||||
// enough Objective-C++ to code that. We'd still have to detect which of the
|
||||
// method overrides is called first so that the results are order-insensitive.
|
||||
class CrashMetadataSingleton: public CrashMetadata, public LLSingleton<CrashMetadataSingleton>
|
||||
{
|
||||
LLSINGLETON(CrashMetadataSingleton);
|
||||
|
||||
// convenience method to log each metadata field retrieved by constructor
|
||||
std::string get_metadata(const LLSD& info, const LLSD::String& key) const
|
||||
{
|
||||
std::string data(info[key].asString());
|
||||
LL_INFOS() << " " << key << "='" << data << "'" << LL_ENDL;
|
||||
return data;
|
||||
}
|
||||
};
|
||||
|
||||
// Populate the fields of our public base-class struct.
|
||||
CrashMetadataSingleton::CrashMetadataSingleton()
|
||||
{
|
||||
// Note: we depend on being able to read the static_debug_info.log file
|
||||
// from the *previous* run before we overwrite it with the new one for
|
||||
// *this* run. LLAppViewer initialization must happen in the Right Order.
|
||||
staticDebugPathname = *gViewerAppPtr->getStaticDebugFile();
|
||||
std::ifstream static_file(staticDebugPathname);
|
||||
LLSD info;
|
||||
if (! static_file.is_open())
|
||||
{
|
||||
LL_INFOS() << "Can't open '" << staticDebugPathname
|
||||
<< "'; no metadata about previous run" << LL_ENDL;
|
||||
}
|
||||
else if (! LLSDSerialize::deserialize(info, static_file, LLSDSerialize::SIZE_UNLIMITED))
|
||||
{
|
||||
LL_INFOS() << "Can't parse '" << staticDebugPathname
|
||||
<< "'; no metadata about previous run" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_INFOS() << "Metadata from '" << staticDebugPathname << "':" << LL_ENDL;
|
||||
logFilePathname = get_metadata(info, "SLLog");
|
||||
userSettingsPathname = get_metadata(info, "SettingsFilename");
|
||||
OSInfo = get_metadata(info, "OSInfo");
|
||||
agentFullname = get_metadata(info, "LoginName");
|
||||
// Translate underscores back to spaces
|
||||
LLStringUtil::replaceChar(agentFullname, '_', ' ');
|
||||
regionName = get_metadata(info, "CurrentRegion");
|
||||
fatalMessage = get_metadata(info, "FatalMessage");
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid having to compile all of our LLSingleton machinery in Objective-C++.
|
||||
CrashMetadata& CrashMetadata_instance()
|
||||
{
|
||||
return CrashMetadataSingleton::instance();
|
||||
}
|
||||
|
||||
void infos(const std::string& message)
|
||||
{
|
||||
LL_INFOS() << message << LL_ENDL;
|
||||
}
|
||||
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
// Store off the command line args for use later.
|
||||
|
|
|
|||
|
|
@ -67,8 +67,101 @@
|
|||
#endif
|
||||
|
||||
#include "stringize.h"
|
||||
#include "lldir.h"
|
||||
#include "llerrorcontrol.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <exception>
|
||||
|
||||
// Bugsplat (http://bugsplat.com) crash reporting tool
|
||||
#ifdef LL_BUGSPLAT
|
||||
#include "BugSplat.h"
|
||||
#include "reader.h" // JsonCpp
|
||||
#include "llagent.h" // for agent location
|
||||
#include "llviewerregion.h"
|
||||
#include "llvoavatarself.h" // for agent name
|
||||
|
||||
namespace
|
||||
{
|
||||
// MiniDmpSender's constructor is defined to accept __wchar_t* instead of
|
||||
// plain wchar_t*. That said, wunder() returns std::basic_string<__wchar_t>,
|
||||
// NOT plain __wchar_t*, despite the apparent convenience. Calling
|
||||
// wunder(something).c_str() as an argument expression is fine: that
|
||||
// std::basic_string instance will survive until the function returns.
|
||||
// Calling c_str() on a std::basic_string local to wunder() would be
|
||||
// Undefined Behavior: we'd be left with a pointer into a destroyed
|
||||
// std::basic_string instance. But we can do that with a macro...
|
||||
#define WCSTR(string) wunder(string).c_str()
|
||||
|
||||
// It would be nice if, when wchar_t is the same as __wchar_t, this whole
|
||||
// function would optimize away. However, we use it only for the arguments
|
||||
// to the BugSplat API -- a handful of calls.
|
||||
inline std::basic_string<__wchar_t> wunder(const std::wstring& str)
|
||||
{
|
||||
return { str.begin(), str.end() };
|
||||
}
|
||||
|
||||
// when what we have in hand is a std::string, convert from UTF-8 using
|
||||
// specific wstringize() overload
|
||||
inline std::basic_string<__wchar_t> wunder(const std::string& str)
|
||||
{
|
||||
return wunder(wstringize(str));
|
||||
}
|
||||
|
||||
// Irritatingly, MiniDmpSender::setCallback() is defined to accept a
|
||||
// classic-C function pointer instead of an arbitrary C++ callable. If it
|
||||
// did accept a modern callable, we could pass a lambda that binds our
|
||||
// MiniDmpSender pointer. As things stand, though, we must define an
|
||||
// actual function and store the pointer statically.
|
||||
static MiniDmpSender *sBugSplatSender = nullptr;
|
||||
|
||||
bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2)
|
||||
{
|
||||
if (nCode == MDSCB_EXCEPTIONCODE)
|
||||
{
|
||||
// send the main viewer log file
|
||||
// widen to wstring, convert to __wchar_t, then pass c_str()
|
||||
sBugSplatSender->sendAdditionalFile(
|
||||
WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log")));
|
||||
|
||||
sBugSplatSender->sendAdditionalFile(
|
||||
WCSTR(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "settings.xml")));
|
||||
|
||||
sBugSplatSender->sendAdditionalFile(
|
||||
WCSTR(*LLAppViewer::instance()->getStaticDebugFile()));
|
||||
|
||||
// We don't have an email address for any user. Hijack this
|
||||
// metadata field for the platform identifier.
|
||||
sBugSplatSender->setDefaultUserEmail(
|
||||
WCSTR(STRINGIZE(LLOSInfo::instance().getOSStringSimple() << " ("
|
||||
<< ADDRESS_SIZE << "-bit)")));
|
||||
|
||||
if (gAgentAvatarp)
|
||||
{
|
||||
// user name, when we have it
|
||||
sBugSplatSender->setDefaultUserName(WCSTR(gAgentAvatarp->getFullname()));
|
||||
}
|
||||
|
||||
// LL_ERRS message, when there is one
|
||||
sBugSplatSender->setDefaultUserDescription(WCSTR(LLError::getFatalMessage()));
|
||||
|
||||
if (gAgent.getRegion())
|
||||
{
|
||||
// region location, when we have it
|
||||
LLVector3 loc = gAgent.getPositionAgent();
|
||||
sBugSplatSender->resetAppIdentifier(
|
||||
WCSTR(STRINGIZE(gAgent.getRegion()->getName()
|
||||
<< '/' << loc.mV[0]
|
||||
<< '/' << loc.mV[1]
|
||||
<< '/' << loc.mV[2])));
|
||||
}
|
||||
} // MDSCB_EXCEPTIONCODE
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif // LL_BUGSPLAT
|
||||
|
||||
namespace
|
||||
{
|
||||
void (*gOldTerminateHandler)() = NULL;
|
||||
|
|
@ -569,15 +662,71 @@ bool LLAppViewerWin32::init()
|
|||
LLWinDebug::instance();
|
||||
#endif
|
||||
|
||||
#if LL_WINDOWS
|
||||
#if LL_SEND_CRASH_REPORTS
|
||||
|
||||
#if ! defined(LL_BUGSPLAT)
|
||||
#pragma message("Building without BugSplat")
|
||||
|
||||
LLAppViewer* pApp = LLAppViewer::instance();
|
||||
pApp->initCrashReporting();
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#else // LL_BUGSPLAT
|
||||
#pragma message("Building with BugSplat")
|
||||
|
||||
std::string build_data_fname(
|
||||
gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, "build_data.json"));
|
||||
// Use llifstream instead of std::ifstream because LL_PATH_EXECUTABLE
|
||||
// could contain non-ASCII characters, which std::ifstream doesn't handle.
|
||||
llifstream inf(build_data_fname.c_str());
|
||||
if (! inf.is_open())
|
||||
{
|
||||
LL_WARNS() << "Can't initialize BugSplat, can't read '" << build_data_fname
|
||||
<< "'" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Json::Reader reader;
|
||||
Json::Value build_data;
|
||||
if (! reader.parse(inf, build_data, false)) // don't collect comments
|
||||
{
|
||||
// gah, the typo is baked into Json::Reader API
|
||||
LL_WARNS() << "Can't initialize BugSplat, can't parse '" << build_data_fname
|
||||
<< "': " << reader.getFormatedErrorMessages() << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
Json::Value BugSplat_DB = build_data["BugSplat DB"];
|
||||
if (! BugSplat_DB)
|
||||
{
|
||||
LL_WARNS() << "Can't initialize BugSplat, no 'BugSplat DB' entry in '"
|
||||
<< build_data_fname << "'" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Got BugSplat_DB, onward!
|
||||
std::wstring version_string(WSTRINGIZE(LL_VIEWER_VERSION_MAJOR << '.' <<
|
||||
LL_VIEWER_VERSION_MINOR << '.' <<
|
||||
LL_VIEWER_VERSION_PATCH << '.' <<
|
||||
LL_VIEWER_VERSION_BUILD));
|
||||
|
||||
// have to convert normal wide strings to strings of __wchar_t
|
||||
sBugSplatSender = new MiniDmpSender(
|
||||
WCSTR(BugSplat_DB.asString()),
|
||||
WCSTR(LL_TO_WSTRING(LL_VIEWER_CHANNEL)),
|
||||
WCSTR(version_string),
|
||||
nullptr, // szAppIdentifier -- set later
|
||||
MDSF_NONINTERACTIVE | // automatically submit report without prompting
|
||||
MDSF_PREVENTHIJACKING); // disallow swiping Exception filter
|
||||
sBugSplatSender->setCallback(bugsplatSendLog);
|
||||
|
||||
// engage stringize() overload that converts from wstring
|
||||
LL_INFOS() << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
|
||||
<< ' ' << stringize(version_string) << ')' << LL_ENDL;
|
||||
} // got BugSplat_DB
|
||||
} // parsed build_data.json
|
||||
} // opened build_data.json
|
||||
|
||||
#endif // LL_BUGSPLAT
|
||||
#endif // LL_SEND_CRASH_REPORTS
|
||||
|
||||
bool success = LLAppViewer::init();
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "llui.h"
|
||||
#include "llprocess.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llstring.h"
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// static
|
||||
|
|
@ -206,12 +207,12 @@ std::string LLExternalEditor::findCommand(
|
|||
cmd = LLUI::sSettingGroups["config"]->getString(sSetting);
|
||||
LL_INFOS() << "Using setting" << LL_ENDL;
|
||||
}
|
||||
else // otherwise use the path specified by the environment variable
|
||||
else // otherwise use the path specified by the environment variable
|
||||
{
|
||||
char* env_var_val = getenv(env_var.c_str());
|
||||
auto env_var_val(LLStringUtil::getoptenv(env_var));
|
||||
if (env_var_val)
|
||||
{
|
||||
cmd = env_var_val;
|
||||
cmd = *env_var_val;
|
||||
LL_INFOS() << "Using env var " << env_var << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -690,7 +690,7 @@ void LLFloaterWorldMap::processParcelInfo(const LLParcelData& parcel_data, const
|
|||
ll_round(region_y),
|
||||
ll_round((F32)pos_global.mdV[VZ]));
|
||||
|
||||
LLTracker::trackLocation(pos_global, parcel_data.name, full_name);
|
||||
LLTracker::trackLocation(pos_global, parcel_data.name.empty() ? getString("UnnamedParcel") : parcel_data.name, full_name);
|
||||
}
|
||||
|
||||
void LLFloaterWorldMap::requestParcelInfo(const LLVector3d& pos_global)
|
||||
|
|
|
|||
|
|
@ -273,14 +273,12 @@ bool LLLoginInstance::handleLoginEvent(const LLSD& event)
|
|||
|
||||
mLoginState = event["state"].asString();
|
||||
mResponseData = event["data"];
|
||||
|
||||
|
||||
if(event.has("transfer_rate"))
|
||||
{
|
||||
mTransferRate = event["transfer_rate"].asReal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Call the method registered in constructor, if any, for more specific
|
||||
// handling
|
||||
mDispatcher.try_call(event);
|
||||
|
|
@ -296,6 +294,14 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
|
|||
// Login has failed.
|
||||
// Figure out why and respond...
|
||||
LLSD response = event["data"];
|
||||
LLSD updater = response["updater"];
|
||||
|
||||
// Always provide a response to the updater, if in fact the updater
|
||||
// contacted us, if in fact the ping contains a 'reply' key. Most code
|
||||
// paths tell it not to proceed with updating.
|
||||
ResponsePtr resp(std::make_shared<LLEventAPI::Response>
|
||||
(LLSDMap("update", false), updater));
|
||||
|
||||
std::string reason_response = response["reason"].asString();
|
||||
std::string message_response = response["message"].asString();
|
||||
LL_DEBUGS("LLLogin") << "reason " << reason_response
|
||||
|
|
@ -347,17 +353,44 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
|
|||
}
|
||||
else if(reason_response == "update")
|
||||
{
|
||||
// This shouldn't happen - the viewer manager should have forced an update;
|
||||
// possibly the user ran the viewer directly and bypassed the update check
|
||||
// This can happen if the user clicked Login quickly, before we heard
|
||||
// back from the Viewer Version Manager, but login failed because
|
||||
// login.cgi is insisting on a required update. We were called with an
|
||||
// event that bundles both the login.cgi 'response' and the
|
||||
// synchronization event from the 'updater'.
|
||||
std::string required_version = response["message_args"]["VERSION"];
|
||||
LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL;
|
||||
|
||||
if (gViewerWindow)
|
||||
gViewerWindow->setShowProgress(FALSE, FALSE);
|
||||
|
||||
LLSD data(LLSD::emptyMap());
|
||||
data["VERSION"] = required_version;
|
||||
LLNotificationsUtil::add("RequiredUpdate", data, LLSD::emptyMap(), boost::bind(&LLLoginInstance::handleLoginDisallowed, this, _1, _2));
|
||||
LLSD args(LLSDMap("VERSION", required_version));
|
||||
if (updater.isUndefined())
|
||||
{
|
||||
// If the updater failed to shake hands, better advise the user to
|
||||
// download the update him/herself.
|
||||
LLNotificationsUtil::add(
|
||||
"RequiredUpdate",
|
||||
args,
|
||||
updater,
|
||||
boost::bind(&LLLoginInstance::handleLoginDisallowed, this, _1, _2));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we've heard from the updater that an update is required,
|
||||
// then display the prompt that assures the user we'll take care
|
||||
// of it. This is the one case in which we bind 'resp':
|
||||
// instead of destroying our Response object (and thus sending a
|
||||
// negative reply to the updater) as soon as we exit this
|
||||
// function, bind our shared_ptr so it gets passed into
|
||||
// syncWithUpdater. That ensures that the response is delayed
|
||||
// until the user has responded to the notification.
|
||||
LLNotificationsUtil::add(
|
||||
"PauseForUpdate",
|
||||
args,
|
||||
updater,
|
||||
boost::bind(&LLLoginInstance::syncWithUpdater, this, resp, _1, _2));
|
||||
}
|
||||
}
|
||||
else if( reason_response == "key"
|
||||
|| reason_response == "presence"
|
||||
|
|
@ -380,6 +413,19 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
|
|||
}
|
||||
}
|
||||
|
||||
void LLLoginInstance::syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LL_INFOS("LLLogin") << "LLLoginInstance::syncWithUpdater" << LL_ENDL;
|
||||
// 'resp' points to an instance of LLEventAPI::Response that will be
|
||||
// destroyed as soon as we return and the notification response functor is
|
||||
// unregistered. Modify it so that it tells the updater to go ahead and
|
||||
// perform the update. Naturally, if we allowed the user a choice as to
|
||||
// whether to proceed or not, this assignment would reflect the user's
|
||||
// selection.
|
||||
(*resp)["update"] = true;
|
||||
attemptComplete();
|
||||
}
|
||||
|
||||
void LLLoginInstance::handleLoginDisallowed(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
attemptComplete();
|
||||
|
|
@ -439,7 +485,6 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
std::string construct_start_string()
|
||||
{
|
||||
std::string start;
|
||||
|
|
|
|||
|
|
@ -28,8 +28,10 @@
|
|||
#define LL_LLLOGININSTANCE_H
|
||||
|
||||
#include "lleventdispatcher.h"
|
||||
#include "lleventapi.h"
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <memory> // std::shared_ptr
|
||||
#include "llsecapi.h"
|
||||
class LLLogin;
|
||||
class LLEventStream;
|
||||
|
|
@ -71,6 +73,7 @@ public:
|
|||
LLNotificationsInterface& getNotificationsInterface() const { return *mNotifications; }
|
||||
|
||||
private:
|
||||
typedef std::shared_ptr<LLEventAPI::Response> ResponsePtr;
|
||||
void constructAuthParams(LLPointer<LLCredential> user_credentials);
|
||||
void updateApp(bool mandatory, const std::string& message);
|
||||
bool updateDialogCallback(const LLSD& notification, const LLSD& response);
|
||||
|
|
@ -80,7 +83,8 @@ private:
|
|||
void handleLoginSuccess(const LLSD& event);
|
||||
void handleDisconnect(const LLSD& event);
|
||||
void handleIndeterminate(const LLSD& event);
|
||||
void handleLoginDisallowed(const LLSD& notification, const LLSD& response);
|
||||
void handleLoginDisallowed(const LLSD& notification, const LLSD& response);
|
||||
void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response);
|
||||
|
||||
bool handleTOSResponse(bool v, const std::string& key);
|
||||
|
||||
|
|
|
|||
|
|
@ -758,8 +758,7 @@ bool idle_startup()
|
|||
if (!found_template)
|
||||
{
|
||||
message_template_path =
|
||||
gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE,
|
||||
"../Resources/app_settings",
|
||||
gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
|
||||
"message_template.msg");
|
||||
found_template = LLFile::fopen(message_template_path.c_str(), "r"); /* Flawfinder: ignore */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1700,7 +1700,25 @@ BOOL LLTextureCtrl::handleUnicodeCharHere(llwchar uni_char)
|
|||
{
|
||||
if( ' ' == uni_char )
|
||||
{
|
||||
showPicker(TRUE);
|
||||
// <FS:Ansariel> Texture preview mode
|
||||
//showPicker(TRUE);
|
||||
if (!mPreviewMode)
|
||||
{
|
||||
showPicker(TRUE);
|
||||
//grab textures first...
|
||||
LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
|
||||
//...then start full inventory fetch.
|
||||
LLInventoryModelBackgroundFetch::instance().start();
|
||||
}
|
||||
else if (!mIsMasked)
|
||||
{
|
||||
// Open the preview floater for the texture
|
||||
LLSD params;
|
||||
params["uuid"] = getValue();
|
||||
params["preview_only"] = TRUE;
|
||||
LLFloaterReg::showInstance("preview_texture", params, TRUE);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
return TRUE;
|
||||
}
|
||||
return LLUICtrl::handleUnicodeCharHere(uni_char);
|
||||
|
|
|
|||
|
|
@ -105,14 +105,11 @@ namespace
|
|||
{
|
||||
// LL_VIEWER_CHANNEL is a macro defined on the compiler command line. The
|
||||
// macro expands to the string name of the channel, but without quotes. We
|
||||
// need to turn it into a quoted string. This macro trick does that.
|
||||
#define stringize_inner(x) #x
|
||||
#define stringize_outer(x) stringize_inner(x)
|
||||
|
||||
// need to turn it into a quoted string. LL_TO_STRING() does that.
|
||||
/// Storage of the channel name the viewer is using.
|
||||
// The channel name is set by hardcoded constant,
|
||||
// or by calling LLVersionInfo::resetChannel()
|
||||
std::string sWorkingChannelName(stringize_outer(LL_VIEWER_CHANNEL));
|
||||
std::string sWorkingChannelName(LL_TO_STRING(LL_VIEWER_CHANNEL));
|
||||
|
||||
// Storage for the "version and channel" string.
|
||||
// This will get reset too.
|
||||
|
|
|
|||
|
|
@ -472,7 +472,10 @@ void LLViewerAssetStorage::assetRequestCoro(
|
|||
LL_WARNS_ONCE("ViewerAsset") << "capsRecv got event" << LL_ENDL;
|
||||
LL_WARNS_ONCE("ViewerAsset") << "region " << gAgent.getRegion() << " mViewerAssetUrl " << mViewerAssetUrl << LL_ENDL;
|
||||
}
|
||||
if (mViewerAssetUrl.empty() && gAgent.getRegion())
|
||||
// <FS:Beq> FIRE-23657 [OPENSIM] Update the Viewer Asset Url irrespective of previous setting (Fix provided by Liru Færs)
|
||||
// if (mViewerAssetUrl.empty() && gAgent.getRegion())
|
||||
if (gAgent.getRegion())
|
||||
// </FS:Beq>
|
||||
{
|
||||
mViewerAssetUrl = gAgent.getRegion()->getViewerAssetUrl();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2507,7 +2507,7 @@ LLUUID find_possible_item_for_regeneration(const LLViewerInventoryItem *target_i
|
|||
++item_iter)
|
||||
{
|
||||
const LLViewerInventoryItem *item = (*item_iter);
|
||||
if (true) return item->getUUID();
|
||||
if (item) return item->getUUID();
|
||||
}
|
||||
return LLUUID::null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -144,7 +144,10 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
|
|||
for (child_list_t::iterator iter = mChildren.begin();
|
||||
iter != mChildren.end(); ++iter)
|
||||
{
|
||||
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
|
||||
// LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
|
||||
// [SL:KB] - Patch: Viewer-OptimizationAnimesh | Checked: Catznip-6.0
|
||||
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
|
||||
// [/SL:KB]
|
||||
F32 jointLOD = joint->getLOD();
|
||||
if (pixelArea >= jointLOD || sDisableLOD)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2304,7 +2304,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
|
|||
{
|
||||
// <FS:Ansariel> This breaks object owner name parsing
|
||||
//log_message = "<nolink>" + chatHistory_string + "</nolink> " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString(".");
|
||||
log_message = chatHistory_string + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString(".");
|
||||
log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + getSanitizedDescription() + LLTrans::getString(".");
|
||||
// </FS:Ansariel>
|
||||
LLSD args;
|
||||
args["MESSAGE"] = log_message;
|
||||
|
|
|
|||
|
|
@ -1061,7 +1061,7 @@ void LLViewerObjectList::update(LLAgent &agent)
|
|||
objectp = *idle_iter;
|
||||
llassert(objectp->isActive());
|
||||
objectp->idleUpdate(agent, frame_time);
|
||||
}
|
||||
}
|
||||
|
||||
//update flexible objects
|
||||
LLVolumeImplFlexible::updateClass();
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#include "llagent.h"
|
||||
#include "llagentcamera.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llavatarrenderinfoaccountant.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llcommandhandler.h"
|
||||
|
|
@ -114,6 +115,18 @@ typedef std::map<std::string, std::string> CapabilityMap;
|
|||
|
||||
static void log_capabilities(const CapabilityMap &capmap);
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
void newRegionEntry(LLViewerRegion& region)
|
||||
{
|
||||
LL_INFOS("LLViewerRegion") << "Entering region [" << region.getName() << "]" << LL_ENDL;
|
||||
gDebugInfo["CurrentRegion"] = region.getName();
|
||||
LLAppViewer::instance()->writeDebugInfo();
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// support for secondlife:///app/region/{REGION} SLapps
|
||||
// N.B. this is defined to work exactly like the classic secondlife://{REGION}
|
||||
// However, the later syntax cannot support spaces in the region name because
|
||||
|
|
@ -261,6 +274,9 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
|
|||
return; // this error condition is not recoverable.
|
||||
}
|
||||
|
||||
// record that we just entered a new region
|
||||
newRegionEntry(*regionp);
|
||||
|
||||
// After a few attempts, continue login. But keep trying to get the caps:
|
||||
if (mSeedCapAttempts >= mSeedCapMaxAttemptsBeforeLogin &&
|
||||
STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
|
||||
|
|
@ -384,6 +400,9 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCompleteCoro(U64 regionHandle)
|
|||
break; // this error condition is not recoverable.
|
||||
}
|
||||
|
||||
// record that we just entered a new region
|
||||
newRegionEntry(*regionp);
|
||||
|
||||
LLSD capabilityNames = LLSD::emptyArray();
|
||||
buildCapabilityNames(capabilityNames);
|
||||
|
||||
|
|
|
|||
|
|
@ -332,6 +332,9 @@ private:
|
|||
RecordToChatConsole::RecordToChatConsole():
|
||||
mRecorder(new RecordToChatConsoleRecorder())
|
||||
{
|
||||
mRecorder->showTags(false);
|
||||
mRecorder->showLocation(false);
|
||||
mRecorder->showMultiline(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue