diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/cmake/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | indra/cmake/Copy3rdPartyLibs.cmake | 12 | ||||
| -rw-r--r-- | indra/cmake/bugsplat.cmake | 30 | ||||
| -rw-r--r-- | indra/llcommon/llpreprocessor.h | 2 | ||||
| -rw-r--r-- | indra/llcommon/stringize.h | 52 | ||||
| -rw-r--r-- | indra/llcommon/tests/wrapllerrs.h | 14 | ||||
| -rw-r--r-- | indra/newview/CMakeLists.txt | 43 | ||||
| -rw-r--r-- | indra/newview/llappdelegate-objc.mm | 8 | ||||
| -rw-r--r-- | indra/newview/llappviewerwin32.cpp | 72 | ||||
| -rw-r--r-- | indra/newview/llversioninfo.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/tests/llversioninfo_test.cpp | 6 | ||||
| -rwxr-xr-x | indra/newview/viewer_manifest.py | 218 | 
12 files changed, 315 insertions, 150 deletions
| diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 4a3ebe4835..84e1c5d6fd 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -12,6 +12,7 @@ set(cmake_SOURCE_FILES      Audio.cmake      BerkeleyDB.cmake      Boost.cmake +    bugsplat.cmake      BuildVersion.cmake      CEFPlugin.cmake      CEFPlugin.cmake diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake index 09a97fc03e..7f708bc27a 100644 --- a/indra/cmake/Copy3rdPartyLibs.cmake +++ b/indra/cmake/Copy3rdPartyLibs.cmake @@ -49,6 +49,18 @@ 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(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) +      if (FMODEX)          if(ADDRESS_SIZE EQUAL 32) diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake new file mode 100644 index 0000000000..a7f4194905 --- /dev/null +++ b/indra/cmake/bugsplat.cmake @@ -0,0 +1,30 @@ +# BUGSPLAT can be set when launching the make using the argument -DBUGSPLAT:BOOL=ON +# When building using proprietary binaries though (i.e. having access to LL private servers), +# we always build with BUGSPLAT. +# Open source devs should use the -DBUGSPLAT:BOOL=ON then if they want to +# build with BugSplat, whether they are using USESYSTEMLIBS or not. +if (INSTALL_PROPRIETARY) +  set(BUGSPLAT ON CACHE BOOL "Using BugSplat crash reporting library.") +endif (INSTALL_PROPRIETARY) + +if (BUGSPLAT) +  if (USESYSTEMLIBS) +    set(BUGSPLAT_FIND_QUIETLY ON) +    set(BUGSPLAT_FIND_REQUIRED ON) +    include(FindBUGSPLAT) +  else (USESYSTEMLIBS) +    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) diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h index 2879038c36..ef015fdce4 100644 --- a/indra/llcommon/llpreprocessor.h +++ b/indra/llcommon/llpreprocessor.h @@ -198,6 +198,8 @@  #define LL_TO_STRING_HELPER(x) #x  #define LL_TO_STRING(x) LL_TO_STRING_HELPER(x) +#define LL_TO_WSTRING_HELPER(x) L#x +#define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x)  #define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg  #define LL_GLUE_IMPL(x, y) x##y  #define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y) diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h index a5a90d7297..38dd198ad3 100644 --- a/indra/llcommon/stringize.h +++ b/indra/llcommon/stringize.h @@ -30,7 +30,6 @@  #define LL_STRINGIZE_H  #include <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) */ diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h index 9a4bbbd630..08fbf19b1c 100644 --- a/indra/llcommon/tests/wrapllerrs.h +++ b/indra/llcommon/tests/wrapllerrs.h @@ -109,6 +109,12 @@ public:          mMessages.push_back(message);      } +    friend inline +    std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log) +    { +        return log.streamto(out); +    } +      /// Don't assume the message we want is necessarily the LAST log message      /// emitted by the underlying code; search backwards through all messages      /// for the sought string. @@ -126,7 +132,7 @@ public:          throw tut::failure(STRINGIZE("failed to find '" << search                                       << "' in captured log messages:\n" -                                     << boost::ref(*this))); +                                     << *this));      }      std::ostream& streamto(std::ostream& out) const @@ -200,10 +206,4 @@ private:  	LLError::RecorderPtr mRecorder;  }; -inline -std::ostream& operator<<(std::ostream& out, const CaptureLogRecorder& log) -{ -    return log.streamto(out); -} -  #endif /* ! defined(LL_WRAPLLERRS_H) */ diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 23337ddbfb..9e8a68224b 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -3,7 +3,12 @@  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) +include(bugsplat)  include(BuildPackagesInfo)  include(BuildVersion)  include(CMakeCopyIfDifferent) @@ -37,7 +42,6 @@ include(LLUI)  include(LLVFS)  include(LLWindow)  include(LLXML) -include(Linking)  include(NDOF)  include(NVAPI)  include(OPENAL) @@ -91,6 +95,7 @@ include_directories(      ${LIBS_PREBUILT_DIR}/include/collada/1.4      ${LLAPPEARANCE_INCLUDE_DIRS}      ${CMAKE_CURRENT_SOURCE_DIR} +    ${BUGSPLAT_INCLUDE_DIR}      )  include_directories(SYSTEM @@ -1354,6 +1359,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" +    )    find_library(AGL_LIBRARY AGL)    find_library(APPKIT_LIBRARY AppKit) @@ -1366,6 +1379,7 @@ if (DARWIN)      ${AGL_LIBRARY}      ${IOKIT_LIBRARY}      ${COREAUDIO_LIBRARY} +    ${BUGSPLAT_LIBRARIES}      )    # Add resource files to the project. @@ -1393,6 +1407,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)      SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed") @@ -1409,6 +1428,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 @@ -1691,6 +1715,11 @@ if (SDL_FOUND)      )  endif (SDL_FOUND) +if (BUGSPLAT) +  set_property(TARGET ${VIEWER_BINARY_NAME} +    PROPERTY COMPILE_DEFINITIONS "LL_BUGSPLAT") +endif (BUGSPLAT) +  # add package files  file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST       ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py) @@ -1789,7 +1818,7 @@ if (WINDOWS)             ${SHARED_LIB_STAGING_DIR}/Debug/fmodexL.dll            )      endif (FMODEX) -     +      add_custom_command(        OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat        COMMAND ${PYTHON_EXECUTABLE} @@ -1903,8 +1932,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 @@ -1977,6 +2006,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}      ${LLPHYSICS_LIBRARIES}      ${LLPHYSICSEXTENSIONS_LIBRARIES}      ${LLAPPEARANCE_LIBRARIES} +    ${BUGSPLAT_LIBRARIES}      )  set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH @@ -2066,11 +2096,16 @@ if (DARWIN)    set(MACOSX_BUNDLE_COPYRIGHT "Copyright © Linden Research, Inc. 2007")    set(MACOSX_BUNDLE_NSMAIN_NIB_FILE "SecondLife.nib")    set(MACOSX_BUNDLE_NSPRINCIPAL_CLASS "NSApplication") + +  # 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"      MACOSX_BUNDLE_INFO_PLIST      "${CMAKE_CURRENT_SOURCE_DIR}/Info-SecondLife.plist"      ) diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index aebae4c434..e8b4272e51 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -25,6 +25,9 @@   */  #import "llappdelegate-objc.h" +#if defined(LL_BUGSPLAT) +@import BugsplatMac; +#endif  #include "llwindowmacosx-objc.h"  #include <Carbon/Carbon.h> // Used for Text Input Services ("Safe" API - it's supported) @@ -64,6 +67,11 @@  	[[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] start]; +#endif  }  - (void) handleGetURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 48b3a1c485..5f3bf14bc2 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -66,8 +66,54 @@  #endif  #include "stringize.h" +#include "lldir.h"  #include <exception> + +// Bugsplat (http://bugsplat.com) crash reporting tool +#ifdef LL_BUGSPLAT +#include "BugSplat.h" + +namespace +{ +    // FIXME: need a production BugSplat database name +    static const wchar_t *bugdb_name = L"second_life_callum_test"; + +    // MiniDmpSender's constructor is defined to accept __wchar_t* instead of +    // plain wchar_t*. +    inline std::basic_string<__wchar_t> wunder(const std::wstring& str) +    { +        return { str.begin(), str.end() }; +    } + +    // Irritatingly, MiniDmpSender::setCallback() is defined to accept a +    // classic-C function pointer instead of an arbitrary C++ callable. In the +    // latter case, we could pass a lambda that binds our MiniDmpSender +    // pointer. As things stand, we must define an actual function and store +    // the pointer statically. +    static MiniDmpSender *sBugSplatSender = nullptr; + +    bool bugsplatSendLog(UINT nCode, LPVOID lpVal1, LPVOID lpVal2) +    { +        // If we haven't yet initialized LLDir, don't bother trying to +        // find our log file. +        // Alternatively -- if we might encounter trouble trying to query +        // LLDir during crash cleanup -- consider making gDirUtilp an +        // LLPounceable, and attach a callback that stores the pathname to +        // the log file here. +        if (nCode == MDSCB_EXCEPTIONCODE && gDirUtilp) +        { +            // send the main viewer log file +            // widen to wstring, convert to __wchar_t, then pass c_str() +            sBugSplatSender->sendAdditionalFile( +                wunder(wstringize(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLife.log"))).c_str()); +        } + +        return false; +    } +} +#endif // LL_BUGSPLAT +  namespace  {      void (*gOldTerminateHandler)() = NULL; @@ -495,15 +541,33 @@ bool LLAppViewerWin32::init()  	LLWinDebug::instance();  #endif -#if LL_WINDOWS  #if LL_SEND_CRASH_REPORTS - +#if ! defined(LL_BUGSPLAT)  	LLAppViewer* pApp = LLAppViewer::instance();  	pApp->initCrashReporting(); -#endif -#endif +#else // LL_BUGSPLAT + +	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( +		wunder(bugdb_name).c_str(), +		wunder(LL_TO_WSTRING(LL_VIEWER_CHANNEL)).c_str(), +		wunder(version_string).c_str(), +		nullptr); +	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; + +#endif // LL_BUGSPLAT +#endif // LL_SEND_CRASH_REPORTS  	bool success = LLAppViewer::init(); diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp index 375dce485d..4e07223784 100644 --- a/indra/newview/llversioninfo.cpp +++ b/indra/newview/llversioninfo.cpp @@ -101,14 +101,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. diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp index 2f7a4e9601..58f0469552 100644 --- a/indra/newview/tests/llversioninfo_test.cpp +++ b/indra/newview/tests/llversioninfo_test.cpp @@ -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  { diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 541112a765..1fa948f89e 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -580,6 +580,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") +              # For google-perftools tcmalloc allocator.              try:                  if self.args['configuration'].lower() == 'debug': @@ -589,7 +599,6 @@ class WindowsManifest(ViewerManifest):              except:                  print "Skipping libtcmalloc_minimal.dll" -          self.path(src="licenses-win32.txt", dst="licenses.txt")          self.path("featuretable.txt") @@ -597,106 +606,107 @@ class WindowsManifest(ViewerManifest):              self.path("ca-bundle.crt")          # Media plugins - CEF -        with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration'], dst="llplugin"): -            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 - 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") - -        # 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") - -        # 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") - -        # 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") - -        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, 'bin', 'release'), dst="llplugin"): -            self.path("libvlc.dll") -            self.path("libvlccore.dll") -            self.path("plugins/") +        with self.prefix(dst="llplugin"): +            with self.prefix(src='../media_plugins/cef/%s' % self.args['configuration']): +                self.path("media_plugin_cef.dll") + +            # Media plugins - LibVLC +            with self.prefix(src='../media_plugins/libvlc/%s' % 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']): +                    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)): +                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')): +                self.path("msvcp120.dll") +                self.path("msvcr120.dll") + +            # 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='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')): +                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 @@ -996,13 +1006,15 @@ open "%s" --args "$@"                          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 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="MacOS"):                          # CMake constructs the Second Life executable in the                          # MacOS directory belonging to the top-level Second | 
