Merge viewer-bugsplat

master
Ansariel 2018-07-27 11:19:42 +02:00
commit 0f121d042d
25 changed files with 864 additions and 325 deletions

View File

@ -429,6 +429,60 @@
<key>version</key>
<string>1.57</string>
</map>
<key>bugsplat</key>
<map>
<key>copyright</key>
<string>Copyright 2003-2017, BugSplat</string>
<key>description</key>
<string>Bugsplat crash reporting package</string>
<key>license</key>
<string>Proprietary</string>
<key>license_file</key>
<string>LICENSES/BUGSPLAT_LICENSE.txt</string>
<key>name</key>
<string>bugsplat</string>
<key>platforms</key>
<map>
<key>darwin64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>0da51341172a14f06c323e240dd238f5</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21954/163369/bugsplat-1.0.2.517972-darwin64-517972.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
</map>
<key>windows</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>d25adf0f2bcdbf59c035def0914fa1d5</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21955/163376/bugsplat-3.6.0.4.517972-windows-517972.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
</map>
<key>windows64</key>
<map>
<key>archive</key>
<map>
<key>hash</key>
<string>0a4fc1ddec4ea0ad2d75d5422ef1df2b</string>
<key>url</key>
<string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/21953/163362/bugsplat-3.6.0.4.517972-windows64-517972.tar.bz2</string>
</map>
<key>name</key>
<string>windows64</string>
</map>
</map>
<key>version</key>
<string>1.0.2.517972</string>
</map>
<key>chardet</key>
<map>
<key>copyright</key>
@ -3566,9 +3620,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>86f6708f393c162cd4f92426b0a3cde7</string>
<string>78e3b5f51554a186f8a62c0161f549d5</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/15341/99062/viewer_manager-1.0.513570-darwin64-513570.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21002/152053/viewer_manager-1.0.517331-darwin64-517331.tar.bz2</string>
</map>
<key>name</key>
<string>darwin64</string>
@ -3602,9 +3656,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>archive</key>
<map>
<key>hash</key>
<string>c4dec51062ad78c09b11f7432aff4d1d</string>
<string>ccf1e6ba7811897f7d88af2a6fddceb0</string>
<key>url</key>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/17857/121832/viewer_manager-1.0.515286-windows-515286.tar.bz2</string>
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/21003/152060/viewer_manager-1.0.517331-windows-517331.tar.bz2</string>
</map>
<key>name</key>
<string>windows</string>
@ -3615,7 +3669,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
<key>source_type</key>
<string>hg</string>
<key>version</key>
<string>1.0.515286</string>
<string>1.0.517331</string>
</map>
<key>vlc-bin</key>
<map>

View File

@ -95,26 +95,36 @@ 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" ]
then
if [ "$variant" == "Release" ]
then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
"-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
if [ "$arch" == "Darwin" -a "$variant" == "Release" ]
then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
"-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
fi
# don't spew credentials into build log
bugsplat_sh="$build_secrets_checkout/bugsplat/bugsplat.sh"
set +x
# HACK: Suppress for Mac until BugSplat fixes the Mac client API
if [ -r "$bugsplat_sh" -a "$arch" != "Darwin" ]
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_CHANNEL:STRING="${viewer_channel}" \
-DGRID:STRING="\"$viewer_grid\"" \
-DLL_TESTS:BOOL="$run_tests" \
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
"${SIGNING[@]}" \
|| fatal "$variant configuration failed"
@ -194,6 +204,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"
@ -412,7 +424,9 @@ then
if [ "$last_built_variant" = "Release" ]
then
# nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file.
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
# Likewise, BUGSPLAT_DB suppresses generating the symbol file.
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" \
-a -z "${BUGSPLAT_DB:-}" ]
then
# Upload crash reporter file
# These names must match the set of VIEWER_SYMBOL_FILE in indra/newview/CMakeLists.txt

View File

@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES
Audio.cmake
BerkeleyDB.cmake
Boost.cmake
bugsplat.cmake
BuildVersion.cmake
CEFPlugin.cmake
CMakeCopyIfDifferent.cmake

View File

@ -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 (DEFINED ENV{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 (DEFINED ENV{BUGSPLAT_DB})
set(release_files ${release_files} growl++.dll growl.dll )
if (FMODSTUDIO)
if(ADDRESS_SIZE EQUAL 32)

View File

@ -213,7 +213,6 @@ 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(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

View File

@ -0,0 +1,26 @@
# BugSplat is engaged by setting environment variable BUGSPLAT_DB to the
# target BugSplat database name prior to running CMake (and during autobuild
# build).
if (DEFINED ENV{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 (DEFINED ENV{BUGSPLAT_DB})

View File

@ -379,7 +379,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 +389,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 +417,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 +485,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
@ -628,7 +651,6 @@ class LLManifest(object):
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)
@ -696,7 +718,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 +732,7 @@ class LLManifest(object):
if err.errno != errno.ENOENT:
raise
## print "{} => {}".format(src, reldst)
shutil.copy2(src, dst)
def ccopytree(self, src, dst):

View File

@ -211,4 +211,3 @@ void LLLocalTextureObject::setBakedReady(BOOL ready)
{
mIsBakedReady = ready;
}

View File

@ -281,6 +281,11 @@ list(APPEND llcommon_HEADER_FILES "tea.h" )
set_source_files_properties(${llcommon_HEADER_FILES}
PROPERTIES HEADER_FILE_ONLY TRUE)
if (DEFINED ENV{BUGSPLAT_DB})
set_source_files_properties(llapp.cpp
PROPERTIES COMPILE_DEFINITIONS "LL_BUGSPLAT")
endif (DEFINED ENV{BUGSPLAT_DB})
list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
if(LLCOMMON_LINK_SHARED)

View File

@ -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();
}

View File

@ -375,6 +375,7 @@ namespace
public:
std::ostringstream messageStream;
bool messageStreamInUse;
std::string mFatalMessage;
void addCallSite(LLError::CallSite&);
void invalidateCallSites();
@ -699,11 +700,16 @@ namespace LLError
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)
{
@ -1182,7 +1188,7 @@ namespace LLError
std::ostringstream prefix;
if( nd::logging::throttle( site.mFile, site.mLine, &prefix ) )
return;
std::ostringstream message_stream;
if (site.mPrintOnce)
@ -1207,14 +1213,19 @@ namespace LLError
s->mUniqueLogMessages[message] = 1;
}
}
message_stream << message;
writeToRecorders(site, message_stream.str());
if (site.mLevel == LEVEL_ERROR && s->mCrashFunction)
std::string message_line(message_stream.str());
writeToRecorders(site, message_line);
if (site.mLevel == LEVEL_ERROR)
{
s->mCrashFunction(message_stream.str());
g->mFatalMessage = message_line;
if (s->mCrashFunction)
{
s->mCrashFunction(message_line);
}
}
}
}

View File

@ -102,6 +102,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

View File

@ -208,6 +208,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)

View File

@ -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) */

View File

@ -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) */

View File

@ -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 (DEFINED ENV{BUGSPLAT_DB})
include(bugsplat)
endif (DEFINED ENV{BUGSPLAT_DB})
include(BuildPackagesInfo)
include(BuildVersion)
include(CMakeCopyIfDifferent)
@ -38,7 +45,6 @@ include(LLUI)
include(LLVFS)
include(LLWindow)
include(LLXML)
include(Linking)
include(NDOF)
include(NVAPI)
include(OPENAL)
@ -110,6 +116,12 @@ include_directories(
${CMAKE_CURRENT_BINARY_DIR}
)
if (DEFINED ENV{BUGSPLAT_DB})
include_directories(
${BUGSPLAT_INCLUDE_DIR}
)
endif (DEFINED ENV{BUGSPLAT_DB})
include_directories(SYSTEM
${LLCOMMON_SYSTEM_INCLUDE_DIRS}
${LLXML_SYSTEM_INCLUDE_DIRS}
@ -1652,6 +1664,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
@ -1678,6 +1698,12 @@ if (DARWIN)
${COREAUDIO_LIBRARY}
)
if (DEFINED ENV{BUGSPLAT_DB})
list(APPEND viewer_LIBRARIES
${BUGSPLAT_LIBRARIES}
)
endif (DEFINED ENV{BUGSPLAT_DB})
# Add resource files to the project.
set(viewer_RESOURCE_FILES
firestorm_icon.icns
@ -1703,6 +1729,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)
@ -1737,6 +1768,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
@ -2075,6 +2111,11 @@ if (SDL_FOUND)
)
endif (SDL_FOUND)
if (DEFINED ENV{BUGSPLAT_DB})
set_property(TARGET ${VIEWER_BINARY_NAME}
PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT")
endif (DEFINED ENV{BUGSPLAT_DB})
# add package files
file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@ -2232,21 +2273,6 @@ if (WINDOWS)
windows-crash-logger
)
# sets the 'working directory' for debugging from visual studio.
if (NOT UNATTENDED)
add_custom_command(
TARGET ${VIEWER_BINARY_NAME} POST_BUILD
COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
ARGS
--solution
${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
--workingdir
${VIEWER_BINARY_NAME}
"${CMAKE_CURRENT_SOURCE_DIR}"
COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging."
)
endif (NOT UNATTENDED)
if (PACKAGE)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/event_host.tar.bz2
@ -2309,8 +2335,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
@ -2384,6 +2410,12 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${LLAPPEARANCE_LIBRARIES}
${GROWL_LIBRARY}
)
if (DEFINED ENV{BUGSPLAT_DB})
target_link_libraries(${VIEWER_BINARY_NAME}
${BUGSPLAT_LIBRARIES}
)
endif (DEFINED ENV{BUGSPLAT_DB})
if (WINDOWS)
target_link_libraries(${VIEWER_BINARY_NAME}
@ -2479,25 +2511,35 @@ endif (NOT ENABLE_MEDIA_PLUGINS)
endif (LINUX)
if (DARWIN)
# These all get set with PROPERTIES
set(product "Firestorm")
# 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}")
# 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")
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-2018 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"
@ -2573,7 +2615,7 @@ if (INSTALL)
include(${CMAKE_CURRENT_SOURCE_DIR}/ViewerInstall.cmake)
endif (INSTALL)
if (PACKAGE)
if (PACKAGE AND (RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING) AND NOT DEFINED ENV{BUGSPLAT_DB})
set(SYMBOL_SEARCH_DIRS "")
# Note that the path to VIEWER_SYMBOL_FILE must match that in ../../build.sh
if (WINDOWS)
@ -2592,8 +2634,8 @@ if (PACKAGE)
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_EXE_GLOBS "'${product}' SLPlugin mac-crash-logger")
set(VIEWER_EXE_GLOBS "'${product}' mac-crash-logger")
set(VIEWER_LIB_GLOB "*.dylib")
endif (DARWIN)
if (LINUX)
@ -2605,7 +2647,6 @@ if (PACKAGE)
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 ".")
@ -2632,8 +2673,7 @@ if (PACKAGE)
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)
endif ()
if (LL_TESTS)
# To add a viewer unit test, just add the test .cpp file below

View File

@ -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>

View File

@ -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()

View File

@ -25,7 +25,14 @@
*/
#import "llappdelegate-objc.h"
#if defined(LL_BUGSPLAT)
@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
@ -79,6 +86,14 @@
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(languageUpdated) name:@"NSTextInputContextKeyboardSelectionDidChangeNotification" object:nil];
// [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self andSelector:@selector(handleGetURLEvent:withReplyEvent:) forEventClass:kInternetEventClass andEventID:kAEGetURL];
#if defined(LL_BUGSPLAT)
// 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
}
- (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent {
@ -196,4 +211,54 @@
return ret;
}
#if defined(LL_BUGSPLAT)
- (NSString *)applicationLogForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager
{
infos("Reached applicationLogForBugsplatStartupManager");
// Apparently this override method only contributes the User Description
// field of BugSplat's All Crashes table. Despite the method name, it
// would seem to be a bad place to try to stuff all of SecondLife.log.
return [NSString stringWithCString:getFatalMessage().c_str()
encoding:NSUTF8StringEncoding];
}
- (void)bugsplatStartupManagerWillSendCrashReport:(BugsplatStartupManager *)bugsplatStartupManager
{
infos("Reached bugsplatStartupManagerWillSendCrashReport");
}
- (BugsplatAttachment *)attachmentForBugsplatStartupManager:(BugsplatStartupManager *)bugsplatStartupManager {
// We get the *old* log file pathname (for SecondLife.old) because it's on
// the run *following* the crash that BugsplatStartupManager notices that
// the previous run crashed and calls this override. By that time, we've
// already renamed SecondLife.log to SecondLife.old.
std::string logfile = getOldLogFilePathname();
NSString *ns_logfile = [NSString stringWithCString:logfile.c_str()
encoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithContentsOfFile:ns_logfile];
// Apologies for the hard-coded log-file basename, but I do not know the
// incantation for "$(basename "$logfile")" in this language.
BugsplatAttachment *attachment =
[[BugsplatAttachment alloc] initWithFilename:@"SecondLife.log"
attachmentData:data
contentType:@"text/plain"];
infos("attachmentForBugsplatStartupManager: attaching " + logfile);
return attachment;
}
- (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

View File

@ -0,0 +1,37 @@
/**
* @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>
bool initViewer();
void handleUrl(const char* url_utf8);
bool pumpMainLoop();
void handleQuit();
void cleanupViewer();
std::string getOldLogFilePathname();
std::string getFatalMessage();
std::string getAgentFullname();
void infos(const std::string& message);
#endif /* ! defined(LL_LLAPPVIEWERMACOSX_FOR_OBJC_H) */

View File

@ -36,6 +36,7 @@
#include "llappviewermacosx-objc.h"
#include "llappviewermacosx.h"
#include "llappviewermacosx-for-objc.h"
#include "llwindowmacosx-objc.h"
#include "llcommandlineparser.h"
@ -44,6 +45,8 @@
#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>
@ -147,6 +150,26 @@ void cleanupViewer()
gViewerAppPtr = NULL;
}
std::string getOldLogFilePathname()
{
return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.old");
}
std::string getFatalMessage()
{
return LLError::getFatalMessage();
}
std::string getAgentFullname()
{
return gAgentAvatarp? gAgentAvatarp->getFullname() : std::string();
}
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.

View File

@ -67,8 +67,96 @@
#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")));
// We don't have an email address for any user. Hijack this
// metadata field for the platform identifier.
sBugSplatSender->setDefaultUserEmail(WCSTR(STRINGIZE("Windows" << ADDRESS_SIZE)));
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 +657,69 @@ 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"));
std::ifstream 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();

View File

@ -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.

View File

@ -33,10 +33,8 @@
// 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)
#define ll_viewer_channel stringize_outer(LL_VIEWER_CHANNEL)
// need to turn it into a quoted string. LL_TO_STRING() does that.
#define ll_viewer_channel LL_TO_STRING(LL_VIEWER_CHANNEL)
namespace tut
{

View File

@ -26,19 +26,20 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
import sys
import os
import os.path
import shutil
import errno
import json
import os
import os.path
import plistlib
import random
import re
import shutil
import stat
import subprocess
import sys
import tarfile
import time
import zipfile
#<FS:AO>
import shlex
@ -76,7 +77,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
# </FS:LO>
if self.is_packaging_viewer():
with self.prefix(src="app_settings"):
with self.prefix(src_dst="app_settings"):
self.exclude("logcontrol.xml")
self.exclude("logcontrol-dev.xml")
self.path("*.ini")
@ -100,7 +101,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
# <FS:LO> Copy dictionaries to a place where the viewer can find them if ran from visual studio
# ... and the included spell checking dictionaries
# pkgdir = os.path.join(self.args['build'], os.pardir, 'packages')
# with self.prefix(src=pkgdir,dst=""):
# with self.prefix(src=pkgdir):
# self.path("dictionaries")
# </FS:LO>
@ -149,28 +150,28 @@ class ViewerManifest(LLManifest,FSViewerManifest):
src="environment")
with self.prefix(src="character"):
with self.prefix(src_dst="character"):
self.path("*.llm")
self.path("*.xml")
self.path("*.tga")
# Include our fonts
with self.prefix(src="fonts"):
with self.prefix(src_dst="fonts"):
self.path("*.ttf")
self.path("*.txt")
self.path("*.xml")
# <FS:AO> Include firestorm resources
with self.prefix(src="fs_resources"):
with self.prefix(src_dst="fs_resources"):
self.path("*.txt")
self.path("*.lsl")
self.path("*.lsltxt")
# skins
with self.prefix(src="skins"):
with self.prefix(src_dst="skins"):
self.path("skins.xml")
# include the entire textures directory recursively
with self.prefix(src="*/textures"):
with self.prefix(src_dst="*/textures"):
self.path("*/*.tga")
self.path("*/*.j2c")
self.path("*/*.jpg")
@ -208,7 +209,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
# local_assets dir (for pre-cached textures)
with self.prefix(src="local_assets"):
with self.prefix(src_dst="local_assets"):
self.path("*.j2c")
self.path("*.tga")
@ -224,6 +225,11 @@ class ViewerManifest(LLManifest,FSViewerManifest):
"Address Size":self.address_size,
"Update Service":"https://update.secondlife.com/update",
}
try:
build_data_dict["BugSplat DB"] = os.environ["BUGSPLAT_DB"]
except KeyError:
# skip the assignment if there's no BUGSPLAT_DB variable
pass
build_data_dict = self.finish_build_data_dict(build_data_dict)
with open(os.path.join(os.pardir,'build_data.json'), 'w') as build_data_handle:
json.dump(build_data_dict,build_data_handle)
@ -253,8 +259,7 @@ class ViewerManifest(LLManifest,FSViewerManifest):
return self.channel().replace(CHANNEL_VENDOR_BASE, "").strip()
def channel_type(self): # returns 'release', 'beta', 'project', or 'test'
global CHANNEL_VENDOR_BASE
channel_qualifier=self.channel().replace(CHANNEL_VENDOR_BASE, "").lower().strip()
channel_qualifier=self.channel_variant().lower()
if channel_qualifier.startswith('release'):
channel_type='release'
elif channel_qualifier.startswith('beta'):
@ -551,19 +556,19 @@ class WindowsManifest(ViewerManifest):
self.path(src='%s/firestorm-bin.exe' % self.args['configuration'], dst=self.final_exe())
# <FS:Ansariel> Remove VMP
#with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
#with self.prefix(src=os.path.join(pkgdir, "VMP")):
# include the compiled launcher scripts so that it gets included in the file_list
# self.path('SL_Launcher.exe')
#IUM is not normally executed directly, just imported. No exe needed.
# self.path("InstallerUserMessage.py")
#with self.prefix(src=self.icon_path(), dst="vmp_icons"):
# self.path("secondlife.ico")
#VMP Tkinter icons
#with self.prefix("vmp_icons"):
# self.path("*.png")
# self.path("*.gif")
#with self.prefix(dst="vmp_icons"):
# with self.prefix(src=self.icon_path()):
# self.path("secondlife.ico")
#VMP Tkinter icons
# with self.prefix(src="vmp_icons"):
# self.path("*.png")
# self.path("*.gif")
#before, we only needed llbase at build time. With VMP, we need it at run time.
#with self.prefix(src=os.path.join(pkgdir, "lib", "python", "llbase"), dst="llbase"):
@ -577,8 +582,8 @@ class WindowsManifest(ViewerManifest):
"slplugin.exe")
# Get shared libs from the shared libs staging directory
with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
dst=""):
with self.prefix(src=os.path.join(self.args['build'], os.pardir,
'sharedlibs', self.args['configuration'])):
# Get llcommon and deps. If missing assume static linkage and continue.
try:
@ -656,6 +661,16 @@ class WindowsManifest(ViewerManifest):
# Hunspell
self.path("libhunspell.dll")
# BugSplat
if(self.address_size == 64):
self.path("BsSndRpt64.exe")
self.path("BugSplat64.dll")
self.path("BugSplatRc64.dll")
else:
self.path("BsSndRpt.exe")
self.path("BugSplat.dll")
self.path("BugSplatRc.dll")
# Growl
self.path("growl.dll")
self.path("growl++.dll")
@ -678,114 +693,116 @@ class WindowsManifest(ViewerManifest):
except:
print "Skipping libtcmalloc_minimal.dll"
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
with self.prefix(src=pkgdir,dst=""):
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
self.path("VivoxAUP.txt")
# Media plugins - CEF
with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_cef.dll")
with self.prefix(dst="llplugin"):
with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins')):
with self.prefix(src=os.path.join('cef', self.args['configuration'])):
self.path("media_plugin_cef.dll")
# Media plugins - LibVLC
with self.prefix(src='../media_plugins/libvlc/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_libvlc.dll")
# Media plugins - LibVLC
with self.prefix(src=os.path.join('libvlc', self.args['configuration'])):
self.path("media_plugin_libvlc.dll")
# Media plugins - Example (useful for debugging - not shipped with release viewer)
if self.channel_type() != 'release':
with self.prefix(src='../media_plugins/example/%s' % self.args['configuration'], dst="llplugin"):
self.path("media_plugin_example.dll")
# Media plugins - Example (useful for debugging - not shipped with release viewer)
if self.channel_type() != 'release':
with self.prefix(src=os.path.join('example', self.args['configuration'])):
self.path("media_plugin_example.dll")
# CEF runtime files - debug
# CEF runtime files - not debug (release, relwithdebinfo etc.)
config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
with self.prefix(src=os.path.join(pkgdir, 'bin', config), dst="llplugin"):
self.path("chrome_elf.dll")
self.path("d3dcompiler_43.dll")
self.path("d3dcompiler_47.dll")
self.path("libcef.dll")
self.path("libEGL.dll")
self.path("libGLESv2.dll")
self.path("dullahan_host.exe")
self.path("natives_blob.bin")
self.path("snapshot_blob.bin")
self.path("widevinecdmadapter.dll")
# CEF runtime files - debug
# CEF runtime files - not debug (release, relwithdebinfo etc.)
config = 'debug' if self.args['configuration'].lower() == 'debug' else 'release'
with self.prefix(src=os.path.join(pkgdir, 'bin', config)):
self.path("chrome_elf.dll")
self.path("d3dcompiler_43.dll")
self.path("d3dcompiler_47.dll")
self.path("libcef.dll")
self.path("libEGL.dll")
self.path("libGLESv2.dll")
self.path("dullahan_host.exe")
self.path("natives_blob.bin")
self.path("snapshot_blob.bin")
self.path("widevinecdmadapter.dll")
# MSVC DLLs needed for CEF and have to be in same directory as plugin
with self.prefix(src=os.path.join(os.pardir, 'sharedlibs', 'Release'), dst="llplugin"):
self.path("msvcp120.dll")
self.path("msvcr120.dll")
# MSVC DLLs needed for CEF and have to be in same directory as plugin
with self.prefix(src=os.path.join(self.args['build'], os.pardir,
'sharedlibs', 'Release')):
self.path("msvcp120.dll")
self.path("msvcr120.dll")
# CEF files common to all configurations
with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="llplugin"):
self.path("cef.pak")
self.path("cef_100_percent.pak")
self.path("cef_200_percent.pak")
self.path("cef_extensions.pak")
self.path("devtools_resources.pak")
self.path("icudtl.dat")
# CEF files common to all configurations
with self.prefix(src=os.path.join(pkgdir, 'resources')):
self.path("cef.pak")
self.path("cef_100_percent.pak")
self.path("cef_200_percent.pak")
self.path("cef_extensions.pak")
self.path("devtools_resources.pak")
self.path("icudtl.dat")
with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('llplugin', 'locales')):
self.path("am.pak")
self.path("ar.pak")
self.path("bg.pak")
self.path("bn.pak")
self.path("ca.pak")
self.path("cs.pak")
self.path("da.pak")
self.path("de.pak")
self.path("el.pak")
self.path("en-GB.pak")
self.path("en-US.pak")
self.path("es-419.pak")
self.path("es.pak")
self.path("et.pak")
self.path("fa.pak")
self.path("fi.pak")
self.path("fil.pak")
self.path("fr.pak")
self.path("gu.pak")
self.path("he.pak")
self.path("hi.pak")
self.path("hr.pak")
self.path("hu.pak")
self.path("id.pak")
self.path("it.pak")
self.path("ja.pak")
self.path("kn.pak")
self.path("ko.pak")
self.path("lt.pak")
self.path("lv.pak")
self.path("ml.pak")
self.path("mr.pak")
self.path("ms.pak")
self.path("nb.pak")
self.path("nl.pak")
self.path("pl.pak")
self.path("pt-BR.pak")
self.path("pt-PT.pak")
self.path("ro.pak")
self.path("ru.pak")
self.path("sk.pak")
self.path("sl.pak")
self.path("sr.pak")
self.path("sv.pak")
self.path("sw.pak")
self.path("ta.pak")
self.path("te.pak")
self.path("th.pak")
self.path("tr.pak")
self.path("uk.pak")
self.path("vi.pak")
self.path("zh-CN.pak")
self.path("zh-TW.pak")
with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst='locales'):
self.path("am.pak")
self.path("ar.pak")
self.path("bg.pak")
self.path("bn.pak")
self.path("ca.pak")
self.path("cs.pak")
self.path("da.pak")
self.path("de.pak")
self.path("el.pak")
self.path("en-GB.pak")
self.path("en-US.pak")
self.path("es-419.pak")
self.path("es.pak")
self.path("et.pak")
self.path("fa.pak")
self.path("fi.pak")
self.path("fil.pak")
self.path("fr.pak")
self.path("gu.pak")
self.path("he.pak")
self.path("hi.pak")
self.path("hr.pak")
self.path("hu.pak")
self.path("id.pak")
self.path("it.pak")
self.path("ja.pak")
self.path("kn.pak")
self.path("ko.pak")
self.path("lt.pak")
self.path("lv.pak")
self.path("ml.pak")
self.path("mr.pak")
self.path("ms.pak")
self.path("nb.pak")
self.path("nl.pak")
self.path("pl.pak")
self.path("pt-BR.pak")
self.path("pt-PT.pak")
self.path("ro.pak")
self.path("ru.pak")
self.path("sk.pak")
self.path("sl.pak")
self.path("sr.pak")
self.path("sv.pak")
self.path("sw.pak")
self.path("ta.pak")
self.path("te.pak")
self.path("th.pak")
self.path("tr.pak")
self.path("uk.pak")
self.path("vi.pak")
self.path("zh-CN.pak")
self.path("zh-TW.pak")
with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="llplugin"):
self.path("libvlc.dll")
self.path("libvlccore.dll")
self.path("plugins/")
with self.prefix(src=os.path.join(pkgdir, 'bin', 'release')):
self.path("libvlc.dll")
self.path("libvlccore.dll")
self.path("plugins/")
# pull in the crash logger and updater from other projects
# tag:"crash-logger" here as a cue to the exporter
@ -797,10 +814,10 @@ class WindowsManifest(ViewerManifest):
# is a 32bit process and Windows will silently copy the 32bit versions from
# the SysWOW64 folder, even if explicitly trying to copy from System32!
if (self.address_size == 64):
with self.prefix(src=os.path.join(os.pardir, '..', 'indra', 'newview', 'installers', 'windows_x64'), dst="llplugin"):
with self.prefix(src=os.path.join(self.args['build'], os.pardir, os.pardir, 'indra', 'newview', 'installers', 'windows_x64'), dst="llplugin"):
self.path("msvcp120.dll")
self.path("msvcr120.dll")
with self.prefix(src=os.path.join(os.pardir, '..', 'indra', 'newview', 'installers', 'windows_x64'), dst=""):
with self.prefix(src=os.path.join(self.args['build'], os.pardir, os.pardir, 'indra', 'newview', 'installers', 'windows_x64')):
self.path("msvcp120.dll")
self.path("msvcr120.dll")
@ -1017,6 +1034,9 @@ class DarwinManifest(ViewerManifest):
# launcher_app, launcher_icon = "Second Life Launcher.app", "secondlife.icns"
# viewer_app, viewer_icon = "Second Life Viewer.app", "secondlife.icns"
# # capture the path to the directory containing toplevel_app
# parentdir = os.path.join(self.get_dst_prefix(), os.pardir)
# # copy over the build result (this is a no-op if run within the xcode script)
# self.path(os.path.join(self.args['configuration'], toplevel_app), dst="")
@ -1026,12 +1046,9 @@ class DarwinManifest(ViewerManifest):
# # -------------------- top-level Second Life.app ---------------------
# # top-level Second Life application is only a container
# with self.prefix(src="", dst="Contents"): # everything goes in Contents
# with self.prefix(dst="Contents"): # everything goes in Contents
# # top-level Info.plist is as generated by CMake
# Info_plist = "Info.plist"
# ## This self.path() call reports 0 files... skip?
# self.path(Info_plist)
# Info_plist = self.dst_path_of(Info_plist)
# Info_plist = self.dst_path_of("Info.plist")
# # the one file in top-level MacOS directory is the trampoline to
# # our nested launcher_app
@ -1058,10 +1075,10 @@ class DarwinManifest(ViewerManifest):
# # rather than relsymlinkf().
# self.symlinkf(os.path.join("Resources", viewer_app, "Contents", "Frameworks"))
# with self.prefix(src="", dst="Resources"):
# with self.prefix(dst="Resources"):
# # top-level Resources directory should be pretty sparse
# # need .icns file referenced by top-level Info.plist
# with self.prefix(src=self.icon_path(), dst="") :
# with self.prefix(src=self.icon_path()) :
# self.path(toplevel_icon)
# # ------------------- nested launcher_app --------------------
@ -1081,15 +1098,15 @@ class DarwinManifest(ViewerManifest):
# #this copies over the python wrapper script,
# #associated utilities and required libraries, see
# #SL-321, SL-322, SL-323
# with self.prefix(src=os.path.join(pkgdir, "VMP"), dst=""):
# with self.prefix(src=os.path.join(pkgdir, "VMP")):
# self.path("SL_Launcher")
# self.path("*.py")
# # certifi will be imported by requests; this is
# # our custom version to get our ca-bundle.crt
# self.path("certifi")
# with self.prefix(src=os.path.join(pkgdir, "lib", "python"), dst=""):
# with self.prefix(src=os.path.join(pkgdir, "lib", "python")):
# # llbase provides our llrest service layer and llsd decoding
# with self.prefix("llbase"):
# with self.prefix(src="llbase", dst="llbase"):
# # (Why is llbase treated specially here? What
# # DON'T we want to copy out of lib/python/llbase?)
# self.path("*.py")
@ -1102,36 +1119,18 @@ class DarwinManifest(ViewerManifest):
# # launcher_app/Contents/Resources
# with self.prefix(dst="Resources"):
# with self.prefix(src=self.icon_path(), dst="") :
# with self.prefix(src=self.icon_path()) :
# self.path(launcher_icon)
# with self.prefix(dst="vmp_icons"):
# self.path("secondlife.ico")
# #VMP Tkinter icons
# with self.prefix("vmp_icons"):
# with self.prefix(src_dst="vmp_icons"):
# self.path("*.png")
# self.path("*.gif")
# # -------------------- nested viewer_app ---------------------
# with self.prefix(dst=os.path.join(viewer_app, "Contents")):
# # Info.plist is just like top-level one...
# Info = plistlib.readPlist(Info_plist)
# # except for these replacements:
# # (CFBundleExecutable may be moot: SL_Launcher directly
# # runs the executable, instead of launching the app)
# Info["CFBundleExecutable"] = "Second Life"
# Info["CFBundleIconFile"] = viewer_icon
# self.put_in_file(
# plistlib.writePlistToString(Info),
# os.path.basename(Info_plist),
# "Info.plist")
# # CEF framework goes inside viewer_app/Contents/Frameworks.
# # Remember where we parked this car.
# with self.prefix(src="", dst="Frameworks"):
# CEF_framework = "Chromium Embedded Framework.framework"
# self.path2basename(relpkgdir, CEF_framework)
# CEF_framework = self.dst_path_of(CEF_framework)
# defer Info.plist until after MacOS
# with self.prefix(dst="MacOS"):
# # CMake constructs the Second Life executable in the
# # MacOS directory belonging to the top-level Second
@ -1144,33 +1143,104 @@ class DarwinManifest(ViewerManifest):
# # don't move the trampoline script we just made!
# continue
# fromwhere = os.path.join(toplevel_MacOS, f)
# towhere = os.path.join(here, f)
# towhere = self.dst_path_of(f)
# print "Moving %s => %s" % \
# (self.relpath(fromwhere, relbase),
# self.relpath(towhere, relbase))
# # now do it, only without relativizing paths
# os.rename(fromwhere, towhere)
# # NOTE: the -S argument to strip causes it to keep
# # enough info for annotated backtraces (i.e. function
# # names in the crash log). 'strip' with no arguments
# # yields a slightly smaller binary but makes crash
# # logs mostly useless. This may be desirable for the
# # final release. Or not.
# Pick the biggest of the executables as the real viewer.
# Make (basename, fullpath) pairs; for each pair,
# expand to (size, basename, fullpath) triples; sort
# by size; pick the last triple; take the basename and
# fullpath from that.
# _, exename, exepath = \
# sorted((os.path.getsize(path), name, path)
# for name, path in
# ((name, os.path.join(here, name))
# for name in os.listdir(here)))[-1]
# if ("package" in self.args['actions'] or
# "unpacked" in self.args['actions']):
# self.run_command(
# ['strip', '-S', self.dst_path_of('Second Life')])
# "unpacked" in self.args['actions']):
# # only if we're engaging BugSplat
# if "BUGSPLAT_DB" in os.environ:
# # Create a symbol archive BEFORE stripping the
# # binary.
# self.run_command(['dsymutil', exepath])
# # This should produce a Second Life.dSYM bundle directory.
# try:
# # Now pretend we're Xcode making a .xcarchive file.
# # Put it as a sibling of the top-level .app.
# # From "Dave" at BugSplat support:
# # "More from our Mac lead: I think zipping
# # a folder containing the binary and
# # symbols would be sufficient. Assuming
# # symbol files are created with CMake. I'm
# # not sure if CMake strips symbols into
# # separate files at build time, and if so
# # they're in a supported format."
# xcarchive = os.path.join(parentdir,
# exename + '.xcarchive.zip')
# with zipfile.ZipFile(xcarchive, 'w',
# compression=zipfile.ZIP_DEFLATED) as zf:
# print "Creating {}".format(xcarchive)
# for base, dirs, files in os.walk(here):
# for fn in files:
# fullfn = os.path.join(base, fn)
# relfn = os.path.relpath(fullfn, here)
# print " {}".format(relfn)
# zf.write(fullfn, relfn)
# finally:
# # Whether or not we were able to create the
# # .xcarchive file, clean up the .dSYM bundle
# shutil.rmtree(self.dst_path_of(exename + '.dSYM'))
# # NOTE: the -S argument to strip causes it to keep
# # enough info for annotated backtraces (i.e. function
# # names in the crash log). 'strip' with no arguments
# # yields a slightly smaller binary but makes crash
# # logs mostly useless. This may be desirable for the
# # final release. Or not.
# self.run_command(['strip', '-S', exepath])
# # Info.plist is just like top-level one...
# Info = plistlib.readPlist(Info_plist)
# # except for these replacements:
# # (CFBundleExecutable may be moot: SL_Launcher directly
# # runs the executable, instead of launching the app)
# Info["CFBundleExecutable"] = exename
# Info["CFBundleIconFile"] = viewer_icon
# try:
# # https://www.bugsplat.com/docs/platforms/os-x#configuration
# Info["BugsplatServerURL"] = \
# "https://{BUGSPLAT_DB}.bugsplatsoftware.com/".format(**os.environ)
# except KeyError:
# # skip the assignment if there's no BUGSPLAT_DB variable
# pass
# self.put_in_file(
# plistlib.writePlistToString(Info),
# os.path.basename(Info_plist),
# "Info.plist")
# with self.prefix(dst="Frameworks"):
# # CEF framework goes inside viewer_app/Contents/Frameworks.
# CEF_framework = "Chromium Embedded Framework.framework"
# self.path2basename(relpkgdir, CEF_framework)
# # Remember where we parked this car.
# CEF_framework = self.dst_path_of(CEF_framework)
# self.path2basename(relpkgdir, "BugsplatMac.framework")
# with self.prefix(dst="Resources"):
# # defer cross-platform file copies until we're in the right
# # nested Resources directory
# super(DarwinManifest, self).construct()
# with self.prefix(src=self.icon_path(), dst="") :
# with self.prefix(src=self.icon_path()) :
# self.path(viewer_icon)
# with self.prefix(src=relpkgdir, dst=""):
# with self.prefix(src=relpkgdir):
# self.path("libndofdev.dylib")
# self.path("libhunspell-1.3.0.dylib")
@ -1409,7 +1479,7 @@ class DarwinManifest(ViewerManifest):
chardetdir = os.path.join(pkgdir, "lib", "python", "chardet")
idnadir = os.path.join(pkgdir, "lib", "python", "idna")
with self.prefix(src="", dst="Contents"): # everything goes in Contents
with self.prefix(dst="Contents"): # everything goes in Contents
self.path("Info.plist", dst="Info.plist")
# copy additional libs in <bundle>/Contents/MacOS/
@ -1420,7 +1490,7 @@ class DarwinManifest(ViewerManifest):
self.path("../packages/Frameworks/Growl", dst="Frameworks/Growl")
# most everything goes in the Resources directory
with self.prefix(src="", dst="Resources"):
with self.prefix(dst="Resources"):
super(DarwinManifest, self).construct()
with self.prefix("cursors_mac"):
@ -1430,11 +1500,11 @@ class DarwinManifest(ViewerManifest):
self.path("featuretable_mac.txt")
self.path("VivoxAUP.txt")
with self.prefix(src=pkgdir,dst=""):
with self.prefix(src=pkgdir):
self.path("ca-bundle.crt")
icon_path = self.icon_path()
with self.prefix(src=icon_path, dst="") :
with self.prefix(src=icon_path) :
self.path("firestorm_icon.icns")
self.path("Firestorm.nib")
@ -1587,15 +1657,15 @@ class DarwinManifest(ViewerManifest):
#<FS:TS> Moved from the x86_64 specific version because code
# below that does symlinking and path fixup depends on it.
with self.prefix(src="../packages/bin_x86", dst=""):
with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'bin_x86')):
self.path("SLPlugin.app", "SLPlugin.app")
with self.prefix(src = "llplugin", dst="llplugin"):
with self.prefix(src_dst="llplugin"):
self.path("media_plugin_quicktime.dylib", "media_plugin_quicktime.dylib")
self.path("media_plugin_cef.dylib", "media_plugin_cef.dylib")
# Dullahan helper apps go inside SLPlugin.app
with self.prefix(src="", dst="SLPlugin.app/Contents/Frameworks"):
with self.prefix(dst="SLPlugin.app/Contents/Frameworks"):
helperappfile = 'DullahanHelper.app'
self.path2basename(relpkgdir, helperappfile)
@ -1611,14 +1681,13 @@ class DarwinManifest(ViewerManifest):
self.dst_path_of('DullahanHelper.app/Contents/MacOS/'
'Frameworks/Chromium Embedded Framework.framework')
helperexecutablepath = self.dst_path_of('SLPlugin.app/Contents/Frameworks/DullahanHelper.app/Contents/MacOS/DullahanHelper')
self.run_command_shell('install_name_tool -change '
'"@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" '
'"@executable_path/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" "%s"' % helperexecutablepath)
# SLPlugin plugins
with self.prefix(src="", dst="llplugin"):
with self.prefix(dst="llplugin"):
self.path2basename("../media_plugins/cef/" + self.args['configuration'],
"media_plugin_cef.dylib")
@ -1627,14 +1696,13 @@ class DarwinManifest(ViewerManifest):
"media_plugin_libvlc.dylib")
# copy LibVLC dynamic libraries
with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release' ), dst="lib"):
self.path( "libvlc*.dylib*" )
with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'lib', 'release' ), dst="lib"):
self.path("libvlc*.dylib*")
# copy LibVLC plugins folder
with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release', 'plugins' ), dst="lib"):
self.path( "*.dylib" )
self.path( "plugins.dat" )
with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'lib', 'release', 'plugins' ), dst="lib"):
self.path("*.dylib")
self.path("plugins.dat")
# do this install_name_tool *after* media plugin is copied over
dylibexecutablepath = self.dst_path_of('llplugin/media_plugin_cef.dylib')
@ -1642,13 +1710,12 @@ class DarwinManifest(ViewerManifest):
'"@rpath/Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" '
'"@executable_path/../Frameworks/Chromium Embedded Framework.framework/Chromium Embedded Framework" "%s"' % dylibexecutablepath)
#<FS:TS> Copy in prebuilt framework if it's there
with self.prefix(src="../packages/bin_x86/Frameworks", dst="Frameworks"):
with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'packages', 'bin_x86', 'Frameworks'), dst="Frameworks"):
self.path("Chromium Embedded Framework.framework")
# CEF framework goes inside Second Life.app/Contents/Frameworks
with self.prefix(src="", dst="Frameworks"):
with self.prefix(dst="Frameworks"):
frameworkfile="Chromium Embedded Framework.framework"
self.path2basename(relpkgdir, frameworkfile)
@ -1921,26 +1988,26 @@ class LinuxManifest(ViewerManifest):
self.path("licenses-linux.txt","licenses.txt")
self.path("VivoxAUP.txt")
self.path("res/firestorm_icon.png","firestorm_icon.png")
with self.prefix("linux_tools", dst=""):
with self.prefix("linux_tools"):
self.path("client-readme.txt","README-linux.txt")
self.path("FIRESTORM_DESKTOPINSTALL.txt","FIRESTORM_DESKTOPINSTALL.txt")
self.path("client-readme-voice.txt","README-linux-voice.txt")
self.path("client-readme-joystick.txt","README-linux-joystick.txt")
self.path("wrapper.sh","firestorm")
with self.prefix(src="", dst="etc"):
with self.prefix(dst="etc"):
self.path("handle_secondlifeprotocol.sh")
self.path("register_secondlifeprotocol.sh")
self.path("refresh_desktop_app_entry.sh")
self.path("launch_url.sh")
self.path("install.sh")
with self.prefix(src="", dst="bin"):
with self.prefix(dst="bin"):
self.path("firestorm-bin","do-not-directly-run-firestorm-bin")
self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
self.path2basename("../llplugin/slplugin", "SLPlugin")
#this copies over the python wrapper script, associated utilities and required libraries, see SL-321, SL-322 and SL-323
# <FS:Ansariel> Remove VMP
#with self.prefix(src="../viewer_components/manager", dst=""):
#with self.prefix(src="../viewer_components/manager"):
# self.path("SL_Launcher")
# self.path("*.py")
#with self.prefix(src=os.path.join("lib", "python", "llbase"), dst="llbase"):
@ -1954,24 +2021,24 @@ class LinuxManifest(ViewerManifest):
# Get the icons based on the channel type
icon_path = self.icon_path()
print "DEBUG: icon_path '%s'" % icon_path
with self.prefix(src=icon_path, dst="") :
with self.prefix(src=icon_path) :
self.path("firestorm_256.png","firestorm_48.png")
with self.prefix(src="",dst="res-sdl") :
with self.prefix(dst="res-sdl") :
self.path("firestorm_256.BMP","ll_icon.BMP")
# plugins
with self.prefix(src="../media_plugins", dst="bin/llplugin"):
with self.prefix(src=os.path.join(self.args['build'], os.pardir, 'media_plugins', dst="bin/llplugin")):
self.path("gstreamer010/libmedia_plugin_gstreamer010.so",
"libmedia_plugin_gstreamer.so")
self.path2basename("libvlc", "libmedia_plugin_libvlc.so")
self.path("cef/libmedia_plugin_cef.so", "libmedia_plugin_cef.so" )
with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
self.path( "plugins.dat" )
self.path( "*/*.so" )
with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib' ), dst="lib"):
with self.prefix(src=os.path.join(pkgdir, 'lib' ), dst="lib"):
self.path( "libvlc*.so*" )
with self.prefix(src=os.path.join(pkgdir, 'lib', 'vlc', 'plugins'), dst="bin/llplugin/vlc/plugins"):
@ -1982,14 +2049,14 @@ class LinuxManifest(ViewerManifest):
self.path( "libvlc*.so*" )
# CEF files
with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release'), dst="lib"):
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path( "libcef.so" )
self.path( "libllceflib.so" )
with self.prefix(src=os.path.join(os.pardir, 'packages', 'lib', 'release', 'swiftshader'), dst=os.path.join("bin", "swiftshader") ):
with self.prefix(src=os.path.join(pkgdir, 'release', 'swiftshader'), dst=os.path.join("bin", "swiftshader") ):
self.path( "*.so" )
with self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'release'), dst="bin"):
with self.prefix(src=os.path.join(pkgdir, 'bin', 'release'), dst="bin"):
self.path( "chrome-sandbox" )
self.path( "dullahan_host" )
self.path( "natives_blob.bin" )
@ -1997,7 +2064,7 @@ class LinuxManifest(ViewerManifest):
self.path( "v8_context_snapshot.bin" )
self.path( "libffmpegsumo.so" )
with self.prefix(src=os.path.join(os.pardir, 'packages', 'resources'), dst="bin"):
with self.prefix(src=os.path.join(pkgdir, 'resources'), dst="bin"):
self.path( "cef.pak" )
self.path( "cef_extensions.pak" )
self.path( "cef_100_percent.pak" )
@ -2005,7 +2072,7 @@ class LinuxManifest(ViewerManifest):
self.path( "devtools_resources.pak" )
self.path( "icudtl.dat" )
with self.prefix(src=os.path.join(os.pardir, 'packages', 'resources', 'locales'), dst=os.path.join('bin', 'locales')):
with self.prefix(src=os.path.join(pkgdir, 'resources', 'locales'), dst=os.path.join('bin', 'locales')):
self.path("am.pak")
self.path("ar.pak")
self.path("bg.pak")
@ -2066,11 +2133,11 @@ class LinuxManifest(ViewerManifest):
self.path("featuretable_linux.txt")
with self.prefix(src=pkgdir,dst="bin"):
with self.prefix(src=pkgdir, dst="bin"):
self.path("ca-bundle.crt")
if self.is_packaging_viewer():
with self.prefix("../packages/lib/release", dst="lib"):
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libapr-1.so*")
self.path("libaprutil-1.so*")
self.path("libboost_context-mt.so*")
@ -2132,11 +2199,11 @@ class LinuxManifest(ViewerManifest):
# Vivox runtimes
# Currentelly, the 32-bit ones will work with a 64-bit client.
with self.prefix(src="../packages/lib/release", dst="bin"):
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="bin"):
self.path("SLVoice")
self.path("win32")
with self.prefix(src="../packages/lib/release", dst="lib"):
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libortp.so")
self.path("libsndfile.so.1")
# <FS:TS> Vivox wants this library even if it's present already in the viewer
@ -2207,7 +2274,7 @@ class Linux_i686_Manifest(LinuxManifest):
relpkgdir = os.path.join(pkgdir, "lib", "release")
debpkgdir = os.path.join(pkgdir, "lib", "debug")
with self.prefix(relpkgdir, dst="lib"):
with self.prefix(src=relpkgdir, dst="lib"):
self.path("libapr-1.so")
self.path("libapr-1.so.0")
self.path("libapr-1.so.0.4.5")
@ -2303,7 +2370,7 @@ class Linux_x86_64_Manifest(LinuxManifest):
super(Linux_x86_64_Manifest, self).construct()
if self.is_packaging_viewer():
with self.prefix("../packages/lib/release", dst="lib"):
with self.prefix(src=os.path.join(pkgdir, 'lib', 'release'), dst="lib"):
self.path("libffi*.so*")
# vivox 32-bit hack.
# one has to extract libopenal.so from the 32-bit openal package, or official LL viewer, and rename it to libopenal32.so
@ -2329,18 +2396,18 @@ class Linux_x86_64_Manifest(LinuxManifest):
print "Skipping libfmod.so - not found"
pass
self.prefix(src="../packages/lib/release/x64", dst="lib")
self.prefix(src=os.path.join(pkgdir, 'lib', 'release', 'x64'), dst="lib")
try:
self.path("libLeap.so")
except:
print "Leap Motion library not found"
self.end_prefix("lib")
with self.prefix(src="", dst="bin"):
with self.prefix(dst="bin"):
self.path2basename("../llplugin/slplugin", "SLPlugin")
# plugins
with self.prefix(src="", dst="bin/llplugin"):
with self.prefix(dst="bin/llplugin"):
self.path2basename("../media_plugins/webkit", "libmedia_plugin_webkit.so")
self.path("../media_plugins/gstreamer010/libmedia_plugin_gstreamer010.so", "libmedia_plugin_gstreamer.so")