V3 merge for most python scripts. fmod inclusion/linkage/packaging changes.

This commit is contained in:
Shyotl
2014-12-18 18:01:41 -06:00
parent 32706065ac
commit 44f8f17763
24 changed files with 1045 additions and 1735 deletions

View File

@@ -6,10 +6,6 @@
set(LIBS_PREBUILT_DIR "@LIBS_PREBUILT_DIR@")
set(LIBS_PREBUILT_LEGACY_DIR "@LIBS_PREBUILT_LEGACY_DIR@")
set(FMODSTUDIO_SDK_DIR "@FMODSTUDIO_SDK_DIR@")
set(FMODEX_SDK_DIR "@FMODEX_SDK_DIR@")
set(FMODSTUDIO @FMODSTUDIO@)
set(FMODEX @FMODEX@)
set(MSVC10 "@MSVC10@")
set(WORD_SIZE "@WORD_SIZE@")
@@ -181,62 +177,5 @@ if(0)
copy_files("${LIBS_DEBUG_DIR}/codecs" "${plugin_codec_debug_files}" "../test_apps/llplugintest/codecs/Debug")
endif(0)
if(FMODSTUDIO)
if (WORD_SIZE EQUAL 32)
set(fmodstudio_dll_file "fmod.dll")
else (WORD_SIZE EQUAL 32)
set(fmodstudio_dll_file "fmod64.dll")
endif (WORD_SIZE EQUAL 32)
find_path(FMODSTUDIO_BINARY_RELEASE_DIR "${fmodstudio_dll_file}"
${LIBS_RELEASE_DIR}
"${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib"
"${FMODSTUDIO_SDK_DIR}"
NO_DEFAULT_PATH
)
find_path(FMODSTUDIO_BINARY_DEBUG_DIR "${fmodstudio_dll_file}"
${LIBS_DEBUG_DIR}
"${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib"
"${FMODSTUDIO_SDK_DIR}"
NO_DEFAULT_PATH
)
if(FMODSTUDIO_BINARY_RELEASE_DIR)
copy_files(${FMODSTUDIO_BINARY_RELEASE_DIR} ${fmodstudio_dll_file} "Release")
copy_files(${FMODSTUDIO_BINARY_RELEASE_DIR} ${fmodstudio_dll_file} "RelWithDebInfo")
endif(FMODSTUDIO_BINARY_RELEASE_DIR)
if(FMODSTUDIO_BINARY_DEBUG_DIR)
copy_files(${FMODSTUDIO_BINARY_DEBUG_DIR} ${fmodstudio_dll_file} "Debug")
endif(FMODSTUDIO_BINARY_DEBUG_DIR)
endif(FMODSTUDIO)
if(FMODEX)
if (WORD_SIZE EQUAL 32)
set(fmodex_dll_file "fmodex.dll")
else (WORD_SIZE EQUAL 32)
set(fmodex_dll_file "fmodex64.dll")
endif (WORD_SIZE EQUAL 32)
find_path(FMODEX_BINARY_RELEASE_DIR "${fmodex_dll_file}"
${LIBS_RELEASE_DIR}
"${FMODEX_SDK_DIR}/api"
"${FMODEX_SDK_DIR}"
NO_DEFAULT_PATH
)
find_path(FMODEX_BINARY_DEBUG_DIR "${fmodex_dll_file}"
${LIBS_DEBUG_DIR}
"${FMODSTUDIO_SDK_DIR}/api"
"${FMODSTUDIO_SDK_DIR}"
NO_DEFAULT_PATH
)
if(FMODEX_BINARY_RELEASE_DIR)
copy_files(${FMODEX_BINARY_RELEASE_DIR ${fmodex_dll_file} "Release")
copy_files(${FMODEX_BINARY_RELEASE_DIR ${fmodex_dll_file} "RelWithDebInfo")
endif(FMODEX_BINARY_RELEASE_DIR)
if(FMODEX_BINARY_DEBUG_DIR)
copy_files(${FMODEX_BINARY_DEBUG_DIR ${fmodex_dll_file} "Debug")
endif(FMODEX_BINARY_DEBUG_DIR)
endif(FMODEX)

View File

@@ -6,81 +6,80 @@ if (FMODEX AND FMODSTUDIO)
message( FATAL_ERROR "You can not enable two FMOD variants at the same time." )
endif (FMODEX AND FMODSTUDIO)
if (NOT FMODEX_LIBRARY)
unset(FMOD_LIBRARY_RELEASE CACHE)
unset(FMOD_LIBRARY_DEBUG CACHE)
unset(FMOD_LINK_LIBRARY_RELEASE CACHE)
unset(FMOD_LINK_LIBRARY_DEBUG CACHE)
unset(FMOD_INCLUDE_DIR CACHE)
if (NOT FMODEX_SDK_DIR)
set(FMODEX_SDK_DIR CACHE PATH "Path to the FMOD Ex SDK.")
if (FMODEX_SDK_DIR)
if(WORD_SIZE EQUAL 32)
find_library(FMODEX_LIBRARY
fmodex_vc fmodexL_vc fmodex fmodexL
PATHS
"${FMODEX_SDK_DIR}/api/lib"
"${FMODEX_SDK_DIR}/api"
"${FMODEX_SDK_DIR}/lib"
"${FMODEX_SDK_DIR}"
)
elseif(WORD_SIZE EQUAL 64)
find_library(FMODEX_LIBRARY
fmodex64_vc fmodexL64_vc fmodex64 fmodexL64
PATHS
"${FMODEX_SDK_DIR}/api/lib"
"${FMODEX_SDK_DIR}/api"
"${FMODEX_SDK_DIR}/lib"
"${FMODEX_SDK_DIR}"
)
endif(WORD_SIZE EQUAL 32)
endif(FMODEX_SDK_DIR)
if(WINDOWS AND NOT FMODEX_SDK_DIR)
GET_FILENAME_COMPONENT(FMODEX_PROG_DIR [HKEY_CURRENT_USER\\Software\\FMOD\ Programmers\ API\ Windows] ABSOLUTE CACHE)
if(WORD_SIZE EQUAL 32)
find_library(FMODEX_LIBRARY
fmodex_vc fmodexL_vc
PATHS
"${FMODEX_PROG_DIR}/api/lib"
"${FMODEX_PROG_DIR}/api"
"${FMODEX_PROG_DIR}"
)
else(WORD_SIZE EQUAL 32)
find_library(FMODEX_LIBRARY
fmodex64_vc fmodexL64_vc
PATHS
"${FMODEX_PROG_DIR}/api/lib"
"${FMODEX_PROG_DIR}/api"
"${FMODEX_PROG_DIR}"
)
endif(WORD_SIZE EQUAL 32)
if(FMODEX_LIBRARY)
message(STATUS "Found fmodex in ${FMODEX_PROG_DIR}")
set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}")
set(FMODEX_SDK_DIR "${FMODEX_PROG_DIR}" CACHE PATH "Path to the FMOD Ex SDK." FORCE)
endif(FMODEX_LIBRARY)
endif(WINDOWS AND NOT FMODEX_SDK_DIR)
endif (NOT FMODEX_LIBRARY)
if(WINDOWS)
GET_FILENAME_COMPONENT(FMODEX_SDK_DIR [HKEY_CURRENT_USER\\Software\\FMOD\ Programmers\ API\ Windows] ABSOLUTE CACHE)
endif(WINDOWS)
endif (NOT FMODEX_SDK_DIR)
find_path(FMODEX_INCLUDE_DIR fmod.hpp
${LIBS_PREBUILT_DIR}/include/fmodex
${LIBS_PREBUILT_LEGACY_DIR}/include/fmodex
"${FMODEX_SDK_DIR}/api/inc"
"${FMODEX_SDK_DIR}/inc"
"${FMODEX_SDK_DIR}"
)
set(release_fmod_lib_paths
${LIBS_PREBUILT_DIR}/release/lib/
${LIBS_PREBUILT_LEGACY_DIR}/release/lib)
set(debug_fmod_lib_paths
${LIBS_PREBUILT_DIR}/debug/lib
${LIBS_PREBUILT_LEGACY_DIR}/debug/lib)
set(fmod_inc_paths
${LIBS_PREBUILT_DIR}/include/fmodsex
${LIBS_PREBUILT_LEGACY_DIR}/include/fmodex)
if(DARWIN)
set(FMODEX_ORIG_LIBRARY "${FMODEX_LIBRARY}")
set(FMODEX_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/libfmodex.dylib")
endif(DARWIN)
if (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
set(FMODEX ON CACHE BOOL "Use closed source FMOD Ex sound library.")
else (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
set(FMODEX_LIBRARY "")
set(FMODEX_INCLUDE_DIR "")
if (FMODEX)
if (FMODEX_SDK_DIR)
set(release_fmod_lib_paths ${release_fmod_lib_paths} "${FMODEX_SDK_DIR}/api" "${FMODEX_SDK_DIR}/api/lib")
set(debug_fmod_lib_paths ${debug_fmod_lib_paths} "${FMODEX_SDK_DIR}/api" "${FMODEX_SDK_DIR}/api/lib")
set(fmod_inc_paths ${fmod_inc_paths} "${FMODEX_SDK_DIR}/api/inc")
endif (FMODEX_SDK_DIR)
if(WINDOWS)
set(CMAKE_FIND_LIBRARY_SUFFIXES_OLD ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
endif(WINDOWS)
if(WORD_SIZE EQUAL 32) #Check if CMAKE_FIND_LIBRARY_PREFIXES is set to 'lib' for darwin.
find_library(FMOD_LIBRARY_RELEASE fmodex PATHS ${release_fmod_lib_paths})
find_library(FMOD_LIBRARY_DEBUG fmodexL PATHS ${debug_fmod_lib_paths})
elseif(WORD_SIZE EQUAL 64)
find_library(FMOD_LIBRARY_RELEASE fmodex64 PATHS ${release_fmod_lib_paths})
find_library(FMOD_LIBRARY_DEBUG fmodLex64 PATHS ${debug_fmod_lib_paths})
endif (WORD_SIZE EQUAL 32)
if(WINDOWS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_OLD})
if(WORD_SIZE EQUAL 32)
find_library(FMOD_LINK_LIBRARY_RELEASE fmodex_vc PATHS ${release_fmod_lib_paths})
find_library(FMOD_LINK_LIBRARY_DEBUG fmodexL_vc PATHS ${debug_fmod_lib_paths})
elseif(WORD_SIZE EQUAL 64)
find_library(FMOD_LINK_LIBRARY_RELEASE fmodex64_vc PATHS ${release_fmod_lib_paths})
find_library(FMOD_LINK_LIBRARY_DEBUG fmodLex64_vc PATHS ${debug_fmod_lib_paths})
endif (WORD_SIZE EQUAL 32)
else(WINDOWS)
set(FMODSTUDIO_LINK_LIBRARY_RELEASE ${FMODSTUDIO_LIBRARY_RELEASE})
set(FMODSTUDIO_LINK_LIBRARY_DEBUG ${FMODSTUDIO_LIBRARY_DEBUG})
endif(WINDOWS)
find_path(FMOD_INCLUDE_DIR fmod.hpp ${fmod_inc_paths})
if (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
set(FMOD ON CACHE BOOL "Use closed source FMOD sound library.")
if (NOT FMOD_LIBRARY_DEBUG) #Use release library in debug configuration if debug library is absent.
set(FMOD_LIBRARY_DEBUG ${FMOD_LIBRARY_RELEASE})
endif (NOT FMOD_LIBRARY_DEBUG)
else (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
unset(FMOD_LIBRARY_RELEASE CACHE)
unset(FMOD_LIBRARY_DEBUG CACHE)
unset(FMOD_INCLUDE_DIR CACHE)
if (FMOD)
message(STATUS "No support for FMOD Ex audio (need to set FMODEX_SDK_DIR?)")
endif (FMODEX)
set(FMODEX OFF CACHE BOOL "Use closed source FMOD Ex sound library.")
endif (FMOD)
set(FMOD OFF CACHE BOOL "Use closed source FMOD sound library.")
set(FMOD OFF)
set(FMODEX OFF)
endif (FMODEX_LIBRARY AND FMODEX_INCLUDE_DIR)
endif (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
if (FMODEX)
message(STATUS "Building with FMOD Ex audio support")
endif (FMODEX)
if (FMOD)
message(STATUS "Building with FMOD audio support")
endif (FMOD)

View File

@@ -6,78 +6,83 @@ if (FMODEX AND FMODSTUDIO)
message( FATAL_ERROR "You can not enable two FMOD variants at the same time." )
endif (FMODEX AND FMODSTUDIO)
if (NOT FMODSTUDIO_LIBRARY)
set(FMODSTUDIO_SDK_DIR CACHE PATH "Path to the FMOD Ex SDK.")
if (FMODSTUDIO_SDK_DIR)
if(WORD_SIZE EQUAL 32)
find_library(FMODSTUDIO_LIBRARY
fmod_vc fmodL_vc fmod fmodL
PATHS
"${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib"
"${FMODSTUDIO_SDK_DIR}/api/lowlevel"
"${FMODSTUDIO_SDK_DIR}"
)
elseif(WORD_SIZE EQUAL 64)
find_library(FMODSTUDIO_LIBRARY
fmod64_vc fmodL64_vc fmod64 fmodL64
PATHS
"${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib"
"${FMODSTUDIO_SDK_DIR}/api/lowlevel"
"${FMODSTUDIO_SDK_DIR}"
)
endif(WORD_SIZE EQUAL 32)
endif(FMODSTUDIO_SDK_DIR)
if(WINDOWS AND NOT FMODSTUDIO_SDK_DIR)
GET_FILENAME_COMPONENT(FMODSTUDIO_PROG_DIR [HKEY_CURRENT_USER\\Software\\FMOD\ Studio\ API\ Windows] ABSOLUTE CACHE)
if(WORD_SIZE EQUAL 32)
find_library(FMODSTUDIO_LIBRARY
fmod_vc fmodL_vc
PATHS
"${FMODSTUDIO_PROG_DIR}/api/lowlevel/lib"
"${FMODSTUDIO_PROG_DIR}/api/lowlevel"
"${FMODSTUDIO_PROG_DIR}"
)
else(WORD_SIZE EQUAL 32)
find_library(FMODSTUDIO_LIBRARY
fmod64_vc fmodL64_vc
PATHS
"${FMODSTUDIO_PROG_DIR}/api/lowlevel/lib"
"${FMODSTUDIO_PROG_DIR}/api/lowlevel"
"${FMODSTUDIO_PROG_DIR}"
)
endif(WORD_SIZE EQUAL 32)
if(FMODSTUDIO_LIBRARY)
message(STATUS "Found fmodstudio in ${FMODSTUDIO_PROG_DIR}")
set(FMODSTUDIO_SDK_DIR "${FMODSTUDIO_PROG_DIR}")
set(FMODSTUDIO_SDK_DIR "${FMODSTUDIO_PROG_DIR}" CACHE PATH "Path to the FMOD Studio SDK." FORCE)
endif(FMODSTUDIO_LIBRARY)
endif(WINDOWS AND NOT FMODSTUDIO_SDK_DIR)
endif (NOT FMODSTUDIO_LIBRARY)
unset(FMOD_LIBRARY_RELEASE CACHE)
unset(FMOD_LIBRARY_DEBUG CACHE)
unset(FMOD_LINK_LIBRARY_RELEASE CACHE)
unset(FMOD_LINK_LIBRARY_DEBUG CACHE)
unset(FMOD_INCLUDE_DIR CACHE)
find_path(FMODSTUDIO_INCLUDE_DIR fmod.hpp
${LIBS_PREBUILT_DIR}/include/fmodstudio
${LIBS_PREBUILT_LEGACY_DIR}/include/fmodstudio
"${FMODSTUDIO_SDK_DIR}/api/lowlevel/inc"
"${FMODSTUDIO_SDK_DIR}"
)
if (NOT FMODSTUDIO_SDK_DIR)
set(FMODSTUDIO_SDK_DIR CACHE PATH "Path to the FMOD Studio SDK.")
if(WINDOWS)
GET_FILENAME_COMPONENT(FMODSTUDIO_SDK_DIR [HKEY_CURRENT_USER\\Software\\FMOD\ Studio\ API\ Windows] ABSOLUTE CACHE)
endif(WINDOWS)
endif (NOT FMODSTUDIO_SDK_DIR)
if(DARWIN)
set(FMODSTUDIO_ORIG_LIBRARY "${FMODSTUDIO_LIBRARY}")
set(FMODSTUDIO_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/libfmod.dylib")
endif(DARWIN)
set(release_fmod_lib_paths
${LIBS_PREBUILT_DIR}/release/lib/
${LIBS_PREBUILT_LEGACY_DIR}/release/lib)
set(debug_fmod_lib_paths
${LIBS_PREBUILT_DIR}/debug/lib
${LIBS_PREBUILT_LEGACY_DIR}/debug/lib)
set(fmod_inc_paths
${LIBS_PREBUILT_DIR}/include/fmodstudio
${LIBS_PREBUILT_LEGACY_DIR}/include/fmodstudio)
if (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
set(FMODSTUDIO ON CACHE BOOL "Use closed source FMOD Studio sound library.")
else (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
set(FMODSTUDIO_LIBRARY "")
set(FMODSTUDIO_INCLUDE_DIR "")
if (FMODSTUDIO)
if (FMODSTUDIO_SDK_DIR)
if(LINUX AND WORD_SIZE EQUAL 32)
set(release_lib_paths ${release_fmod_lib_paths} "${FMODSTUDIO_SDK_DIR}/api/lowlevel/x86/lib" )
set(debug__lib_paths ${debug_fmod_lib_paths} "${FMODSTUDIO_SDK_DIR}/api/lowlevel/x86/lib")
elseif(LINUX)
set(release__lib_paths ${release_fmod_lib_paths} "${FMODSTUDIO_SDK_DIR}/api/lowlevel/x86_64/lib")
set(debug_fmod_lib_paths ${debug_fmod_lib_paths} "${FMODSTUDIO_SDK_DIR}/api/lowlevel/x86_64/lib")
else(LINUX AND WORD_SIZE EQUAL 32)
set(release_fmod_lib_paths ${release_fmod_lib_paths} "${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib")
set(debug_fmod_lib_paths ${debug_fmod_lib_paths} "${FMODSTUDIO_SDK_DIR}/api/lowlevel/lib")
endif(LINUX AND WORD_SIZE EQUAL 32)
set(fmod_inc_paths ${fmod_inc_paths} "${FMODSTUDIO_SDK_DIR}/api/lowlevel/inc")
endif (FMODSTUDIO_SDK_DIR)
if(WINDOWS)
set(CMAKE_FIND_LIBRARY_SUFFIXES_OLD ${CMAKE_FIND_LIBRARY_SUFFIXES})
set(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
endif(WINDOWS)
if(WORD_SIZE EQUAL 32) #Check if CMAKE_FIND_LIBRARY_PREFIXES is set to 'lib' for darwin.
find_library(FMOD_LIBRARY_RELEASE fmod PATHS ${release_fmod_lib_paths})
find_library(FMOD_LIBRARY_DEBUG fmodL PATHS ${debug_fmod_lib_paths})
elseif(WORD_SIZE EQUAL 64)
find_library(FMOD_LIBRARY_RELEASE fmod64 PATHS ${release_fmod_lib_paths})
find_library(FMOD_LIBRARY_DEBUG fmodL64 PATHS ${debug_fmod_lib_paths})
endif (WORD_SIZE EQUAL 32)
if(WINDOWS)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_OLD})
string(REPLACE ".dll" "_vc.lib" FMOD_LINK_LIBRARY_RELEASE ${FMOD_LIBRARY_RELEASE})
string(REPLACE ".dll" "_vc.lib" FMOD_LINK_LIBRARY_DEBUG ${FMOD_LIBRARY_DEBUG})
else(WINDOWS)
set(FMODSTUDIO_LINK_LIBRARY_RELEASE ${FMODSTUDIO_LIBRARY_RELEASE})
set(FMODSTUDIO_LINK_LIBRARY_DEBUG ${FMODSTUDIO_LIBRARY_DEBUG})
endif(WINDOWS)
find_path(FMOD_INCLUDE_DIR fmod.hpp ${fmod_inc_paths})
if (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
set(FMOD ON CACHE BOOL "Use closed source FMOD sound library.")
if (NOT FMOD_LIBRARY_DEBUG) #Use release library in debug configuration if debug library is absent.
set(FMOD_LIBRARY_DEBUG ${FMOD_LIBRARY_RELEASE})
endif (NOT FMOD_LIBRARY_DEBUG)
else (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
unset(FMOD_LIBRARY_RELEASE CACHE)
unset(FMOD_LIBRARY_DEBUG CACHE)
unset(FMOD_INCLUDE_DIR CACHE)
if (FMOD)
message(STATUS "No support for FMOD Studio audio (need to set FMODSTUDIO_SDK_DIR?)")
endif (FMODSTUDIO)
set(FMODSTUDIO OFF CACHE BOOL "Use closed source FMOD Studio sound library.")
endif (FMOD)
set(FMOD OFF CACHE BOOL "Use closed source FMOD sound library.")
set(FMOD OFF)
set(FMODSTUDIO OFF)
endif (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
endif (FMOD_LIBRARY_RELEASE AND FMOD_INCLUDE_DIR)
if (FMODSTUDIO)
message(STATUS "Building with FMOD Studio audio support")
endif (FMODSTUDIO)
if (FMOD)
message(STATUS "Building with FMOD audio support")
endif (FMOD)

View File

@@ -2,19 +2,24 @@
@file __init__.py
@brief Initialization file for the indra module.
$LicenseInfo:firstyear=2006&license=internal$
$LicenseInfo:firstyear=2006&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2006-2010, Linden Research, Inc.
Copyright (c) 2006-2009, Linden Research, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License only.
The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
this source code is governed by the Linden Lab Source Code Disclosure
Agreement ("Agreement") previously entered between you and Linden
Lab. By accessing, using, copying, modifying or distributing this
software, you acknowledge that you have been informed of your
obligations under the Agreement and agree to abide by those obligations.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
COMPLETENESS OR PERFORMANCE.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""

View File

@@ -1,3 +1,25 @@
#!/usr/bin/python
##
## $LicenseInfo:firstyear=2011&license=viewerlgpl$
## Second Life Viewer Source Code
## Copyright (C) 2011, Linden Research, Inc.
##
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation;
## version 2.1 of the License only.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library; if not, write to the Free Software
## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
##
## Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
## $/LicenseInfo$
from indra.base import llsd, lluuid
from datetime import datetime
import cllsd
@@ -10,7 +32,7 @@ values = (
'&<>',
u'\u81acj',
llsd.uri('http://foo<'),
lluuid.LLUUID(),
lluuid.UUID(),
llsd.LLSD(['thing']),
1,
myint(31337),

View File

@@ -1,72 +0,0 @@
"""\
@file lllog.py
@brief Logging for event processing
$LicenseInfo:firstyear=2008&license=mit$
Copyright (c) 2008-2009, Linden Research, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$/LicenseInfo$
"""
from indra.base.llsd import format_notation
try:
import syslog
except ImportError:
# Windows
import sys
class syslog(object):
_logfp = sys.stderr
def syslog(msg):
_logfp.write(msg)
if not msg.endswith('\n'):
_logfp.write('\n')
syslog = staticmethod(syslog)
class Logger(object):
def __init__(self, name='indra'):
self._sequence = 0
try:
syslog.openlog(name, syslog.LOG_CONS | syslog.LOG_PID,
syslog.LOG_LOCAL0)
except AttributeError:
# No syslog module on Windows
pass
def next(self):
self._sequence += 1
return self._sequence
def log(self, msg, llsd):
payload = 'INFO: log: LLLOGMESSAGE (%d) %s %s' % (self.next(), msg,
format_notation(llsd))
syslog.syslog(payload)
_logger = None
def log(msg, llsd):
global _logger
if _logger is None:
_logger = Logger()
_logger.log(msg, llsd)

View File

@@ -72,8 +72,11 @@ BOOL_FALSE = ('0', '0.0', 'false', '')
def format_datestr(v):
""" Formats a datetime object into the string format shared by xml and notation serializations."""
return v.isoformat() + 'Z'
""" Formats a datetime or date object into the string format shared by xml and notation serializations."""
if hasattr(v, 'microsecond'):
return v.isoformat() + 'Z'
else:
return v.strftime('%Y-%m-%dT%H:%M:%SZ')
def parse_datestr(datestr):
"""Parses a datetime object from the string format shared by xml and notation serializations."""
@@ -183,6 +186,7 @@ class LLSDXMLFormatter(object):
unicode : self.STRING,
uri : self.URI,
datetime.datetime : self.DATE,
datetime.date : self.DATE,
list : self.ARRAY,
tuple : self.ARRAY,
types.GeneratorType : self.ARRAY,
@@ -234,7 +238,7 @@ class LLSDXMLFormatter(object):
def MAP(self, v):
return self.elt(
'map',
''.join(["%s%s" % (self.elt('key', key), self.generate(value))
''.join(["%s%s" % (self.elt('key', self.xml_esc(str(key))), self.generate(value))
for key, value in v.items()]))
typeof = type
@@ -347,6 +351,7 @@ class LLSDNotationFormatter(object):
unicode : self.STRING,
uri : self.URI,
datetime.datetime : self.DATE,
datetime.date : self.DATE,
list : self.ARRAY,
tuple : self.ARRAY,
types.GeneratorType : self.ARRAY,
@@ -924,12 +929,13 @@ def _format_binary_recurse(something):
(type(something), something))
def parse_binary(something):
header = '<?llsd/binary?>\n'
if not something.startswith(header):
raise LLSDParseError('LLSD binary encoding header not found')
return LLSDBinaryParser().parse(something[len(header):])
def parse_binary(binary):
if binary.startswith('<?llsd/binary?>'):
just_binary = binary.split('\n', 1)[1]
else:
just_binary = binary
return LLSDBinaryParser().parse(just_binary)
def parse_xml(something):
try:
return to_python(fromstring(something)[0])

View File

@@ -28,13 +28,12 @@ $/LicenseInfo$
import random, socket, string, time, re
import uuid
# *HACK: Necessary for python 2.4. Consider replacing this code wart
# after python >=2.5 has deployed everywhere. 2009-10-05
try:
# Python 2.6
from hashlib import md5
except ImportError:
from md5 import md5
# Python 2.5 and earlier
from md5 import new as md5
def _int2binstr(i,l):
s=''
@@ -73,7 +72,7 @@ class UUID(object):
ip = ''
try:
ip = socket.gethostbyname(socket.gethostname())
except(socket.gaierror):
except(socket.gaierror, socket.error):
# no ip address, so just default to somewhere in 10.x.x.x
ip = '10'
for i in range(3):
@@ -164,7 +163,7 @@ class UUID(object):
def setFromMemoryDump(self, gdb_string):
"""
We expect to get gdb_string as four hex units. eg:
0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2
0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2
Which will be translated to:
db547d14-1b3f4bc3-9b984f71-d22f890a
Returns self.
@@ -188,7 +187,7 @@ class UUID(object):
def getAsString(self):
"""
Return a different string representation of the form
AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC (a 128-bit number in hex)
AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC (a 128-bit number in hex)
where A=network address, B=timestamp, C=random.
"""
i1 = _binstr2int(self._bits[0:4])
@@ -234,7 +233,7 @@ NULL = UUID()
def printTranslatedMemory(four_hex_uints):
"""
We expect to get the string as four hex units. eg:
0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2
0x147d54db 0xc34b3f1b 0x714f989b 0x0a892fd2
Which will be translated to:
db547d14-1b3f4bc3-9b984f71-d22f890a
"""

View File

@@ -29,25 +29,93 @@ $/LicenseInfo$
"""
import sys
from indra.base import llsd
try:
import syslog
except ImportError:
# Windows
import sys
class syslog(object):
# wrap to a lame syslog for windows
_logfp = sys.stderr
def syslog(msg):
_logfp.write(msg)
if not msg.endswith('\n'):
_logfp.write('\n')
syslog = staticmethod(syslog)
_sequence_id = 0
from indra.base.llsd import format_notation
def record_metrics(table, stats, dest=None):
def record_metrics(table, stats):
"Write a standard metrics log"
_log("LLMETRICS", table, stats, dest)
_log("LLMETRICS", table, stats)
def record_event(table, data, dest=None):
def record_event(table, data):
"Write a standard logmessage log"
_log("LLLOGMESSAGE", table, data, dest)
_log("LLLOGMESSAGE", table, data)
def _log(header, table, data, dest):
def set_destination(dest):
"""Set the destination of metrics logs for this process.
If you do not call this function prior to calling a logging
method, that function will open sys.stdout as a destination.
Attempts to set dest to None will throw a RuntimeError.
@param dest a file-like object which will be the destination for logs."""
if dest is None:
# do this check here in case sys.stdout changes at some
# point. as a default parameter, it will never be
# re-evaluated.
dest = sys.stdout
raise RuntimeError("Attempt to unset metrics destination.")
global _destination
_destination = dest
def destination():
"""Get the destination of the metrics logs for this process.
Returns None if no destination is set"""
global _destination
return _destination
class SysLogger(object):
"A file-like object which writes to syslog."
def __init__(self, ident='indra', logopt = None, facility = None):
try:
if logopt is None:
logopt = syslog.LOG_CONS | syslog.LOG_PID
if facility is None:
facility = syslog.LOG_LOCAL0
syslog.openlog(ident, logopt, facility)
import atexit
atexit.register(syslog.closelog)
except AttributeError:
# No syslog module on Windows
pass
def write(str):
syslog.syslog(str)
write = staticmethod(write)
def flush():
pass
flush = staticmethod(flush)
#
# internal API
#
_sequence_id = 0
_destination = None
def _next_id():
global _sequence_id
print >>dest, header, "(" + str(_sequence_id) + ")",
print >>dest, table, llsd.format_notation(data)
next = _sequence_id
_sequence_id += 1
return next
def _dest():
global _destination
if _destination is None:
# this default behavior is documented in the metrics functions above.
_destination = sys.stdout
return _destination
def _log(header, table, data):
log_line = "%s (%d) %s %s" \
% (header, _next_id(), table, format_notation(data))
dest = _dest()
dest.write(log_line)
dest.flush()

View File

@@ -39,6 +39,12 @@ except:
pass
_g_builder = None
def _builder():
global _g_builder
if _g_builder is None:
_g_builder = ServiceBuilder()
return _g_builder
def build(name, context={}, **kwargs):
""" Convenience method for using a global, singleton, service builder. Pass arguments either via a dict or via python keyword arguments, or both!
@@ -56,6 +62,11 @@ def build(name, context={}, **kwargs):
_g_builder = ServiceBuilder()
return _g_builder.buildServiceURL(name, context, **kwargs)
def build_path(name, context={}, **kwargs):
context = context.copy() # shouldn't modify the caller's dictionary
context.update(kwargs)
return _builder().buildPath(name, context)
class ServiceBuilder(object):
def __init__(self, services_definition = services_config):
"""\
@@ -73,12 +84,21 @@ class ServiceBuilder(object):
continue
if isinstance(service_builder, dict):
# We will be constructing several builders
for name, builder in service_builder.items():
for name, builder in service_builder.iteritems():
full_builder_name = service['name'] + '-' + name
self.builders[full_builder_name] = builder
else:
self.builders[service['name']] = service_builder
def buildPath(self, name, context):
"""\
@brief given the environment on construction, return a service path.
@param name The name of the service.
@param context A dict of name value lookups for the service.
@returns Returns the
"""
return russ.format(self.builders[name], context)
def buildServiceURL(self, name, context={}, **kwargs):
"""\
@brief given the environment on construction, return a service URL.
@@ -108,7 +128,7 @@ def on_in(query_name, host_key, schema_key):
@param schema_key Logical name of destination schema. Will
be looked up in indra.xml.
"""
host_name = config.get(host_key)
schema_name = config.get(schema_key)
return '/'.join( ('on', host_name, 'in', schema_name, query_name.lstrip('/')) )
return "on/config:%s/in/config:%s/%s" % (host_key.strip('/'),
schema_key.strip('/'),
query_name.lstrip('/'))

View File

@@ -1,3 +1,32 @@
"""\
@file siesta.py
@brief A tiny llsd based RESTful web services framework
$LicenseInfo:firstyear=2008&license=mit$
Copyright (c) 2008, Linden Research, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$/LicenseInfo$
"""
from indra.base import config
from indra.base import llsd
from webob import exc
import webob
@@ -37,11 +66,11 @@ def mime_type(content_type):
return content_type.split(';', 1)[0].strip().lower()
class BodyLLSD(object):
'''Give a webob Request or Response an llsd property.
'''Give a webob Request or Response an llsd based "content" property.
Getting the llsd property parses the body, and caches the result.
Getting the content property parses the body, and caches the result.
Setting the llsd property formats a payload, and the body property
Setting the content property formats a payload, and the body property
is set.'''
def _llsd__get(self):
@@ -80,7 +109,7 @@ class BodyLLSD(object):
if hasattr(self, '_llsd'):
del self._llsd
llsd = property(_llsd__get, _llsd__set, _llsd__del)
content = property(_llsd__get, _llsd__set, _llsd__del)
class Response(webob.Response, BodyLLSD):
@@ -114,10 +143,10 @@ class Request(webob.Request, BodyLLSD):
Sensible content type and accept headers are used by default.
Setting the llsd property also sets the body. Getting the llsd
Setting the content property also sets the body. Getting the content
property parses the body if necessary.
If you set the body property directly, the llsd property will be
If you set the body property directly, the content property will be
deleted.'''
default_content_type = 'application/llsd+xml'
@@ -149,11 +178,11 @@ class Request(webob.Request, BodyLLSD):
body = property(webob.Request._body__get, _body__set,
webob.Request._body__del, webob.Request._body__get.__doc__)
def create_response(self, llsd=None, status='200 OK',
def create_response(self, content=None, status='200 OK',
conditional_response=webob.NoDefault):
resp = self.ResponseClass(status=status, request=self,
conditional_response=conditional_response)
resp.llsd = llsd
resp.content = content
return resp
def curl(self):
@@ -196,12 +225,18 @@ llsd_formatters = {
'application/xml': llsd.format_xml,
}
formatter_qualities = (
('application/llsd+xml', 1.0),
('application/llsd+notation', 0.5),
('application/llsd+binary', 0.4),
('application/xml', 0.3),
('application/json', 0.2),
)
def formatter_for_mime_type(mime_type):
'''Return a formatter that encodes to the given MIME type.
The result is a pair of function and MIME type.'''
try:
return llsd_formatters[mime_type], mime_type
except KeyError:
@@ -214,21 +249,19 @@ def formatter_for_request(req):
'''Return a formatter that encodes to the preferred type of the client.
The result is a pair of function and actual MIME type.'''
for ctype in req.accept.best_matches('application/llsd+xml'):
try:
return llsd_formatters[ctype], ctype
except KeyError:
pass
else:
ctype = req.accept.best_match(formatter_qualities)
try:
return llsd_formatters[ctype], ctype
except KeyError:
raise exc.HTTPNotAcceptable().exception
def wsgi_adapter(func, environ, start_response):
'''Adapt a Siesta callable to act as a WSGI application.'''
# Process the request as appropriate.
try:
req = Request(environ)
#print req.urlvars
resp = func(req, **req.urlvars)
if not isinstance(resp, webob.Response):
try:
@@ -281,7 +314,8 @@ def llsd_class(cls):
allowed = [m for m in http11_methods
if hasattr(instance, 'handle_' + m.lower())]
raise exc.HTTPMethodNotAllowed(
headers={'Allowed': ', '.join(allowed)}).exception
headers={'Allow': ', '.join(allowed)}).exception
#print "kwargs: ", kwargs
return handler(req, **kwargs)
def replacement(environ, start_response):
@@ -336,7 +370,7 @@ def curl(reqs):
route_re = re.compile(r'''
\{ # exact character "{"
(\w+) # variable name (restricted to a-z, 0-9, _)
(\w*) # "config" or variable (restricted to a-z, 0-9, _)
(?:([:~])([^}]+))? # optional :type or ~regex part
\} # exact character "}"
''', re.VERBOSE)
@@ -344,27 +378,37 @@ route_re = re.compile(r'''
predefined_regexps = {
'uuid': r'[a-f0-9][a-f0-9-]{31,35}',
'int': r'\d+',
'host': r'[a-z0-9][a-z0-9\-\.]*',
}
def compile_route(route):
fp = StringIO()
last_pos = 0
for match in route_re.finditer(route):
#print "matches: ", match.groups()
fp.write(re.escape(route[last_pos:match.start()]))
var_name = match.group(1)
sep = match.group(2)
expr = match.group(3)
if expr:
if sep == ':':
expr = predefined_regexps[expr]
# otherwise, treat what follows '~' as a regexp
if var_name == 'config':
expr = re.escape(str(config.get(var_name)))
else:
expr = '[^/]+'
expr = '(?P<%s>%s)' % (var_name, expr)
if expr:
if sep == ':':
expr = predefined_regexps[expr]
# otherwise, treat what follows '~' as a regexp
else:
expr = '[^/]+'
if var_name != '':
expr = '(?P<%s>%s)' % (var_name, expr)
else:
expr = '(%s)' % (expr,)
fp.write(expr)
last_pos = match.end()
fp.write(re.escape(route[last_pos:]))
return '^%s$' % fp.getvalue()
compiled_route = '^%s$' % fp.getvalue()
#print route, "->", compiled_route
return compiled_route
class Router(object):
'''WSGI routing class. Parses a URL and hands off a request to
@@ -372,21 +416,43 @@ class Router(object):
responds with a 404.'''
def __init__(self):
self.routes = []
self.paths = []
self._new_routes = []
self._routes = []
self._paths = []
def add(self, route, app, methods=None):
self.paths.append(route)
self.routes.append((re.compile(compile_route(route)), app,
methods and dict.fromkeys(methods)))
self._new_routes.append((route, app, methods))
def _create_routes(self):
for route, app, methods in self._new_routes:
self._paths.append(route)
self._routes.append(
(re.compile(compile_route(route)),
app,
methods and dict.fromkeys(methods)))
self._new_routes = []
def __call__(self, environ, start_response):
# load up the config from the config file. Only needs to be
# done once per interpreter. This is the entry point of all
# siesta applications, so this is where we trap it.
_conf = config.get_config()
if _conf is None:
import os.path
fname = os.path.join(
environ.get('ll.config_dir', '/local/linden/etc'),
'indra.xml')
config.load(fname)
# proceed with handling the request
self._create_routes()
path_info = environ['PATH_INFO']
request_method = environ['REQUEST_METHOD']
allowed = []
for regex, app, methods in self.routes:
for regex, app, methods in self._routes:
m = regex.match(path_info)
if m:
#print "groupdict:",m.groupdict()
if not methods or request_method in methods:
environ['paste.urlvars'] = m.groupdict()
return app(environ, start_response)
@@ -396,7 +462,7 @@ class Router(object):
allowed = dict.fromkeys(allows).keys()
allowed.sort()
resp = exc.HTTPMethodNotAllowed(
headers={'Allowed': ', '.join(allowed)})
headers={'Allow': ', '.join(allowed)})
else:
resp = exc.HTTPNotFound()
return resp(environ, start_response)

View File

@@ -41,14 +41,6 @@ import tarfile
import errno
import subprocess
class ManifestError(RuntimeError):
"""Use an exception more specific than generic Python RuntimeError"""
pass
class MissingError(ManifestError):
"""You specified a file that doesn't exist"""
pass
def path_ancestors(path):
drive, path = os.path.splitdrive(os.path.normpath(path))
result = []
@@ -253,25 +245,15 @@ def main():
for opt in args:
print "Option:", opt, "=", args[opt]
# Build base package.
touch = args.get('touch')
if touch:
print 'Creating base package'
args['package_id'] = "" # base package has no package ID
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
wm.do(*args['actions'])
# Store package file for later if making touched file.
base_package_file = ""
if touch:
print 'Created base package ', wm.package_file
base_package_file = "" + wm.package_file
# Write out the package file in this format, so that it can easily be called
# and used in a .bat file - yeah, it sucks, but this is the simplest...
touch = args.get('touch')
if touch:
fp = open(touch, 'w')
fp.write('set package_file=%s\n' % base_package_file)
fp.write('set package_file=%s\n' % wm.package_file)
fp.close()
print 'touched', touch
return 0
@@ -298,13 +280,14 @@ class LLManifest(object):
self.file_list = []
self.excludes = []
self.actions = []
self.src_prefix = [args['source']]
self.artwork_prefix = [args['artwork']]
self.build_prefix = [args['build']]
self.dst_prefix = [args['dest']]
self.src_prefix = list([args['source']])
self.artwork_prefix = list([args['artwork']])
self.build_prefix = list([args['build']])
self.alt_build_prefix = list([args['build']])
self.dst_prefix = list([args['dest']])
self.created_paths = []
self.package_name = "Unknown"
def default_grid(self):
return self.args.get('grid', None) == ''
def default_channel(self):
@@ -328,7 +311,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=None, dst=None, alt_build=None):
""" Pushes a prefix onto the stack. Until end_prefix is
called, all relevant method calls (esp. to path()) will prefix
paths with the entire prefix stack. Source and destination
@@ -339,10 +322,15 @@ class LLManifest(object):
dst = src
if build is None:
build = src
if alt_build is None:
alt_build = build
self.src_prefix.append(src)
self.artwork_prefix.append(src)
self.build_prefix.append(build)
self.dst_prefix.append(dst)
self.alt_build_prefix.append(alt_build)
return True # so that you can wrap it in an if to get indentation
def end_prefix(self, descr=None):
@@ -355,25 +343,30 @@ class LLManifest(object):
src = self.src_prefix.pop()
artwork = self.artwork_prefix.pop()
build = self.build_prefix.pop()
alt_build_prefix = self.alt_build_prefix.pop()
dst = self.dst_prefix.pop()
if descr and not(src == descr or build == descr or dst == descr):
raise ValueError, "End prefix '" + descr + "' didn't match '" +src+ "' or '" +dst + "'"
def get_src_prefix(self):
""" Returns the current source prefix."""
return os.path.join(*self.src_prefix)
return os.path.relpath(os.path.normpath(os.path.join(*self.src_prefix)))
def get_artwork_prefix(self):
""" Returns the current artwork prefix."""
return os.path.join(*self.artwork_prefix)
return os.path.relpath(os.path.normpath(os.path.join(*self.artwork_prefix)))
def get_build_prefix(self):
""" Returns the current build prefix."""
return os.path.join(*self.build_prefix)
return os.path.relpath(os.path.normpath(os.path.join(*self.build_prefix)))
def get_alt_build_prefix(self):
""" Returns the current alternate source prefix."""
return os.path.relpath(os.path.normpath(os.path.join(*self.alt_build_prefix)))
def get_dst_prefix(self):
""" Returns the current destination prefix."""
return os.path.join(*self.dst_prefix)
return os.path.relpath(os.path.normpath(os.path.join(*self.dst_prefix)))
def src_path_of(self, relpath):
"""Returns the full path to a file or directory specified
@@ -390,26 +383,10 @@ class LLManifest(object):
relative to the destination directory."""
return os.path.join(self.get_dst_prefix(), relpath)
def ensure_src_dir(self, reldir):
"""Construct the path for a directory relative to the
source path, and ensures that it exists. Returns the
full path."""
path = os.path.join(self.get_src_prefix(), reldir)
self.cmakedirs(path)
return path
def ensure_dst_dir(self, reldir):
"""Construct the path for a directory relative to the
destination path, and ensures that it exists. Returns the
full path."""
path = os.path.join(self.get_dst_prefix(), reldir)
self.cmakedirs(path)
return path
def run_command(self, command):
""" Runs an external command, and returns the output. Raises
an exception if the command returns a nonzero status code. For
debugging/informational purposes, prints out the command's
an exception if the command reurns a nonzero status code. For
debugging/informational purpoases, prints out the command's
output as it is received."""
print "Running command:", command
fd = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
@@ -422,7 +399,7 @@ class LLManifest(object):
print lines[-1].rstrip('\n'),
output = ''.join(lines)
if fd.returncode:
raise ManifestError(
raise RuntimeError(
"Command %s returned non-zero status (%s) \noutput:\n%s"
% (command, fd.returncode, output) )
return output
@@ -432,24 +409,14 @@ class LLManifest(object):
a) verify that you really have created it
b) schedule it for cleanup"""
if not os.path.exists(path):
raise ManifestError, "Should be something at path " + path
raise RuntimeError, "Should be something at path " + path
self.created_paths.append(path)
def put_in_file(self, contents, dst, src=None):
def put_in_file(self, contents, dst):
# write contents as dst
dst_path = self.dst_path_of(dst)
f = open(dst_path, "wb")
try:
f.write(contents)
finally:
f.close()
# Why would we create a file in the destination tree if not to include
# it in the installer? The default src=None (plus the fact that the
# src param is last) is to preserve backwards compatibility.
if src:
self.file_list.append([src, dst_path])
return dst_path
f = open(self.dst_path_of(dst), "wb")
f.write(contents)
f.close()
def replace_in(self, src, dst=None, searchdict={}):
if dst == None:
@@ -512,29 +479,30 @@ class LLManifest(object):
if method is not None:
method(src, dst)
self.file_list.append([src, dst])
return 1
return [dst]
else:
sys.stdout.write(" (excluding %r, %r)" % (src, dst))
sys.stdout.flush()
return 0
return []
def process_directory(self, src, dst):
if not self.includes(src, dst):
sys.stdout.write(" (excluding %r, %r)" % (src, dst))
sys.stdout.flush()
return 0
return []
names = os.listdir(src)
self.cmakedirs(dst)
errors = []
found_files = []
count = 0
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
if os.path.isdir(srcname):
count += self.process_directory(srcname, dstname)
found_files.extend(self.process_directory(srcname, dstname))
else:
count += self.process_file(srcname, dstname)
return count
found_files.extend(self.process_file(srcname, dstname))
return found_files
def includes(self, src, dst):
if src:
@@ -597,7 +565,7 @@ class LLManifest(object):
except (IOError, os.error), why:
errors.append((srcname, dstname, why))
if errors:
raise ManifestError, errors
raise RuntimeError, errors
def cmakedirs(self, path):
@@ -614,25 +582,11 @@ class LLManifest(object):
if os.path.exists(f):
return f
# didn't find it, return last item in list
if len(list) > 0:
if list:
return list[-1]
else:
return None
def contents_of_tar(self, src_tar, dst_dir):
""" Extracts the contents of the tarfile (specified
relative to the source prefix) into the directory
specified relative to the destination directory."""
self.check_file_exists(src_tar)
tf = tarfile.open(self.src_path_of(src_tar), 'r')
for member in tf.getmembers():
tf.extract(member, self.ensure_dst_dir(dst_dir))
# TODO get actions working on these dudes, perhaps we should extract to a temporary directory and then process_directory on it?
self.file_list.append([src_tar,
self.dst_path_of(os.path.join(dst_dir,member.name))])
tf.close()
def wildcard_regex(self, src_glob, dst_glob):
src_re = re.escape(src_glob)
src_re = src_re.replace('\*', '([-a-zA-Z0-9._ ]*)')
@@ -643,12 +597,7 @@ class LLManifest(object):
i = i+1
return re.compile(src_re), dst_temp
def check_file_exists(self, path):
if not os.path.exists(path) and not os.path.islink(path):
raise MissingError("Path %s doesn't exist" % (os.path.abspath(path),))
wildcard_pattern = re.compile(r'\*')
wildcard_pattern = re.compile('\*')
def expand_globs(self, src, dst):
src_list = glob.glob(src)
src_re, d_template = self.wildcard_regex(src.replace('\\', '/'),
@@ -675,53 +624,44 @@ class LLManifest(object):
return self.path(os.path.join(path, file), file)
def path(self, src, dst=None):
sys.stdout.write("Processing %s => %s ... " % (src, dst))
sys.stdout.flush()
if src == None:
raise ManifestError("No source file, dst is " + dst)
raise RuntimeError("No source file, dst is " + dst)
if dst == None:
dst = src
dst = os.path.join(self.get_dst_prefix(), dst)
sys.stdout.write("Processing %s => %s ... " % (src, dst))
count = 0
is_glob = False
found_files = []
def try_path(src):
# expand globs
count = 0
if self.wildcard_pattern.search(src):
for s,d in self.expand_globs(src, dst):
# look under each prefix for matching paths. Paths are normalized so './../blah' will match '../blah/../blah/'
paths = set([os.path.normpath(os.path.join(self.get_src_prefix(), src)),
os.path.normpath(os.path.join(self.get_artwork_prefix(), src)),
os.path.normpath(os.path.join(self.get_build_prefix(), src)),
os.path.normpath(os.path.join(self.get_alt_build_prefix(), src))]
)
for path in paths:
print path
if self.wildcard_pattern.search(path):
is_glob = True
for s,d in self.expand_globs(path, dst):
assert(s != d)
count += self.process_file(s, d)
found_files.extend(self.process_file(s, d))
else:
# if we're specifying a single path (not a glob),
# we should error out if it doesn't exist
self.check_file_exists(src)
# if it's a directory, recurse through it
if os.path.isdir(src):
count += self.process_directory(src, dst)
else:
count += self.process_file(src, dst)
return count
if os.path.isdir(path):
found_files.extend(self.process_directory(path, dst))
elif os.path.exists(path):
found_files.extend(self.process_file(path, dst))
for pfx in self.get_src_prefix(), self.get_artwork_prefix(), self.get_build_prefix():
try:
count = try_path(os.path.join(pfx, src))
except MissingError:
# If src isn't a wildcard, and if that file doesn't exist in
# this pfx, try next pfx.
count = 0
continue
# if we're specifying a single path (not a glob),
# we should error out if it doesn't exist
if not found_files and not is_glob:
raise RuntimeError("No files match %s\n" % str(paths))
# Here try_path() didn't raise MissingError. Did it process any files?
if count:
break
# Even though try_path() didn't raise MissingError, it returned 0
# files. src is probably a wildcard meant for some other pfx. Loop
# back to try the next.
print "%d files" % count
# Let caller check whether we processed as many files as expected. In
# particular, let caller notice 0.
return count
print "%d files" % len(found_files)
return found_files
def do(self, *actions):
self.actions = actions

View File

@@ -1,4 +1,28 @@
#!/usr/bin/python
#!/usr/bin/env python
"""\
@file llperformance.py
$LicenseInfo:firstyear=2010&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2010-2011, Linden Research, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License only.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
$/LicenseInfo$
"""
# ------------------------------------------------
# Sim metrics utility functions.

View File

@@ -90,6 +90,17 @@ all the output, and get the result.
child.tochild.close()
result = child.poll()
if result != -1:
# At this point, the child process has exited and result
# is the return value from the process. Between the time
# we called select() and poll() the process may have
# exited so read all the data left on the child process
# stdout and stderr.
last = child.fromchild.read()
if last:
out.append(last)
last = child.childerr.read()
if last:
err.append(last)
child.tochild.close()
child.fromchild.close()
child.childerr.close()

View File

@@ -40,7 +40,6 @@ from indra.base import llsd
from indra.base import config
DEBUG = False
NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq')
NQ_FILE_SUFFIX_LEN = len(NQ_FILE_SUFFIX)
@@ -52,6 +51,11 @@ def _init_g_named_manager(sql_dir = None):
This function is intended entirely for testing purposes,
because it's tricky to control the config from inside a test."""
global NQ_FILE_SUFFIX
NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq')
global NQ_FILE_SUFFIX_LEN
NQ_FILE_SUFFIX_LEN = len(NQ_FILE_SUFFIX)
if sql_dir is None:
sql_dir = config.get('named-query-base-dir')
@@ -65,11 +69,11 @@ def _init_g_named_manager(sql_dir = None):
_g_named_manager = NamedQueryManager(
os.path.abspath(os.path.realpath(sql_dir)))
def get(name):
def get(name, schema = None):
"Get the named query object to be used to perform queries"
if _g_named_manager is None:
_init_g_named_manager()
return _g_named_manager.get(name)
return _g_named_manager.get(name).for_schema(schema)
def sql(connection, name, params):
# use module-global NamedQuery object to perform default substitution
@@ -280,7 +284,10 @@ class NamedQuery(object):
So, we need a vendor (or extention) for LIKE_STRING. Anyone
want to write it?"""
utf8_value = unicode(value, "utf-8")
if isinstance(value, unicode):
utf8_value = value
else:
utf8_value = unicode(value, "utf-8")
esc_list = []
remove_chars = set(u"%_")
for glyph in utf8_value:
@@ -317,6 +324,8 @@ class NamedQuery(object):
def for_schema(self, db_name):
"Look trough the alternates and return the correct query"
if db_name is None:
return self
try:
return self._alternative[db_name]
except KeyError, e:
@@ -341,21 +350,21 @@ class NamedQuery(object):
cursor = connection.cursor(MySQLdb.cursors.DictCursor)
else:
cursor = connection.cursor()
statement = self.sql(connection, params)
full_query, params = self._construct_sql(params)
if DEBUG:
print "SQL:", statement
rows = cursor.execute(statement)
print "SQL:", self.sql(connection, params)
rows = cursor.execute(full_query, params)
# *NOTE: the expect_rows argument is a very cheesy way to get some
# validation on the result set. If you want to add more expectation
# logic, do something more object-oriented and flexible. Or use an ORM.
# logic, do something more object-oriented and flexible. Or use an ORM.
if(self._return_as_map):
expect_rows = 1
if expect_rows is not None and rows != expect_rows:
cursor.close()
raise ExpectationFailed("Statement expected %s rows, got %s. Sql: %s" % (
expect_rows, rows, statement))
raise ExpectationFailed("Statement expected %s rows, got %s. Sql: '%s' %s" % (
expect_rows, rows, full_query, params))
# convert to dicts manually if we're not using a dictcursor
if use_dictcursor:
@@ -381,11 +390,9 @@ class NamedQuery(object):
return result_set[0]
return result_set
def sql(self, connection, params):
""" Generates an SQL statement from the named query document
and a dictionary of parameters.
"""
def _construct_sql(self, params):
""" Returns a query string and a dictionary of parameters,
suitable for directly passing to the execute() method."""
self.refresh()
# build the query from the options available and the params
@@ -431,10 +438,23 @@ class NamedQuery(object):
new_params[self._build_integer_key(key)] = int(params[key])
params.update(new_params)
return full_query, params
def sql(self, connection, params):
""" Generates an SQL statement from the named query document
and a dictionary of parameters.
*NOTE: Only use for debugging, because it uses the
non-standard MySQLdb 'literal' method.
"""
if not DEBUG:
import warnings
warnings.warn("Don't use named_query.sql() when not debugging. Used on %s" % self._location)
# do substitution using the mysql (non-standard) 'literal'
# function to do the escaping.
sql = full_query % connection.literal(params)
return sql
full_query, params = self._construct_sql(params)
return full_query % connection.literal(params)
def refresh(self):
""" Refresh self from the file on the filesystem.

View File

@@ -3,20 +3,27 @@
@file simperf_oprof_interface.py
@brief Manage OProfile data collection on a host
$LicenseInfo:firstyear=2008&license=internal$
$LicenseInfo:firstyear=2008&license=mit$
Copyright (c) 2008-2009, Linden Research, Inc.
The following source code is PROPRIETARY AND CONFIDENTIAL. Use of
this source code is governed by the Linden Lab Source Code Disclosure
Agreement ("Agreement") previously entered between you and Linden
Lab. By accessing, using, copying, modifying or distributing this
software, you acknowledge that you have been informed of your
obligations under the Agreement and agree to abide by those obligations.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
COMPLETENESS OR PERFORMANCE.
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$/LicenseInfo$
"""

View File

@@ -1,4 +1,31 @@
#!/usr/bin/python
#!/usr/bin/env python
"""\
@file simperf_proc_interface.py
@brief Utility to extract log messages from *.<pid>.llsd files containing performance statistics.
$LicenseInfo:firstyear=2008&license=mit$
Copyright (c) 2008-2009, Linden Research, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
$/LicenseInfo$
"""
# ----------------------------------------------------
# Utility to extract log messages from *.<pid>.llsd

View File

@@ -0,0 +1,146 @@
#!/usr/bin/env python
"""\
@file test_win32_manifest.py
@brief Test an assembly binding version and uniqueness in a windows dll or exe.
$LicenseInfo:firstyear=2009&license=viewerlgpl$
Second Life Viewer Source Code
Copyright (C) 2009-2011, Linden Research, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation;
version 2.1 of the License only.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
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, os
import tempfile
from xml.dom.minidom import parse
class AssemblyTestException(Exception):
pass
class NoManifestException(AssemblyTestException):
pass
class MultipleBindingsException(AssemblyTestException):
pass
class UnexpectedVersionException(AssemblyTestException):
pass
class NoMatchingAssemblyException(AssemblyTestException):
pass
def get_HKLM_registry_value(key_str, value_str):
import _winreg
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
key = _winreg.OpenKey(reg, key_str)
value = _winreg.QueryValueEx(key, value_str)[0]
#print 'Found: %s' % value
return value
def find_vc_dir():
supported_versions = (r'8.0', r'9.0')
supported_products = (r'VisualStudio', r'VCExpress')
value_str = (r'ProductDir')
for product in supported_products:
for version in supported_versions:
key_str = (r'SOFTWARE\Microsoft\%s\%s\Setup\VC' %
(product, version))
try:
return get_HKLM_registry_value(key_str, value_str)
except WindowsError, err:
x64_key_str = (r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%s\Setup\VS' %
version)
try:
return get_HKLM_registry_value(x64_key_str, value_str)
except:
print >> sys.stderr, "Didn't find MS %s version %s " % (product,version)
raise
def find_mt_path():
vc_dir = find_vc_dir()
mt_path = '\"%sbin\\mt.exe\"' % vc_dir
return mt_path
def test_assembly_binding(src_filename, assembly_name, assembly_ver):
print "checking %s dependency %s..." % (src_filename, assembly_name)
(tmp_file_fd, tmp_file_name) = tempfile.mkstemp(suffix='.xml')
tmp_file = os.fdopen(tmp_file_fd)
tmp_file.close()
mt_path = find_mt_path()
resource_id = ""
if os.path.splitext(src_filename)[1].lower() == ".dll":
resource_id = ";#2"
system_call = '%s -nologo -inputresource:%s%s -out:%s > NUL' % (mt_path, src_filename, resource_id, tmp_file_name)
print "Executing: %s" % system_call
mt_result = os.system(system_call)
if mt_result == 31:
print "No manifest found in %s" % src_filename
raise NoManifestException()
manifest_dom = parse(tmp_file_name)
nodes = manifest_dom.getElementsByTagName('assemblyIdentity')
versions = list()
for node in nodes:
if node.getAttribute('name') == assembly_name:
versions.append(node.getAttribute('version'))
if len(versions) == 0:
print "No matching assemblies found in %s" % src_filename
raise NoMatchingAssemblyException()
elif len(versions) > 1:
print "Multiple bindings to %s found:" % assembly_name
print versions
print
raise MultipleBindingsException(versions)
elif versions[0] != assembly_ver:
print "Unexpected version found for %s:" % assembly_name
print "Wanted %s, found %s" % (assembly_ver, versions[0])
print
raise UnexpectedVersionException(assembly_ver, versions[0])
os.remove(tmp_file_name)
print "SUCCESS: %s OK!" % src_filename
print
if __name__ == '__main__':
print
print "Running test_win32_manifest.py..."
usage = 'test_win32_manfest <srcFileName> <assemblyName> <assemblyVersion>'
try:
src_filename = sys.argv[1]
assembly_name = sys.argv[2]
assembly_ver = sys.argv[3]
except:
print "Usage:"
print usage
print
raise
test_assembly_binding(src_filename, assembly_name, assembly_ver)

View File

@@ -45,13 +45,6 @@ Typical usage:
This module works with Python 2.3 or higher."""
# *HACK: Necessary for python 2.4. Consider replacing this code wart
# after python >=2.5 has deployed everywhere. 2009-10-05
try:
from hashlib import md5
except ImportError:
from md5 import md5
__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
__date__ = '$Date: 2006/06/12 23:15:40 $'.split()[1].replace('/', '-')
__version__ = '$Revision: 1.30 $'.split()[1]
@@ -453,6 +446,13 @@ def uuid1(node=None, clock_seq=None):
def uuid3(namespace, name):
"""Generate a UUID from the MD5 hash of a namespace UUID and a name."""
try:
# Python 2.6
from hashlib import md5
except ImportError:
# Python 2.5 and earlier
from md5 import new as md5
hash = md5(namespace.bytes + name).digest()
return UUID(bytes=hash[:16], version=3)

View File

@@ -1301,13 +1301,6 @@ if (WINDOWS)
winspool
)
if(FMODSTUDIO)
list(APPEND viewer_LIBRARIES ${FMODSTUDIO_LIBRARY})
endif(FMODSTUDIO)
if(FMODEX)
list(APPEND viewer_LIBRARIES ${FMODEX_LIBRARY})
endif(FMODEX)
find_library(DEBUG_INTEL_MEMOPS_LIBRARY ll_intel_memops
PATHS
${LIBS_PREBUILT_DIR}/lib/debug
@@ -1411,20 +1404,16 @@ if (WINDOWS)
list(APPEND viewer_SOURCE_FILES ${viewer_INSTALLER_FILES})
endif (WINDOWS)
if (FMODSTUDIO)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO")
endif (FMODSTUDIO)
if (FMODEX)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
endif (FMODEX)
if (OPENAL)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
endif (OPENAL)
if (FMODSTUDIO)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO")
set(FMODWRAPPER_LIBRARY ${FMODSTUDIO_LIBRARY})
endif (FMODSTUDIO)
if (FMODEX)
set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODEX")
set(FMODWRAPPER_LIBRARY ${FMODEX_LIBRARY})
endif (FMODEX)
set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
@@ -1445,44 +1434,45 @@ endif (!DISABLE_TEMPLATE_CHECK)
set(PACKAGE OFF CACHE BOOL
"Add a package_viewer target that builds an installer package.")
if(FMOD_LIBRARY_RELEASE)
get_filename_component(fmod_lib_rel_name ${FMOD_LIBRARY_RELEASE} NAME)
get_filename_component(fmod_lib_deb_name ${FMOD_LIBRARY_DEBUG} NAME)
add_custom_command(OUTPUT fmod_lib.marker
COMMENT "Copying fmod library to executable directory"
COMMAND ${CMAKE_COMMAND} -E copy_if_different "$<$<NOT:$<CONFIG:debug>>:${FMOD_LIBRARY_RELEASE}>$<$<CONFIG:debug>:${FMOD_LIBRARY_DEBUG}>" "${CMAKE_CFG_INTDIR}/$<$<NOT:$<CONFIG:debug>>:${fmod_lib_rel_name}>$<$<CONFIG:debug>:${fmod_lib_deb_name}>"
DEPENDS "${FMOD_LIBRARY_RELEASE}")
add_custom_target(fmod_lib_copy DEPENDS fmod_lib.marker prepare)
if(DARWIN)
add_custom_command(OUTPUT fmod_lib_install.marker
COMMAND install_name_tool -id "@executable_path/../Resources/$<$<NOT:$<CONFIG:debug>>:${fmod_lib_rel_name}>$<$<CONFIG:debug>:${FMOD_LIBRARY_DEBUG}>" "${CMAKE_CFG_INTDIR}/$<$<NOT:$<CONFIG:debug>>:${fmod_lib_rel_name}>$<$<CONFIG:debug>:${fmod_lib_deb_name}>"
DEPENDS fmod_lib.marker)
add_dependencies(fmod_lib_copy fmod_lib_install.marker)
endif(DARWIN)
add_dependencies(${VIEWER_BINARY_NAME} fmod_lib_copy)
#viewer_manifest.py needs these libraries (for now its all dynlib)
if(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "${MANIFEST_LIBRARIES}|optimized ${fmod_lib_rel_name}|debug ${fmod_lib_deb_name}")
else(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "--extra_libraries=optimized ${fmod_lib_rel_name}|debug ${fmod_lib_deb_name}")
endif(MANIFEST_LIBRARIES)
if(WINDOWS) #If windows, fmod_lib_<config> points to a dll. The correct .lib needs to be linked (but copying is not necessary)
set(EXTRA_LINKER_FLAGS_RELEASE "/DELAYLOAD:${fmod_lib_rel_name}")
set(EXTRA_LINKER_FLAGS_DEBUG "/DELAYLOAD:${fmod_lib_deb_name}")
endif(WINDOWS)
list(APPEND viewer_LIBRARIES optimized "${FMOD_LINK_LIBRARY_RELEASE}" debug "${FMOD_LINK_LIBRARY_DEBUG}" )
endif(FMOD_LIBRARY_RELEASE)
if (WINDOWS)
set(release_flags "/MAPRelease/${VIEWER_BINARY_NAME}.map")
if (FMODSTUDIO)
if (WORD_SIZE EQUAL 32)
set(fmodstudio_dll_file "fmod.dll")
else (WORD_SIZE EQUAL 32)
set(fmodstudio_dll_file "fmod64.dll")
endif (WORD_SIZE EQUAL 32)
if(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "${MANIFEST_LIBRARIES}|${fmodstudio_dll_file}")
else(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "--extra_libraries=${fmodstudio_dll_file}")
endif(MANIFEST_LIBRARIES)
set(EXTRA_LINKER_FLAGS "/DELAYLOAD:${fmodstudio_dll_file}")
endif (FMODSTUDIO)
if (FMODEX)
if (WORD_SIZE EQUAL 32)
set(fmodex_dll_file "fmodex.dll")
else (WORD_SIZE EQUAL 32)
set(fmodex_dll_file "fmodex64.dll")
endif (WORD_SIZE EQUAL 32)
if(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "${MANIFEST_LIBRARIES}|${fmodex_dll_file}")
else(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "--extra_libraries=${fmodex_dll_file}")
endif(MANIFEST_LIBRARIES)
set(EXTRA_LINKER_FLAGS "/DELAYLOAD:${fmodex_dll_file}")
endif (FMODEX)
set(release_flags "/MAP")
set_target_properties(${VIEWER_BINARY_NAME}
PROPERTIES
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${GOOGLE_PERFTOOLS_LINKER_FLAGS} ${EXTRA_LINKER_FLAGS}"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
LINK_FLAGS_RELEASE ${release_flags}
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS ${GOOGLE_PERFTOOLS_LINKER_FLAGS}"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" ${EXTRA_LINKER_FLAGS_DEBUG}"
LINK_FLAGS_RELEASE "${release_flags} ${EXTRA_LINKER_FLAGS_RELEASE}"
LINK_FLAGS_RELWITHDEBINFO "${release_flags} ${EXTRA_LINKER_FLAGS_RELEASE}"
)
# sets the 'working directory' for debugging from visual studio.
@@ -1621,7 +1611,6 @@ target_link_libraries(${VIEWER_BINARY_NAME}
${Boost_DATE_TIME_LIBRARY}
${DBUSGLIB_LIBRARIES}
${OPENGL_LIBRARIES}
${FMODWRAPPER_LIBRARY} # must come after LLAudio
${GLOD_LIBRARIES}
${APRUTIL_LIBRARIES}
${OPENGL_LIBRARIES}
@@ -1647,22 +1636,6 @@ if (LINUX)
set(product ${VIEWER_BRANDING_NAME_CAMELCASE}-${ARCH}-${viewer_VERSION})
if (FMODSTUDIO)
if(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "${MANIFEST_LIBRARIES}|${FMODSTUDIO_LIBRARY}")
else(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "--extra_libraries=${FMODSTUDIO_LIBRARY}")
endif(MANIFEST_LIBRARIES)
endif (FMODSTUDIO)
if (FMODEX)
if(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "${MANIFEST_LIBRARIES}|${FMODEX_LIBRARY}")
else(MANIFEST_LIBRARIES)
set(MANIFEST_LIBRARIES "--extra_libraries=${FMODEX_LIBRARY}")
endif(MANIFEST_LIBRARIES)
endif (FMODEX)
add_custom_command(
OUTPUT ${product}.tar.bz2
COMMAND ${PYTHON_EXECUTABLE}
@@ -1755,24 +1728,6 @@ if (DARWIN)
add_dependencies(${VIEWER_BINARY_NAME} SLPlugin media_plugin_quicktime media_plugin_webkit basic_plugin_filepicker)
if (FMODSTUDIO)
add_custom_command(OUTPUT "${FMODSTUDIO_LIBRARY}"
COMMAND cp "${FMODSTUDIO_ORIG_LIBRARY}" "${FMODSTUDIO_LIBRARY}"
COMMAND install_name_tool -id "@executable_path/../Resources/libfmod.dylib" ${FMODSTUDIO_LIBRARY}
DEPENDS "${FMODSTUDIO_ORIG_LIBRARY}")
add_custom_target(fmodstudio_modified_library DEPENDS "${FMODSTUDIO_LIBRARY}")
add_dependencies(${VIEWER_BINARY_NAME} fmodstudio_modified_library)
endif (FMODSTUDIO)
if (FMODEX)
add_custom_command(OUTPUT "${FMODEX_LIBRARY}"
COMMAND cp "${FMODEX_ORIG_LIBRARY}" "${FMODEX_LIBRARY}"
COMMAND install_name_tool -id "@executable_path/../Resources/libfmodex.dylib" ${FMODEX_LIBRARY}
DEPENDS "${FMODEX_ORIG_LIBRARY}")
add_custom_target(fmodex_modified_library DEPENDS "${FMODEX_LIBRARY}")
add_dependencies(${VIEWER_BINARY_NAME} fmodex_modified_library)
endif (FMODEX)
if (PACKAGE)
add_custom_target(package_viewer ALL DEPENDS ${VIEWER_BINARY_NAME})
@@ -1817,9 +1772,9 @@ if (PACKAGE)
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
# *TODO: Generate these search dirs in the cmake files related to each binary.
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/llplugin/slplugin/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/quicktime/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/media_plugins/webkit/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/plugins/gstreamer010/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/plugins/quicktime/${CMAKE_CFG_INTDIR}")
list(APPEND SYMBOL_SEARCH_DIRS "${CMAKE_BINARY_DIR}/plugins/webkit/${CMAKE_CFG_INTDIR}")
set(VIEWER_SYMBOL_FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/secondlife-symbols-darwin.tar.bz2")
set(VIEWER_EXE_GLOBS "'${VIEWER_BRANDING_NAME}' SLPlugin")
set(VIEWER_LIB_GLOB "*.dylib")
@@ -1897,8 +1852,10 @@ if (WINDOWS)
set_target_properties(llcommon
PROPERTIES
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /LTCG"
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT"
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\""
LINK_FLAGS_RELEASE "${release_flags} /LTCG"
LINK_FLAGS_RELWITHDEBINFO "${release_flags}"
)
add_custom_command(

View File

@@ -176,6 +176,42 @@ class ViewerManifest(LLManifest):
def icon_path(self):
return "../../indra/newview/res/"
def path_optional(self, src, dst=None):
"""
For a number of our self.path() calls, not only do we want
to deal with the absence of src, we also want to remember
which were present. Return either an empty list (absent)
or a list containing dst (present). Concatenate these
return values to get a list of all libs that are present.
"""
found_files = []
try:
found_files = self.path(src, dst)
except RuntimeError, err:
pass
if not found_files:
print "Skipping %s" % dst
return found_files
def add_extra_libraries(self):
found_libs = []
if 'extra_libraries' in self.args:
path_list = self.args['extra_libraries'].split('|')
for cur_path in path_list:
config, file = cur_path.split(' ', 1)
if(config == 'optimized'):
if(self.args['configuration'].lower() != 'release' and self.args['configuration'].lower() != 'relwithdebinfo'):
continue
cur_path = file
if(config == 'debug'):
if(self.args['configuration'].lower() != 'debug'):
continue
cur_path = file
if(cur_path != None):
found_libs += self.path_optional(cur_path)
return found_libs
class WindowsManifest(ViewerManifest):
def is_win64(self):
return self.args.get('arch') == "x86_64"
@@ -189,56 +225,75 @@ class WindowsManifest(ViewerManifest):
# the final exe is complicated because we're not sure where it's coming from,
# nor do we have a fixed name for the executable
self.path(src='%s/secondlife-bin.exe' % self.args['configuration'], dst=self.final_exe())
release_lib_dir = "Release"
# Plugin host application
self.path2basename(os.path.join(os.pardir,
'llplugin', 'slplugin', self.args['configuration']),
"SLplugin.exe")
# Plugin volume control
if not self.is_win64() and self.prefix(src=self.args['configuration'], dst=""):
self.path("winmm.dll")
# Get llcommon and deps. If missing assume static linkage and continue.
if self.prefix(src=self.args['configuration'], dst=""):
try:
self.path('llcommon.dll')
except RuntimeError, err:
print err.message
print "Skipping llcommon.dll (assuming llcommon was linked statically)"
try:
self.path('libapr-1.dll')
self.path('libaprutil-1.dll')
self.path('libapriconv-1.dll')
except RuntimeError, err:
pass
# For mesh upload
if not self.is_win64():
self.path("libcollada14dom22.dll")
self.path("glod.dll")
self.add_extra_libraries()
try:
self.path("msvc*.dll")
except:
try:
if self.prefix(src="msvcrt", dst=""):
self.path("*.dll")
self.path("*.manifest")
self.end_prefix()
except:
pass
# Vivox runtimes
self.path("SLVoice.exe")
self.path("vivoxsdk.dll")
self.path("ortp.dll")
self.path("libsndfile-1.dll")
self.path("zlib1.dll")
self.path("vivoxplatform.dll")
self.path("vivoxoal.dll")
self.path("ca-bundle.crt")
# Security
self.path("ssleay32.dll")
self.path("libeay32.dll")
# For spellchecking
self.path("libhunspell.dll")
# For google-perftools tcmalloc allocator.
if not self.is_win64():
try:
self.path('libtcmalloc_minimal.dll')
except:
print "Skipping libtcmalloc_minimal.dll"
self.end_prefix()
self.path(src="licenses-win32.txt", dst="licenses.txt")
self.path("featuretable.txt")
# For spellchecking
if self.prefix(src=self.args['configuration'], dst=""):
self.path("libhunspell.dll")
self.end_prefix()
# For mesh upload
if not self.is_win64() and self.prefix(src=self.args['configuration'], dst=""):
self.path("libcollada14dom22.dll")
self.end_prefix()
if self.prefix(src=self.args['configuration'], dst=""):
self.path("glod.dll")
self.end_prefix()
# For use in crash reporting (generates minidumps)
#self.path("dbghelp.dll")
#is shipped with windows anyway
# For using FMOD for sound... DJS
#~if self.prefix(src=release_lib_dir, dst=""):
#~try:
#~self.path("fmod.dll")
#~pass
#~except:
#~print "Skipping fmod.dll - not found"
#~ pass
#~self.end_prefix()
# For textures
#if self.prefix(src=release_lib_dir, dst=""):
# self.path("openjpeg.dll")
# self.end_prefix()
# Plugins - FilePicker
if self.prefix(src='../plugins/filepicker/%s' % self.args['configuration'], dst="llplugin"):
self.path("basic_plugin_filepicker.dll")
@@ -254,8 +309,13 @@ class WindowsManifest(ViewerManifest):
self.path("media_plugin_webkit.dll")
self.end_prefix()
# Plugin volume control
if not self.is_win64() and self.prefix(src='../plugins/winmmshim/%s' % self.args['configuration'], dst=""):
self.path("winmm.dll")
self.end_prefix()
# For WebKit/Qt plugin runtimes
if self.prefix(src=release_lib_dir+"/llplugin", dst="llplugin"):
if self.prefix(src=self.args['configuration']+"/llplugin", dst="llplugin"):
self.path("libeay32.dll")
self.path("qtcore4.dll")
self.path("qtgui4.dll")
@@ -264,82 +324,29 @@ class WindowsManifest(ViewerManifest):
self.path("qtwebkit4.dll")
self.path("qtxmlpatterns4.dll")
self.path("ssleay32.dll")
# For WebKit/Qt plugin runtimes (image format plugins)
if self.prefix(src="imageformats", dst="imageformats"):
self.path("qgif4.dll")
self.path("qico4.dll")
self.path("qjpeg4.dll")
self.path("qmng4.dll")
self.path("qsvg4.dll")
self.path("qtiff4.dll")
self.end_prefix()
if self.prefix(src="codecs", dst="codecs"):
self.path("qcncodecs4.dll")
self.path("qjpcodecs4.dll")
self.path("qkrcodecs4.dll")
self.path("qtwcodecs4.dll")
self.end_prefix()
self.end_prefix()
# For WebKit/Qt plugin runtimes (image format plugins)
if self.prefix(src=release_lib_dir+"/llplugin/imageformats", dst="llplugin/imageformats"):
self.path("qgif4.dll")
self.path("qico4.dll")
self.path("qjpeg4.dll")
self.path("qmng4.dll")
self.path("qsvg4.dll")
self.path("qtiff4.dll")
self.end_prefix()
if self.prefix(src=release_lib_dir+"/llplugin/codecs", dst="llplugin/codecs"):
self.path("qcncodecs4.dll")
self.path("qjpcodecs4.dll")
self.path("qkrcodecs4.dll")
self.path("qtwcodecs4.dll")
self.end_prefix()
# Get llcommon and deps. If missing assume static linkage and continue.
if self.prefix(src=self.args['configuration'], dst=""):
try:
self.path('llcommon.dll')
except RuntimeError, err:
print err.message
print "Skipping llcommon.dll (assuming llcommon was linked statically)"
self.end_prefix()
if self.prefix(src=release_lib_dir, dst=""):
self.path("libeay32.dll")
self.path("ssleay32.dll")
try:
self.path('libapr-1.dll')
self.path('libaprutil-1.dll')
self.path('libapriconv-1.dll')
except RuntimeError, err:
pass
self.end_prefix()
# For google-perftools tcmalloc allocator.
if not self.is_win64():
self.path(release_lib_dir+"/libtcmalloc_minimal.dll", dst="libtcmalloc_minimal.dll")
try:
self.path("msvc*.dll")
except:
try:
if self.prefix(src=release_lib_dir+"/msvcrt", dst=""):
self.path("*.dll")
self.path("*.manifest")
self.end_prefix()
except:
pass
# Vivox runtimes
if self.prefix(src=release_lib_dir, dst=""):
self.path("SLVoice.exe")
self.path("ca-bundle.crt")
self.path("libsndfile-1.dll")
self.path("ortp.dll")
self.path("vivoxoal.dll")
self.path("vivoxplatform.dll")
self.path("vivoxsdk.dll")
self.path("zlib1.dll")
self.end_prefix()
if 'extra_libraries' in self.args:
print self.args['extra_libraries']
path_list = self.args['extra_libraries'].split('|')
for path in path_list:
if self.prefix(src=release_lib_dir, dst=""):
self.path(path)
self.end_prefix()
self.package_file = 'none'
def nsi_file_commands(self, install=True):
def wpath(path):
if path.endswith('/') or path.endswith(os.path.sep):
@@ -357,7 +364,7 @@ class WindowsManifest(ViewerManifest):
for pkg_file in dest_files:
rel_file = os.path.normpath(pkg_file.replace(self.get_dst_prefix()+os.path.sep,''))
installed_dir = wpath(os.path.join('$INSTDIR', os.path.dirname(rel_file)))
pkg_file = wpath(os.path.normpath(pkg_file))
pkg_file = wpath(os.path.join(os.pardir,os.path.normpath(pkg_file)))
if installed_dir != out_path:
if install:
out_path = installed_dir
@@ -392,22 +399,6 @@ class WindowsManifest(ViewerManifest):
mask = "%s_%s_Setup.exe"
return mask % (self.channel_oneword(), '-'.join(self.args['version']))
def sign_command(self, *argv):
return [
"signtool.exe",
"sign", "/v",
"/f",os.environ['VIEWER_SIGNING_KEY'],
"/p",os.environ['VIEWER_SIGNING_PASSWORD'],
"/d","%s" % self.channel(),
"/du",os.environ['VIEWER_SIGNING_URL'],
"/t","http://timestamp.comodoca.com/authenticode"
] + list(argv)
def sign(self, *argv):
subprocess.check_call(self.sign_command(*argv))
def package_finish(self):
# a standard map of strings for replacing in the templates
substitution_strings = {
@@ -454,20 +445,12 @@ class WindowsManifest(ViewerManifest):
installer_file = installer_file % substitution_strings
substitution_strings['installer_file'] = installer_file
# Sign the binaries
if 'VIEWER_SIGNING_PASSWORD' in os.environ:
try:
self.sign(self.args['configuration']+"\\"+self.final_exe())
self.sign(self.args['configuration']+"\\SLPlugin.exe")
self.sign(self.args['configuration']+"\\SLVoice.exe")
except Exception, e:
print "Couldn't sign binaries. Tried to sign %s" % self.args['configuration'] + "\\" + self.final_exe() + "\nException: %s" % e
tempfile = "secondlife_setup_tmp.nsi"
# the following replaces strings in the nsi template
# it also does python-style % substitution
self.replace_in("installers/windows/installer_template.nsi", tempfile, {
"%%VERSION%%":version_vars,
"%%SOURCE%%":self.get_src_prefix(),
"%%SOURCE%%":os.path.abspath(self.get_src_prefix()),
"%%GRID_VARS%%":grid_vars_template % substitution_strings,
"%%INSTALL_FILES%%":self.nsi_file_commands(True),
"%%DELETE_FILES%%":self.nsi_file_commands(False),
@@ -489,14 +472,14 @@ class WindowsManifest(ViewerManifest):
NSIS_path = os.environ['ProgramFiles(X86)'] + '\\NSIS\\Unicode\\makensis.exe'
self.run_command([proper_windows_path(NSIS_path),self.dst_path_of(tempfile)])
# self.remove(self.dst_path_of(tempfile))
# Sign the installer
if 'VIEWER_SIGNING_PASSWORD' in os.environ:
try:
self.sign(self.args['configuration'] + "\\" + substitution_strings['installer_file'])
except Exception, e:
print "Couldn't sign windows installer. Tried to sign %s" % self.args['configuration'] + "\\" + substitution_strings['installer_file'] + "\nException: %s" % e
# If we're on a build machine, sign the code using our Authenticode certificate. JC
sign_py = os.path.expandvars("{SIGN_PY}")
if sign_py == "" or sign_py == "{SIGN_PY}":
sign_py = 'C:\\buildscripts\\code-signing\\sign.py'
if os.path.exists(sign_py):
self.run_command('python ' + sign_py + ' ' + self.dst_path_of(installer_file))
else:
print "Skipping code signing,", sign_py, "does not exist"
self.created_path(self.dst_path_of(installer_file))
self.package_file = installer_file
@@ -508,10 +491,6 @@ class DarwinManifest(ViewerManifest):
if self.prefix(src="", dst="Contents"): # everything goes in Contents
# copy additional libs in <bundle>/Contents/MacOS/
self.path("../packages/libraries/universal-darwin/lib/release/libndofdev.dylib", dst="Resources/libndofdev.dylib")
self.path("../packages/libraries/universal-darwin/lib/release/libhunspell-1.3.0.dylib", dst="Resources/libhunspell-1.3.0.dylib")
# most everything goes in the Resources directory
if self.prefix(src="", dst="Resources"):
super(DarwinManifest, self).construct()
@@ -547,20 +526,8 @@ class DarwinManifest(ViewerManifest):
self.path("uk.lproj")
self.path("zh-Hans.lproj")
def path_optional(src, dst):
"""
For a number of our self.path() calls, not only do we want
to deal with the absence of src, we also want to remember
which were present. Return either an empty list (absent)
or a list containing dst (present). Concatenate these
return values to get a list of all libs that are present.
"""
if self.path(src, dst):
return [dst]
print "Skipping %s" % dst
return []
libdir = "../packages/libraries/universal-darwin/lib/release"
libdir = "../packages/lib/release"
alt_libdir = "../packages/libraries/universal-darwin/lib/release"
# dylibs is a list of all the .dylib files we expect to need
# in our bundled sub-apps. For each of these we'll create a
# symlink from sub-app/Contents/Resources to the real .dylib.
@@ -568,57 +535,40 @@ class DarwinManifest(ViewerManifest):
libfile = "libllcommon.dylib"
dylibs = path_optional(self.find_existing_file(os.path.join(os.pardir,
dylibs = self.path_optional(self.find_existing_file(os.path.join(os.pardir,
"llcommon",
self.args['configuration'],
libfile),
os.path.join(libdir, libfile)),
dst=libfile)
for libfile in (
"libapr-1.0.dylib",
"libaprutil-1.0.dylib",
"libcollada14dom.dylib",
"libexpat.1.5.2.dylib",
"libexception_handler.dylib",
"libGLOD.dylib",
):
dylibs += path_optional(os.path.join(libdir, libfile), libfile)
if self.prefix(src=libdir, alt_build=alt_libdir, dst=""):
for libfile in (
"libapr-1.0.dylib",
"libaprutil-1.0.dylib",
"libcollada14dom.dylib",
"libexpat.1.5.2.dylib",
"libexception_handler.dylib",
"libGLOD.dylib",
"libhunspell-1.3.0.dylib",
"libndofdev.dylib",
):
dylibs += self.path_optional(libfile)
# SLVoice and vivox lols, no symlinks needed
for libfile in (
for libfile in (
'libortp.dylib',
'libsndfile.dylib',
'libvivoxoal.dylib',
'libvivoxsdk.dylib',
'libvivoxplatform.dylib',
'ca-bundle.crt',
'SLVoice',
'SLVoice'
):
self.path2basename(libdir, libfile)
self.path(libfile)
dylibs += self.add_extra_libraries()
# For using FMOD for sound...but, fmod is proprietary so some might not use it...
try:
self.path(self.args['configuration'] + "/libfmodwrapper.dylib", "libfmodwrapper.dylib")
pass
except:
print "Skipping libfmodwrapper.dylib - not found"
pass
# dylibs that vary based on configuration
if self.args['configuration'].lower() == 'debug':
for libfile in (
"libfmodexL.dylib",
):
dylibs += path_optional(os.path.join("../packages/lib/debug",
libfile), libfile)
else:
for libfile in (
"libfmodex.dylib",
):
dylibs += path_optional(os.path.join("../packages/lib/release",
libfile), libfile)
self.end_prefix()
# our apps
for app_bld_dir, app in (#("mac_crash_logger", "mac-crash-logger.app"),
@@ -634,8 +584,8 @@ class DarwinManifest(ViewerManifest):
# create a symlink to the real copy of the dylib.
resource_path = self.dst_path_of(os.path.join(app, "Contents", "Resources"))
for libfile in dylibs:
symlinkf(os.path.join(os.pardir, os.pardir, os.pardir, libfile),
os.path.join(resource_path, libfile))
symlinkf(os.path.join(os.pardir, os.pardir, os.pardir, os.path.basename(libfile)),
os.path.join(resource_path, os.path.basename(libfile)))
# plugins
if self.prefix(src="", dst="llplugin"):
@@ -675,37 +625,6 @@ class DarwinManifest(ViewerManifest):
if not self.default_channel_for_brand():
channel_standin = self.channel()
# Sign the app if we have a key.
try:
signing_password = os.environ['VIEWER_SIGNING_PASSWORD']
except KeyError:
print "Skipping code signing"
pass
else:
home_path = os.environ['HOME']
self.run_command('security unlock-keychain -p "%s" "%s/Library/Keychains/viewer.keychain"' % (signing_password, home_path))
signed=False
sign_attempts=3
sign_retry_wait=15
while (not signed) and (sign_attempts > 0):
try:
sign_attempts-=1;
self.run_command('codesign --verbose --force --timestamp --keychain "%(home_path)s/Library/Keychains/viewer.keychain" -s %(identity)r -f %(bundle)r' % {
'home_path' : home_path,
'identity': os.environ['VIEWER_SIGNING_KEY'],
'bundle': self.get_dst_prefix()
})
signed=True
except:
if sign_attempts:
print >> sys.stderr, "codesign failed, waiting %d seconds before retrying" % sign_retry_wait
time.sleep(sign_retry_wait)
sign_retry_wait*=2
else:
print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
raise
imagename=self.installer_prefix() + '_'.join(self.args['version'])
# See Ambroff's Hack comment further down if you want to create new bundles and dmg
@@ -729,88 +648,64 @@ class DarwinManifest(ViewerManifest):
'vol':volname})
# mount the image and get the name of the mount point and device node
hdi_output = self.run_command('hdiutil attach -private %r' % sparsename)
try:
devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
hdi_output = self.run_command('hdiutil attach -private "' + sparsename + '"')
devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
if devfile != '/dev/disk1':
# adding more debugging info based upon nat's hunches to the
# logs to help track down 'SetFile -a V' failures -brad
print "WARNING: 'SetFile -a V' command below is probably gonna fail"
# Copy everything in to the mounted .dmg
# Copy everything in to the mounted .dmg
if self.default_channel_for_brand() and not self.default_grid():
app_name = self.app_name() + " " + self.args['grid']
else:
app_name = channel_standin.strip()
if self.default_channel_for_brand() and not self.default_grid():
app_name = self.app_name() + " " + self.args['grid']
else:
app_name = channel_standin.strip()
# Hack:
# Because there is no easy way to coerce the Finder into positioning
# the app bundle in the same place with different app names, we are
# adding multiple .DS_Store files to svn. There is one for release,
# one for release candidate and one for first look. Any other channels
# will use the release .DS_Store, and will look broken.
# - Ambroff 2008-08-20
# Added a .DS_Store for snowglobe - Merov 2009-06-17
# Hack:
# Because there is no easy way to coerce the Finder into positioning
# the app bundle in the same place with different app names, we are
# adding multiple .DS_Store files to svn. There is one for release,
# one for release candidate and one for first look. Any other channels
# will use the release .DS_Store, and will look broken.
# - Ambroff 2008-08-20
# Added a .DS_Store for snowglobe - Merov 2009-06-17
# We have a single branded installer for all snowglobe channels so snowglobe logic is a bit different
if (self.app_name()=="Snowglobe"):
dmg_template = os.path.join ('installers', 'darwin', 'snowglobe-dmg')
else:
dmg_template = os.path.join(
'installers',
'darwin',
'%s-dmg' % "".join(self.channel_unique().split()).lower())
# We have a single branded installer for all snowglobe channels so snowglobe logic is a bit different
if (self.app_name()=="Snowglobe"):
dmg_template = os.path.join ('installers', 'darwin', 'snowglobe-dmg')
else:
dmg_template = os.path.join(
'installers',
'darwin',
'%s-dmg' % "".join(self.channel_unique().split()).lower())
if not os.path.exists (self.src_path_of(dmg_template)):
dmg_template = os.path.join ('installers', 'darwin', 'release-dmg')
if not os.path.exists (self.src_path_of(dmg_template)):
dmg_template = os.path.join ('installers', 'darwin', 'release-dmg')
for s,d in {self.get_dst_prefix():app_name + ".app",
os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns",
os.path.join(dmg_template, "background.jpg"): "background.jpg",
os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items():
print "Copying to dmg", s, d
self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
for s,d in {self.get_dst_prefix():app_name + ".app",
os.path.join(dmg_template, "_VolumeIcon.icns"): ".VolumeIcon.icns",
os.path.join(dmg_template, "background.jpg"): "background.jpg",
os.path.join(dmg_template, "_DS_Store"): ".DS_Store"}.items():
print "Copying to dmg", s, d
self.copy_action(self.src_path_of(s), os.path.join(volpath, d))
# Hide the background image, DS_Store file, and volume icon file (set their "visible" bit)
self.run_command('SetFile -a V "' + os.path.join(volpath, ".VolumeIcon.icns") + '"')
self.run_command('SetFile -a V "' + os.path.join(volpath, "background.jpg") + '"')
self.run_command('SetFile -a V "' + os.path.join(volpath, ".DS_Store") + '"')
# Hide the background image, DS_Store file, and volume icon file (set their "visible" bit)
for f in ".VolumeIcon.icns", "background.jpg", ".DS_Store":
pathname = os.path.join(volpath, f)
# We've observed mysterious "no such file" failures of the SetFile
# command, especially on the first file listed above -- yet
# subsequent inspection of the target directory confirms it's
# there. Timing problem with copy command? Try to handle.
for x in xrange(3):
if os.path.exists(pathname):
print "Confirmed existence: %r" % pathname
break
print "Waiting for %s copy command to complete (%s)..." % (f, x+1)
sys.stdout.flush()
time.sleep(1)
# If we fall out of the loop above without a successful break, oh
# well, possibly we've mistaken the nature of the problem. In any
# case, don't hang up the whole build looping indefinitely, let
# the original problem manifest by executing the desired command.
self.run_command('SetFile -a V %r' % pathname)
# Create the alias file (which is a resource file) from the .r
self.run_command('rez "' + self.src_path_of("installers/darwin/release-dmg/Applications-alias.r") + '" -o "' + os.path.join(volpath, "Applications") + '"')
# Create the alias file (which is a resource file) from the .r
self.run_command('Rez %r -o %r' %
(self.src_path_of("installers/darwin/release-dmg/Applications-alias.r"),
os.path.join(volpath, "Applications")))
# Set the alias file's alias and custom icon bits
self.run_command('SetFile -a AC "' + os.path.join(volpath, "Applications") + '"')
# Set the alias file's alias and custom icon bits
self.run_command('SetFile -a AC "' + os.path.join(volpath, "Applications") + '"')
# Set the disk image root's custom icon bit
self.run_command('SetFile -a C "' + volpath + '"')
# Set the disk image root's custom icon bit
self.run_command('SetFile -a C "' + volpath + '"')
finally:
# Unmount the image
self.run_command('hdiutil detach -force "' + devfile + '"')
# Unmount the image
self.run_command('hdiutil detach -force "' + devfile + '"')
print "Converting temp disk image to final disk image"
self.run_command('hdiutil convert "%(sparse)s" -format UDZO -imagekey zlib-level=9 -o "%(final)s"' % {'sparse':sparsename, 'final':finalname})
self.run_command('hdiutil internet-enable -yes "%(final)s"' % {'final':finalname})
# get rid of the temp file
self.package_file = finalname
self.remove(sparsename)
@@ -848,7 +743,6 @@ class LinuxManifest(ViewerManifest):
#else:
# self.path("secondlife-bin","bin/"+self.binary_name())
if self.prefix(src="", dst="bin"):
self.path("secondlife-bin",self.binary_name())
self.path2basename("../llplugin/slplugin", "SLPlugin")
self.end_prefix("bin")
@@ -864,6 +758,10 @@ class LinuxManifest(ViewerManifest):
self.path("../plugins/gstreamer010", "libmedia_plugin_gstreamer.so")
self.end_prefix("bin/llplugin")
# llcommon
if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
self.path("featuretable_linux.txt")
def wrapper_name(self):
@@ -930,14 +828,10 @@ class Linux_i686Manifest(LinuxManifest):
def construct(self):
super(Linux_i686Manifest, self).construct()
if not self.path("../llcommon/libllcommon.so", "lib/libllcommon.so"):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
if (not self.standalone()) and self.prefix("../packages/lib/release", dst="lib"):
self.prefix("../packages/libraries/i686-linux/lib/release", dst="lib")
if (not self.standalone()) and self.prefix(src="../packages/lib/release", alt_build="../packages/libraries/i686-linux/lib/release", dst="lib"):
self.path("libapr-1.so*")
self.path("libaprutil-1.so*")
self.path("libdb*.so")
self.path("libexpat.so*")
self.path("libglod.so")
@@ -946,20 +840,19 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libdirectfb-1.*.so*")
self.path("libfusion-1.*.so*")
self.path("libdirect-1.*.so*")
self.path("libhunspell-*.so.*")
self.path("libminizip.so.1.2.3", "libminizip.so");
self.path("libhunspell-*.so.*")
# OpenAL
self.path("libalut.so")
self.path("libopenal.so.1")
self.path("libtcmalloc_minimal.so.0") #formerly called google perf tools
self.path("libcollada14dom.so.2.2", "libcollada14dom.so")
self.path("libcrypto.so*")
self.path("libELFIO.so")
self.path("libssl.so*")
self.path("libtcmalloc_minimal.so.0")
self.path("libtcmalloc_minimal.so.0.2.2")
try:
self.path("libfmod-3.75.so")
pass
except:
print "Skipping libfmod-3.75.so - not found"
pass
# Boost
self.path("libboost_context-mt.so.*")
@@ -969,23 +862,11 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libboost_signals-mt.so.*")
self.path("libboost_system-mt.so.*")
self.path("libboost_thread-mt.so.*")
self.path("libcollada14dom.so.2.2", "libcollada14dom.so")
self.path("libcrypto.so*")
self.path("libELFIO.so")
self.path("libminizip.so.1.2.3", "libminizip.so");
self.path("libssl.so*")
if 'extra_libraries' in self.args:
path_list = self.args['extra_libraries'].split('|')
for path in path_list:
src_path = os.path.realpath(path)
dst_path = os.path.basename(path)
self.path(src_path, dst_path)
self.add_extra_libraries()
self.end_prefix("lib")
self.end_prefix("lib")
# Vivox runtimes
if self.prefix(src="../packages/lib/release", dst="bin"):
self.path("SLVoice")
@@ -995,28 +876,33 @@ class Linux_i686Manifest(LinuxManifest):
self.path("libvivoxsdk.so")
self.end_prefix("lib")
class Linux_x86_64Manifest(LinuxManifest):
def construct(self):
super(Linux_x86_64Manifest, self).construct()
if not self.path("../llcommon/libllcommon.so", "lib64/libllcommon.so"):
print "Skipping llcommon.so (assuming llcommon was linked statically)"
if (not self.standalone()) and self.prefix("../packages/lib/release", dst="lib64"):
self.prefix("../../libraries/x86_64-linux/lib/release", dst="lib64")
if (not self.standalone()) and self.prefix(src="../packages/lib/release", alt_build="../packages/libraries/x86_64-linux/lib/release", dst="lib"):
self.path("libapr-1.so*")
self.path("libaprutil-1.so*")
self.path("libdb-*.so*")
self.path("libexpat.so*")
self.path("libglod.so")
self.path("libssl.so*")
self.path("libuuid.so*")
self.path("libSDL-1.2.so*")
self.path("libjpeg.so*")
self.path("libminizip.so.1.2.3", "libminizip.so");
self.path("libhunspell-1.3.so*")
# OpenAL
self.path("libalut.so*")
self.path("libopenal.so*")
self.path("libcollada14dom.so.2.2", "libcollada14dom.so")
self.path("libcrypto.so.*")
self.path("libELFIO.so")
self.path("libjpeg.so*")
self.path("libpng*.so*")
self.path("libz.so*")
# Boost
self.path("libboost_context-mt.so.*")
@@ -1027,43 +913,30 @@ class Linux_x86_64Manifest(LinuxManifest):
self.path("libboost_system-mt.so.*")
self.path("libboost_thread-mt.so.*")
self.path("libcollada14dom.so.2.2", "libcollada14dom.so")
self.path("libcrypto.so.*")
self.path("libELFIO.so")
self.path("libminizip.so.1.2.3", "libminizip.so");
self.path("libpng*.so*")
self.path("libssl.so*")
self.path("libz.so*")
self.add_extra_libraries()
if 'extra_libraries' in self.args:
path_list = self.args['extra_libraries'].split('|')
for path in path_list:
src_path = os.path.realpath(path)
dst_path = os.path.basename(path)
self.path(src_path, dst_path)
self.end_prefix("lib")
self.end_prefix("lib64")
self.end_prefix("lib64")
# Vivox runtimes
if self.prefix(src="../packages/lib/release", dst="bin"):
self.path("SLVoice")
self.end_prefix("bin")
# Vivox runtimes and libs
if self.prefix(src="../packages/lib/release", dst="bin"):
self.path("SLVoice")
self.end_prefix("bin")
if self.prefix(src="../packages/lib/release", dst="lib32"):
#self.path("libalut.so")
self.path("libortp.so")
self.path("libvivoxsdk.so")
self.end_prefix("lib32")
if self.prefix(src="../packages/lib/release", dst="lib32"):
#self.path("libalut.so")
self.path("libortp.so")
self.path("libvivoxsdk.so")
self.end_prefix("lib32")
# 32bit libs needed for voice
if self.prefix("../packages/lib/32bit-compat", dst="lib32"):
self.path("libalut.so")
self.path("libidn.so.11")
self.path("libopenal.so.1")
# self.path("libortp.so")
self.path("libuuid.so.1")
self.end_prefix("lib32")
# 32bit libs needed for voice
if self.prefix(src="../packages/lib/release/32bit-compat", alt_build="../packages/libraries/x86_64-linux/lib/release/32bit-compat", dst="lib32"):
# Vivox libs
self.path("libalut.so")
self.path("libidn.so.11")
self.path("libopenal.so.1")
# self.path("libortp.so")
self.path("libuuid.so.1")
self.end_prefix("lib32")
################################################################

View File

@@ -1341,23 +1341,23 @@
<key>darwin</key>
<map>
<key>md5sum</key>
<string>917a60e1b18dd0f5e6afb555623339a4</string>
<string>8eb5462ea9d469bce4b0d22bd8f0c33b</string>
<key>url</key>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/slvoice-4.6.0009.20030-darwin-20140312.tar.bz2</uri>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/slvoice-4.6.0009.20030-darwin-20140312-rpk.tar.bz2</uri>
</map>
<key>linux</key>
<map>
<key>md5sum</key>
<string>01573510dce7f380f44e561ef2f3dd9f</string>
<string>1c8643e27023f1d9b1523ca5794b7475</string>
<key>url</key>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/vivox-2.1.3010.6270-linux-20090309.tar.bz2</uri>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/vivox-2.1.3010.6270-linux-20090309-rpk.tar.bz2</uri>
</map>
<key>linux64</key>
<map>
<key>md5sum</key>
<string>01573510dce7f380f44e561ef2f3dd9f</string>
<string>1c8643e27023f1d9b1523ca5794b7475</string>
<key>url</key>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/vivox-2.1.3010.6270-linux-20090309.tar.bz2</uri>
<uri>https://bitbucket.org/SingularityViewer/libraries/downloads/vivox-2.1.3010.6270-linux-20090309-rpk.tar.bz2</uri>
</map>
<key>windows</key>
<map>

View File

@@ -1,472 +0,0 @@
#!/bin/sh
# This is the build script used by Linden Lab's automated build system.
#
set -x
export INSTALL_USE_HTTP_FOR_SCP=true
export PATH=/bin:/usr/bin:$PATH
arch=`uname | cut -b-6`
here=`echo $0 | sed 's:[^/]*$:.:'`
# Hack : in the case of Snowglobe 1.x trunk and releases, we continue to use 2009 as the year so to separate them from Snowglobe 2.x trunk and releases
#year=`date +%Y`
year="2009"
branch=`svn info | grep '^URL:' | sed 's:.*/::'`
revision=`svn info | grep '^Revision:' | sed 's/.*: //'`
top=`cd "$here/../../.." && pwd`
[ x"$WGET_CACHE" = x ] && export WGET_CACHE=/var/tmp/parabuild/wget
[ x"$S3GET_URL" = x ] && export S3GET_URL=http://viewer-source-downloads.s3.amazonaws.com/$year
[ x"$S3PUT_URL" = x ] && export S3PUT_URL=https://s3.amazonaws.com/viewer-source-downloads/$year
[ x"$S3SYMBOL_URL" = x ] && export S3SYMBOL_URL=https://s3.amazonaws.com/automated-builds-secondlife-com/binaries
[ x"$PUBLIC_URL" = x ] && export PUBLIC_URL=http://secondlife.com/developers/opensource/downloads/$year
[ x"$PUBLIC_EMAIL" = x ] && export PUBLIC_EMAIL=sldev-commits@lists.secondlife.com
# Make sure command worked and bail out if not, reporting failure to parabuild
fail()
{
echo "BUILD FAILED" $@
exit 1
}
pass()
{
echo "BUILD SUCCESSFUL"
exit 0
}
# Locking to avoid contention with u-s-c
LOCK_PROCESS=
locking_available()
{
test -n "$LOCK_CREATE" -a -x "$LOCK_CREATE"\
-a -n "$LOCK_TOUCH" -a -x "$LOCK_TOUCH"\
-a -n "$LOCK_REMOVE" -a -x "$LOCK_REMOVE"
}
acquire_lock()
{
if locking_available
then
if "$LOCK_CREATE" /var/lock/update-system-config --retry 99
then
"$LOCK_TOUCH" /var/lock/update-system-config &
LOCK_PROCESS="$!"
else
fail acquire lock
fi
else
true
fi
}
release_lock()
{
if locking_available
then
if test x"$LOCK_PROCESS" != x
then
kill "$LOCK_PROCESS"
"$LOCK_REMOVE" /var/lock/update-system-config
else
echo No Lock Acquired >&2
fi
else
true
fi
}
get_asset()
{
mkdir -p "$WGET_CACHE" || fail creating WGET_CACHE
local tarball=`basename "$1"`
test -r "$WGET_CACHE/$tarball" || ( cd "$WGET_CACHE" && curl --location --remote-name "$1" || fail getting $1 )
case "$tarball" in
*.zip) unzip -qq -d "$top" -o "$WGET_CACHE/$tarball" || fail unzip $tarball ;;
*.tar.gz|*.tgz) tar -C "$top" -xzf "$WGET_CACHE/$tarball" || fail untar $tarball ;;
*) fail unrecognized filetype: $tarball ;;
esac
}
s3_available()
{
test -x "$helpers/hg/bin/s3get.sh" -a -x "$helpers/hg/bin/s3put.sh" -a -r "$helpers/hg/bin/s3curl.py"
}
build_dir_Darwin()
{
echo build-darwin-i386
}
build_dir_Linux()
{
echo viewer-linux-i686-`echo $1 | tr A-Z a-z`
}
build_dir_CYGWIN()
{
echo build-vc80
}
installer_Darwin()
{
ls -1td "$(build_dir_Darwin Release)/newview/"*.dmg 2>/dev/null | sed 1q
}
installer_Linux()
{
ls -1td "$(build_dir_Linux Release)/newview/"*.tar.bz2 2>/dev/null | sed 1q
}
installer_CYGWIN()
{
d=$(build_dir_CYGWIN Release)
p=$(sed 's:.*=::' "$d/newview/Release/touched.bat")
echo "$d/newview/Release/$p"
}
# deal with aborts etc..
trap fail 1 2 3 14 15
# Check location
cd "$here/../.."
test -x ../linden/scripts/automated_build_scripts/opensrc-build.sh\
|| fail 'The parent dir of your checkout needs to be named "linden"'
. doc/asset_urls.txt
get_asset "$SLASSET_ART"
update_version_files=
# Set up platform specific stuff
case "$arch" in
# Note that we can only build the "Release" variant for Darwin, because of a compiler bug:
# ld: bl out of range (-16777272 max is +/-16M)
# from __static_initialization_and_destruction_0(int, int)at 0x033D319C
# in __StaticInit of
# indra/build-darwin-universal/newview/SecondLife.build/Debug/Second Life.build/Objects-normal/ppc/llvoicevisualizer.o
# to ___cxa_atexit$island_2 at 0x023D50F8
# in __text of
# indra/build-darwin-universal/newview/SecondLife.build/Debug/Second Life.build/Objects-normal/ppc/Second Life
# in __static_initialization_and_destruction_0(int, int)
# from indra/build-darwin-universal/newview/SecondLife.build/Debug/Second Life.build/Objects-normal/ppc/llvoicevisualizer.o
Darwin)
helpers=/usr/local/buildscripts/shared/latest
variants="Release"
cmake_generator="Xcode"
fmod=fmodapi375mac
fmod_tar="$fmod.zip"
fmod_so=libfmod.a
fmod_lib=lib
target_dirs="libraries/universal-darwin/lib_debug
libraries/universal-darwin/lib_release
libraries/universal-darwin/lib_release_client"
other_archs="$S3GET_URL/$branch/$revision/CYGWIN $S3GET_URL/$branch/$revision/Linux"
symbolfiles=
mail="$helpers"/mail.py
all_done="$helpers"/all_done.py
test -r "$helpers/update_version_files.py" && update_version_files="$helpers/update_version_files.py"
libs_asset="$SLASSET_LIBS_DARWIN"
s3put="$helpers"/hg/bin/s3put.sh
;;
CYGWIN)
helpers=/cygdrive/c/buildscripts/shared/latest
variants="Debug RelWithDebInfo Release ReleaseSSE2"
#variants="Release"
cmake_generator="vc80"
fmod=fmodapi375win
fmod_tar=fmodapi375win.zip
fmod_so=fmodvc.lib
fmod_lib=lib
target_dirs="libraries/i686-win32/lib/debug
libraries/i686-win32/lib/release"
other_archs="$S3GET_URL/$branch/$revision/Darwin $S3GET_URL/$branch/$revision/Linux"
symbolfiles="newview/Release/secondlife-bin.pdb newview/Release/secondlife-bin.map newview/Release/secondlife-bin.exe"
export PATH="/cygdrive/c/Python25:/cygdrive/c/Program Files/Cmake 2.6/bin":$PATH
export PERL="/cygdrive/c/Perl/bin/perl.exe"
export S3CURL="C:\\buildscripts\\shared\\latest\\hg\\bin\\s3curl.py"
export SIGN_PY="C:\\buildscripts\\shared\\latest\\code-signing\\sign.py"
export CURL="C:\\cygwin\\bin\\curl.exe"
mail="C:\\buildscripts\\shared\\latest\\mail.py"
all_done="C:\\buildscripts\\shared\\latest\\all_done.py"
test -r "$helpers/update_version_files.py" && update_version_files="C:\\buildscripts\\shared\\latest\\update_version_files.py"
libs_asset="$SLASSET_LIBS_WIN32"
s3put="$helpers"/hg/bin/s3put.sh
;;
Linux)
helpers=/var/opt/parabuild/buildscripts/shared/latest
if [ x"$CXX" = x ]
then
if test -x /usr/bin/g++-4.1
then
if test -x /usr/bin/distcc
then
export CXX="/usr/bin/distcc /usr/bin/g++-4.1"
else
export CXX=/usr/bin/g++-4.1
fi
fi
fi
variants="Debug RelWithDebInfo Release ReleaseSSE2"
#variants="Release"
cmake_generator="Unix Makefiles"
fmod=fmodapi375linux
fmod_tar="$fmod".tar.gz
fmod_so=libfmod-3.75.so
fmod_lib=.
target_dirs="libraries/i686-linux/lib_debug
libraries/i686-linux/lib_release
libraries/i686-linux/lib_release_client"
other_archs="$S3GET_URL/$branch/$revision/Darwin $S3GET_URL/$branch/$revision/CYGWIN"
symbolfiles=
mail="$helpers"/mail.py
all_done="$helpers"/all_done.py
test -r "$helpers/update_version_files.py" && update_version_files="$helpers/update_version_files.py"
# Change the DISTCC_DIR to be somewhere that the parabuild process can write to
if test -r /etc/debian_version
then
[ x"$DISTCC_DIR" = x ] && export DISTCC_DIR=/var/tmp/parabuild
#case `cat /etc/debian_version` in
#3.*) [ x"$DISTCC_HOSTS" = x ]\
# && export DISTCC_HOSTS="build-linux-1/3
# station30/2,lzo" ;;
#4.*) [ x"$DISTCC_HOSTS" = x ]\
# && export DISTCC_HOSTS="build-linux-6/2,lzo
# build-linux-2/2,lzo
# build-linux-3/2,lzo
# build-linux-4/2,lzo
# build-linux-5/2,lzo
# build-linux-7/2,lzo
# build-linux-8/2,lzo
# build-linux-9/2,lzo" ;;
#esac
# Temp fix for Linux so that parabuild passes: use the new Linux build farm
export hostname=`hostname -f`
export phx_DISTCC_HOSTS="build-linux0.phx.lindenlab.com/2 build-linux1.phx.lindenlab.com/2 build-linux2.phx.lindenlab.com/2 build-linux3.phx.lindenlab.com/2 build-linux5.phx.lindenlab.com/2 build-linux5.phx.lindenlab.com/2 build-linux6.phx.lindenlab.com/2 "
export dfw_DISTCC_HOSTS="build-linux7.dfw.lindenlab.com/2 build-linux8.dfw.lindenlab.com/2 build-linux9.dfw.lindenlab.com/2 build-linux10.dfw.lindenlab.com/2 build-linux11.dfw.lindenlab.com/2 build-linux12.dfw.lindenlab.com/2 build-linux13.dfw.lindenlab.com/2 build-linux14.dfw.lindenlab.com/2 build-linux15.dfw.lindenlab.com/2"
case "$hostname" in
*.dfw.*) export DISTCC_HOSTS="$dfw_DISTCC_HOSTS" ;;
*.phx.*) export DISTCC_HOSTS="$phx_DISTCC_HOSTS" ;;
esac
fi
libs_asset="$SLASSET_LIBS_LINUXI386"
s3put="$helpers"/hg/bin/s3put.sh
;;
*) fail undefined $arch ;;
esac
acquire_lock
trap release_lock EXIT
get_asset "http://www.fmod.org/files/fmod3/$fmod_tar"
case "$arch" in
Darwin)
# Create fat binary on Mac...
if lipo -create -output "../$fmod"/api/$fmod_lib/libfmod-universal.a\
"../$fmod"/api/$fmod_lib/libfmod.a\
"../$fmod"/api/$fmod_lib/libfmodx86.a
then
mv "../$fmod"/api/$fmod_lib/libfmod.a "../$fmod"/api/$fmod_lib/libfmodppc.a
mv "../$fmod"/api/$fmod_lib/libfmod-universal.a "../$fmod"/api/$fmod_lib/libfmod.a
echo Created fat binary
else
fail running lipo
fi
;;
CYGWIN)
# install Quicktime. This will fail outside of Linden's network
scripts/install.py quicktime
;;
esac
# Only run this if the script exists
if test x"$update_version_files" = x
then
echo "Private Build..." > indra/build.log
[ x"$VIEWER_CHANNEL" = x ] && export VIEWER_CHANNEL="CommunityDeveloper"
else
# By right, this should be in the branched source tree, but for now it will be a helper
python "$update_version_files" --verbose --src-root=. --viewer > indra/build.log
[ x"$VIEWER_CHANNEL" = x ] && export VIEWER_CHANNEL="Snowglobe Test Build"
fi
# First, go into the directory where the code was checked out by Parabuild
cd indra
# This is the way it works now, but it will soon work on a variant dependent way
for target_dir in $target_dirs
do
mkdir -p "../$target_dir"
cp -f "../../$fmod/api/$fmod_lib/$fmod_so" "../$target_dir"
done
mkdir -p "../libraries/include"
cp -f "../../$fmod/api/inc/"* "../libraries/include"
# Special Windows case
test -r "../../$fmod/api/fmod.dll" && cp -f "../../$fmod/api/fmod.dll" newview
# Now run the build command over all variants
succeeded=true
### TEST CODE - remove when done
### variants=
### echo "Artificial build failure to test notifications" > build.log
### succeeded=false
### END TEST CODE
for variant in $variants
do
build_dir=`build_dir_$arch $variant`
rm -rf "$build_dir"
get_asset "$libs_asset" # This plunks stuff into the build dir, so have to restore it now.
# SNOW-713 : hack around a Darwin lib 1.23.4.0 tarball issue introduced by the move from universal to i386
# Should be removed when libs are rebuilt cleanly
if test -r build-darwin-universal-Release
then
mv build-darwin-universal-Release/ "$build_dir/"
fi
# End SNOW-713 hack
# This is the way it will work in future
#for target_dir in $target_dirs
#do
# mkdir -p "$build_dir/$target_dir"
# cp "../../$fmod/api/$fmod_lib/$fmod_so" "$build_dir/$target_dir"
#done
#mkdir -p "$build_dir/libraries/include"
#cp "../../$fmod/api/inc/"* "$build_dir/libraries/include"
echo "==== $variant ====" >> build.log
if ./develop.py \
--unattended \
--incredibuild \
-t $variant \
-G "$cmake_generator" \
configure \
-DVIEWER_CHANNEL:STRING="$VIEWER_CHANNEL"\
-DVIEWER_LOGIN_CHANNEL:STRING="$VIEWER_CHANNEL"\
-DPACKAGE:BOOL=ON >>build.log 2>&1
then
if ./develop.py\
--unattended\
--incredibuild \
-t $variant\
-G "$cmake_generator" \
build prepare >>build.log 2>&1
then
if ./develop.py\
--unattended\
--incredibuild \
-t $variant\
-G "$cmake_generator" \
build package >>build.log 2>&1
then
# run tests if needed
true
else
succeeded=false
fi
else
succeeded=false
fi
else
succeeded=false
fi
done
# Check status and upload results to S3
subject=
if $succeeded
then
package=`installer_$arch`
test -r "$package" || fail not found: $package
package_file=`echo $package | sed 's:.*/::'`
if s3_available
then
# Create an empty token file and populate it with the usable URLs: this will be emailed when all_done...
cp /dev/null "$arch"
echo "$PUBLIC_URL/$branch/$revision/$package_file" >> "$arch"
echo "$PUBLIC_URL/$branch/$revision/good-build.$arch" >> "$arch"
"$s3put" "$package" "$S3PUT_URL/$branch/$revision/$package_file" binary/octet-stream public-read\
|| fail Uploading "$package"
"$s3put" build.log "$S3PUT_URL/$branch/$revision/good-build.$arch" text/plain public-read\
|| fail Uploading build.log
"$s3put" "$arch" "$S3PUT_URL/$branch/$revision/$arch" text/plain public-read\
|| fail Uploading token file
for symbolfile in $symbolfiles
do
targetfile="`echo $symbolfile | sed 's:.*/::'`"
"$s3put" "$build_dir/$symbolfile" "$S3SYMBOL_URL/$revision/$targetfile" binary/octet-stream public-read\
|| fail Uploading "$symbolfile"
done
if python "$all_done"\
curl\
"$S3GET_URL/$branch/$revision/$arch"\
$other_archs > message
then
subject="Successful Build for $year/$branch ($revision)"
fi
else
true s3 is not available
fi
else
if s3_available
then
"$s3put" build.log "$S3PUT_URL/$branch/$revision/failed-build.$arch" text/plain public-read\
|| fail Uploading build.log
subject="Failed Build for $year/$branch ($revision) on $arch"
cat >message <<EOF
Build for $branch ($revision) failed for $arch.
Please see the build log for details:
$PUBLIC_URL/$branch/$revision/failed-build.$arch
EOF
else
true s3 is not available
fi
fi
# We have something to say...
if [ x"$subject" != x ]
then
# Extract change list since last build
if [ x"$PARABUILD_CHANGE_LIST_NUMBER" = x ]
then
echo "No change information available" >> message
elif [ x"$PARABUILD_PREVIOUS_CHANGE_LIST_NUMBER" = x ]
then
( cd .. && svn log --verbose --stop-on-copy --limit 50 ) >> message
else
if [ "$PARABUILD_PREVIOUS_CHANGE_LIST_NUMBER" -lt "$PARABUILD_CHANGE_LIST_NUMBER" ]
then
range=`expr 1 + "$PARABUILD_PREVIOUS_CHANGE_LIST_NUMBER"`:"$PARABUILD_CHANGE_LIST_NUMBER"
else
range="$PARABUILD_CHANGE_LIST_NUMBER"
fi
( cd .. && svn log --verbose -r"$range" ) >> message
fi
# $PUBLIC_EMAIL can be a list, so no quotes
python "$mail" "$subject" $PUBLIC_EMAIL < message
fi
if $succeeded
then
pass
else
fail
fi

View File

@@ -1,280 +0,0 @@
#!/usr/bin/python
"""\
@file public_fetch_tarballs.py
@author Rob Lanphier
@date 2009-05-30
@brief Fetch + extract tarballs and zipfiles listed in doc/asset_urls.txt
$LicenseInfo:firstyear=2009&license=viewergpl$
Copyright (c) 2009, Linden Research, Inc.
Second Life Viewer Source Code
The source code in this file ("Source Code") is provided by Linden Lab
to you under the terms of the GNU General Public License, version 2.0
("GPL"), unless you have obtained a separate licensing agreement
("Other License"), formally executed by you and Linden Lab. Terms of
the GPL can be found in doc/GPL-license.txt in this distribution, or
online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
There are special exceptions to the terms and conditions of the GPL as
it is applied to this Source Code. View the full text of the exception
in the file doc/FLOSS-exception.txt in this software distribution, or
online at
http://secondlifegrid.net/programs/open_source/licensing/flossexception
By copying, modifying or distributing this software, you acknowledge
that you have read and understood your obligations described above,
and agree to abide by those obligations.
ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
COMPLETENESS OR PERFORMANCE.
$/LicenseInfo$
"""
import sys
import os.path
# Look for indra/lib/python in all possible parent directories ...
# This is an improvement over the setup-path.py method used previously:
# * the script may blocated anywhere inside the source tree
# * it doesn't depend on the current directory
# * it doesn't depend on another file being present.
def add_indra_lib_path():
root = os.path.realpath(__file__)
# always insert the directory of the script in the search path
dir = os.path.dirname(root)
if dir not in sys.path:
sys.path.insert(0, dir)
# Now go look for indra/lib/python in the parent dies
while root != os.path.sep:
root = os.path.dirname(root)
dir = os.path.join(root, 'indra', 'lib', 'python')
if os.path.isdir(dir):
if dir not in sys.path:
sys.path.insert(0, dir)
return root
else:
print >>sys.stderr, "This script is not inside a valid installation."
sys.exit(1)
base_dir = add_indra_lib_path()
print base_dir
import os
import sys
import re
import urllib
import zipfile
import tarfile
import optparse
import tempfile
import indra.util.helpformatter
# load + parse doc/asset_urls.txt
def get_asset_urls():
asset_urls={}
f = open(os.path.join(base_dir,"doc", "asset_urls.txt"))
for line in f:
line=line.strip()
(name, value)=re.split("=", line, 1)
asset_urls[name]=value
return asset_urls
# Filename from a URL
def get_asset_filename_from_url(asseturl, targetdir):
i = asseturl.rfind('/')
filename = os.path.join(targetdir, asseturl[i+1:])
return filename
# Extract .zip file to targetdir. Called by extract_archive_sans_linden.
def extract_zipfile_sans_linden(filename, targetdir):
archive = zipfile.ZipFile(filename, 'r')
names = archive.namelist()
for path in names:
if(path=="linden/"):
pass
target = os.path.join(targetdir, re.sub("linden/", "", path))
subdir = os.path.dirname(target)
if not os.path.exists(subdir):
os.makedirs(subdir)
if not os.path.exists(target):
fp = open(target, 'wb')
fp.write(archive.read(path))
fp.close()
archive.close()
# Extract .tar.gz file to targetdir. Called by extract_archive_sans_linden.
def extract_tarball_sans_linden(filename, targetdir):
archive = tarfile.TarFile.open(filename, 'r')
# get a series of TarInfo objects
tarentries=archive.getmembers()
for tarentry in tarentries:
target = re.sub(r'^(\./)?(linden/?)?', "", tarentry.name)
if(target==""):
continue
fulltarget=os.path.join(targetdir, target)
subdir = os.path.dirname(fulltarget)
if not os.path.exists(subdir):
os.makedirs(subdir)
if not os.path.exists(fulltarget):
# Reset the name property on the TarInfo object, so it writes the
# file exactly where we want it. It's hard telling for sure if this
# property is intended to be written to, but it works for now.
tarentry.name=fulltarget
# Calling TarFile.extract with the "path" parameter doesn't work as
# we might hope, because the path components in the tarball get
# appended to the "path" parameter. Hence the reason for passing in
# the TarInfo object with the munged name property
archive.extract(tarentry)
archive.close()
# Extract either .tar.gz file or .zip file to targetdir, stripping off the
# leading "linden" directory, but leaving the directory structure otherwise
# intact.
def extract_archive_sans_linden(filename, targetdir):
if(filename.endswith('.tar.gz')):
extract_tarball_sans_linden(filename, targetdir)
elif(filename.endswith('.zip')):
extract_zipfile_sans_linden(filename, targetdir)
else:
raise Exception, "Unhandled archive type"
def get_assetnames_by_platform(platform):
assetnames=['SLASSET_ART']
if(platform=='linux' or platform=='all'):
assetnames.append('SLASSET_LIBS_LINUXI386')
if(platform=='darwin' or platform=='all'):
assetnames.append('SLASSET_LIBS_DARWIN')
if(platform=='windows' or platform=='all'):
assetnames.append('SLASSET_LIBS_WIN32')
return assetnames
# adapted from install.py
def _get_platform():
"Return appropriate platform packages for the environment."
platform_map = {
'darwin': 'darwin',
'linux2': 'linux',
'win32' : 'windows',
'cygwin' : 'windows',
'solaris' : 'solaris'
}
this_platform = platform_map[sys.platform]
return this_platform
# copied from install.py
def _default_installable_cache():
"""In general, the installable files do not change much, so find a
host/user specific location to cache files."""
user = _getuser()
cache_dir = "/var/tmp/%s/sg.install.cache" % user
if _get_platform() == 'windows':
cache_dir = os.path.join(tempfile.gettempdir(), \
'sg.install.cache.%s' % user)
return cache_dir
# For status messages (e.g. "Loading..."). May come in handy if
# we implement a "quiet" mode.
def _report(string):
print string
# copied from install.py
def _getuser():
"Get the user"
try:
# Unix-only.
import getpass
return getpass.getuser()
except ImportError:
import win32api
return win32api.GetUserName()
# adapted from install.py
def _parse_args():
parser = optparse.OptionParser(
usage="usage: %prog [options]",
formatter = indra.util.helpformatter.Formatter(),
description="""This script fetches and installs tarballs and \
zipfiles ("asset bundles") listed in doc/asset_urls.txt
If no asset bundles are specified on the command line, then the default \
behavior is to install all known asset bundles appropriate for the platform \
specified. You can specify more than one asset bundle on the command line.
Example:
%prog SLASSET_ART
This looks for the "SLASSET_ART" entry in doc/asset_urls.txt, and extracts
the corresponding asset bundle into your source tree.
""")
parser.add_option(
'-p', '--platform',
type='choice',
default=_get_platform(),
dest='platform',
choices=['windows', 'darwin', 'linux', 'solaris', 'all'],
help="""Override the automatically determined platform. \
You can specify 'all' to get assets for all platforms. Choices: windows, \
darwin, linux, solaris, or all. Default: autodetected (%s)""" % \
_get_platform())
parser.add_option(
'--cache-dir',
type='string',
default=_default_installable_cache(),
dest='cache_dir',
help='Where to download files. Default: %s'% \
(_default_installable_cache()))
parser.add_option(
'--install-dir',
type='string',
default=base_dir,
dest='install_dir',
help='Where to unpack the installed files. Default: %s' % base_dir)
return parser.parse_args()
def main(argv):
options, args = _parse_args()
# 1. prepare cache dir
if not os.path.exists(options.cache_dir):
os.makedirs(options.cache_dir)
# 2. read doc/asset_urls.txt
asseturls=get_asset_urls()
# 3. figure out which asset bundles we'll be downloading
if len(args)>0:
assetnames=args
else:
assetnames=get_assetnames_by_platform(options.platform)
# 4. download and extract each asset bundle
for asset in assetnames:
# 4a. get the URL for the asset bundle
try:
asseturl=asseturls[asset]
except:
print "No asset in doc/asset_urls.txt named %s" % asset
sys.exit(2)
# 4b. figure out where to put the downloaded asset bundle
filename=get_asset_filename_from_url(asseturl, options.cache_dir)
# 4c. see if we have it, and if not, get it
if os.path.exists(filename):
_report("Using already downloaded "+filename+" ...")
else:
_report("Downloading "+filename+" ...")
urllib.urlretrieve(asseturl, filename)
# 4d. extract it into the tree
extract_archive_sans_linden(filename, options.install_dir)
# execute main() only if invoked directly:
if __name__ == "__main__":
sys.exit(main(sys.argv))