Merge Firestorm LGPL
commit
3a1fcb9521
|
|
@ -24,9 +24,9 @@ build-linux-*
|
|||
build-darwin-*
|
||||
build-vc80/
|
||||
build-vc100/
|
||||
build-vc100_x64/
|
||||
build-vc120/
|
||||
build-vc120_x64/
|
||||
build-vc120-32/
|
||||
build-vc120-64/
|
||||
indra/build-vc[0-9]*
|
||||
indra/CMakeFiles
|
||||
indra/lib/mono/1.0/*.dll
|
||||
|
|
|
|||
1
.hgtags
1
.hgtags
|
|
@ -568,3 +568,4 @@ b4d76b5590fdf8bab72c64442353753a527cbc44 5.0.5-release
|
|||
abcab37e1b29414ab8c03af9ca2ab489d809788a 5.0.7-release
|
||||
505a492f30bd925bb48e2e093ae77c3c2b4c740f 5.0.8-release
|
||||
40ca7118765be85a043b31b011e4ee6bd9e33c95 5.0.9-release
|
||||
ad0e15543836d64d6399d28b32852510435e344a 5.1.0-release
|
||||
|
|
|
|||
28
BuildParams
28
BuildParams
|
|
@ -3,36 +3,18 @@
|
|||
# Please refer to:
|
||||
# https://wiki.secondlife.com/wiki/Automated_Build_System
|
||||
|
||||
|
||||
# Global setting for now....
|
||||
Darwin.symbolfiles = "newview/Release/secondlife-symbols-darwin.tar.bz2"
|
||||
CYGWIN.symbolfiles = "newview/Release/secondlife-symbols-windows.tar.bz2"
|
||||
Linux.symbolfiles = "newview/secondlife-symbols-linux.tar.bz2"
|
||||
# Variants (NOTE: 'Release' must be last for uploads to work correctly)
|
||||
variants = "RelWithDebInfo Release"
|
||||
|
||||
# Use Public Upload Locations
|
||||
public_build = true
|
||||
build_docs = true
|
||||
|
||||
# disable all Debug builds (RelWithDebInfo is sufficient)
|
||||
build_CYGWIN_Debug = false
|
||||
build_Linux_Debug = false
|
||||
build_Darwin_Debug = false
|
||||
build_Debug = false
|
||||
|
||||
# enable Doxygen building on Linux for TeamCity (it can be done manually on any platform)
|
||||
build_Linux_Doxygen = true
|
||||
|
||||
# Update Public Inworld Build Status Indicators (setting should mirror "public_build")
|
||||
email_status_this_is_os = true
|
||||
|
||||
# Limit extent of codeticket updates to revisions after...
|
||||
codeticket_since = 3.3.0-release
|
||||
|
||||
# Override build system default toolchain
|
||||
# Note that this will only affect automated builds.
|
||||
Linux.distcc_version =
|
||||
Linux.gcc_version = /usr/bin/gcc-4.6
|
||||
Linux.cxx_version = /usr/bin/g++-4.6
|
||||
# Need viewer-build-variables as well as other shared repositories
|
||||
buildscripts_shared_more_NAMEs="build_secrets build_variables"
|
||||
|
||||
################################################################
|
||||
#### Examples of how to set the viewer_channel ####
|
||||
|
|
@ -83,5 +65,5 @@ EDU_viewer_channel_suffix = "edu"
|
|||
# Notifications - to configure email notices use the TeamCity parameter
|
||||
# setting screen for your project or build configuration to set the
|
||||
# environment variable 'email' to a space-separated list of email addresses
|
||||
|
||||
email=""
|
||||
|
||||
|
|
|
|||
2435
autobuild.xml
2435
autobuild.xml
File diff suppressed because it is too large
Load Diff
229
build.sh
229
build.sh
|
|
@ -1,4 +1,4 @@
|
|||
#!/bin/sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This is the custom build script for the viewer
|
||||
#
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
build_dir_Darwin()
|
||||
{
|
||||
echo build-darwin-i386
|
||||
echo build-darwin-x86_64
|
||||
}
|
||||
|
||||
build_dir_Linux()
|
||||
|
|
@ -28,7 +28,7 @@ build_dir_Linux()
|
|||
|
||||
build_dir_CYGWIN()
|
||||
{
|
||||
echo build-vc120
|
||||
echo build-vc120-${AUTOBUILD_ADDRSIZE}
|
||||
}
|
||||
|
||||
viewer_channel_suffix()
|
||||
|
|
@ -47,8 +47,8 @@ viewer_channel_suffix()
|
|||
installer_Darwin()
|
||||
{
|
||||
local package_name="$1"
|
||||
local package_dir="$(build_dir_Darwin ${last_built_variant:-Release})/newview/"
|
||||
local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_i386\\.dmg\$"
|
||||
local package_dir="$(build_dir_Darwin)/newview/"
|
||||
local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_x86_64\\.dmg\$"
|
||||
# since the additional packages are built after the base package,
|
||||
# sorting oldest first ensures that the unqualified package is returned
|
||||
# even if someone makes a qualified name that duplicates the last word of the base name
|
||||
|
|
@ -59,7 +59,7 @@ installer_Darwin()
|
|||
installer_Linux()
|
||||
{
|
||||
local package_name="$1"
|
||||
local package_dir="$(build_dir_Linux ${last_built_variant:-Release})/newview/"
|
||||
local package_dir="$(build_dir_Linux)/newview/"
|
||||
local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_i686\\.tar\\.bz2\$"
|
||||
# since the additional packages are built after the base package,
|
||||
# sorting oldest first ensures that the unqualified package is returned
|
||||
|
|
@ -95,14 +95,28 @@ pre_build()
|
|||
&& [ -r "$master_message_template_checkout/message_template.msg" ] \
|
||||
&& template_verifier_master_url="-DTEMPLATE_VERIFIER_MASTER_URL=file://$master_message_template_checkout/message_template.msg"
|
||||
|
||||
"$autobuild" configure "${autobuild_configure_verbosity:---quiet}" -c $variant -- \
|
||||
# nat 2016-12-20: disable HAVOK on Mac until we get a 64-bit Mac build.
|
||||
RELEASE_CRASH_REPORTING=ON
|
||||
HAVOK=ON
|
||||
SIGNING=()
|
||||
if [ "$arch" == "Darwin" ]
|
||||
then
|
||||
if [ "$variant" == "Release" ]
|
||||
then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
|
||||
"-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
|
||||
fi
|
||||
fi
|
||||
|
||||
"$autobuild" configure --quiet -c $variant -- \
|
||||
-DPACKAGE:BOOL=ON \
|
||||
-DUNATTENDED:BOOL=ON \
|
||||
-DRELEASE_CRASH_REPORTING:BOOL=ON \
|
||||
-DVIEWER_CHANNEL:STRING="\"$viewer_channel\"" \
|
||||
-DHAVOK:BOOL="$HAVOK" \
|
||||
-DRELEASE_CRASH_REPORTING:BOOL="$RELEASE_CRASH_REPORTING" \
|
||||
-DVIEWER_CHANNEL:STRING="${viewer_channel}" \
|
||||
-DGRID:STRING="\"$viewer_grid\"" \
|
||||
-DLL_TESTS:BOOL="$run_tests" \
|
||||
-DTEMPLATE_VERIFIER_OPTIONS:STRING="$template_verifier_options" $template_verifier_master_url \
|
||||
"${SIGNING[@]}" \
|
||||
|| fatal "$variant configuration failed"
|
||||
|
||||
end_section "Configure $variant"
|
||||
|
|
@ -112,21 +126,21 @@ package_llphysicsextensions_tpv()
|
|||
{
|
||||
begin_section "PhysicsExtensions_TPV"
|
||||
tpv_status=0
|
||||
if [ "$variant" = "Release" ]
|
||||
# nat 2016-12-21: without HAVOK, can't build PhysicsExtensions_TPV.
|
||||
if [ "$variant" = "Release" -a "${HAVOK:-}" != "OFF" ]
|
||||
then
|
||||
llpetpvcfg=$build_dir/packages/llphysicsextensions/autobuild-tpv.xml
|
||||
"$autobuild" build "${autobuild_build_verbosity:---quiet}" --config-file $llpetpvcfg -c Tpv
|
||||
test -r "$build_dir/packages/llphysicsextensions/autobuild-tpv.xml" || fatal "No llphysicsextensions_tpv autobuild configuration found"
|
||||
tpvconfig=$(native_path "$build_dir/packages/llphysicsextensions/autobuild-tpv.xml")
|
||||
"$autobuild" build --quiet --config-file "$tpvconfig" -c Tpv || fatal "failed to build llphysicsextensions_tpv"
|
||||
|
||||
# capture the package file name for use in upload later...
|
||||
PKGTMP=`mktemp -t pgktpv.XXXXXX`
|
||||
trap "rm $PKGTMP* 2>/dev/null" 0
|
||||
"$autobuild" package --quiet --config-file $llpetpvcfg --results-file "$(native_path $PKGTMP)"
|
||||
"$autobuild" package --quiet --config-file "$tpvconfig" --results-file "$(native_path $PKGTMP)" || fatal "failed to package llphysicsextensions_tpv"
|
||||
tpv_status=$?
|
||||
if [ -r "${PKGTMP}" ]
|
||||
then
|
||||
cat "${PKGTMP}" >> "$build_log"
|
||||
eval $(cat "${PKGTMP}") # sets autobuild_package_{name,filename,md5}
|
||||
autobuild_package_filename="$(shell_path "${autobuild_package_filename}")"
|
||||
. "${PKGTMP}" # sets autobuild_package_{name,filename,md5}
|
||||
echo "${autobuild_package_filename}" > $build_dir/llphysicsextensions_package
|
||||
fi
|
||||
else
|
||||
|
|
@ -142,10 +156,14 @@ build()
|
|||
local variant="$1"
|
||||
if $build_viewer
|
||||
then
|
||||
begin_section "autobuild $variant"
|
||||
"$autobuild" build --no-configure -c $variant || fatal "failed building $variant"
|
||||
echo true >"$build_dir"/build_ok
|
||||
end_section "autobuild $variant"
|
||||
|
||||
begin_section "extensions $variant"
|
||||
# Run build extensions
|
||||
if [ $build_ok -eq 0 -a -d ${build_dir}/packages/build-extensions ]
|
||||
if [ -d ${build_dir}/packages/build-extensions ]
|
||||
then
|
||||
for extension in ${build_dir}/packages/build-extensions/*.sh
|
||||
do
|
||||
|
|
@ -157,10 +175,10 @@ build()
|
|||
|
||||
# *TODO: Make this a build extension.
|
||||
package_llphysicsextensions_tpv || fatal "failed building llphysicsextensions packages"
|
||||
end_section "extensions $variant"
|
||||
|
||||
echo true >"$build_dir"/build_ok
|
||||
else
|
||||
echo "Skipping build due to configuration build_viewer=${build_viewer}"
|
||||
record_event "Skipping build due to configuration build_viewer=${build_viewer}"
|
||||
echo true >"$build_dir"/build_ok
|
||||
fi
|
||||
}
|
||||
|
|
@ -176,13 +194,9 @@ then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Check to see if we're skipping the platform
|
||||
if ! eval '$build_'"$arch"
|
||||
then
|
||||
record_event "building on architecture $arch is disabled"
|
||||
pass
|
||||
fi
|
||||
initialize_build # provided by master buildscripts build.sh
|
||||
|
||||
begin_section "autobuild initialize"
|
||||
# ensure AUTOBUILD is in native path form for child processes
|
||||
AUTOBUILD="$(native_path "$AUTOBUILD")"
|
||||
# set "$autobuild" to cygwin path form for use locally in this script
|
||||
|
|
@ -194,7 +208,17 @@ then
|
|||
fi
|
||||
|
||||
# load autobuild provided shell functions and variables
|
||||
eval "$("$autobuild" --quiet source_environment)"
|
||||
"$autobuild" --quiet source_environment > "$build_log_dir/source_environment"
|
||||
PYTHONPATH="$BUILDSCRIPTS_SHARED/packages/lib/python:$PYTHONPATH"
|
||||
begin_section "dump source environment commands"
|
||||
cat "$build_log_dir/source_environment"
|
||||
end_section "dump source environment commands"
|
||||
|
||||
begin_section "execute source environment commands"
|
||||
. "$build_log_dir/source_environment"
|
||||
end_section "execute source environment commands"
|
||||
|
||||
end_section "autobuild initialize"
|
||||
|
||||
# something about the additional_packages mechanism messes up buildscripts results.py on Linux
|
||||
# since we don't care about those packages on Linux, just zero it out, yes - a HACK
|
||||
|
|
@ -203,10 +227,9 @@ then
|
|||
export additional_packages=
|
||||
fi
|
||||
|
||||
# dump environment variables for debugging
|
||||
begin_section "Environment"
|
||||
env|sort
|
||||
end_section "Environment"
|
||||
python_cmd "$helpers/codeticket.py" addinput "Viewer Channel" "${viewer_channel}"
|
||||
|
||||
initialize_version # provided by buildscripts build.sh; sets version id
|
||||
|
||||
# Now run the build
|
||||
succeeded=true
|
||||
|
|
@ -214,9 +237,6 @@ build_processes=
|
|||
last_built_variant=
|
||||
for variant in $variants
|
||||
do
|
||||
eval '$build_'"$variant" || continue
|
||||
eval '$build_'"$arch"_"$variant" || continue
|
||||
|
||||
# Only the last built arch is available for upload
|
||||
last_built_variant="$variant"
|
||||
|
||||
|
|
@ -232,6 +252,9 @@ do
|
|||
then
|
||||
begin_section "Build $variant"
|
||||
build "$variant" "$build_dir"
|
||||
end_section "Build $variant"
|
||||
|
||||
begin_section "post-build $variant"
|
||||
if `cat "$build_dir/build_ok"`
|
||||
then
|
||||
case "$variant" in
|
||||
|
|
@ -239,10 +262,11 @@ do
|
|||
if [ -r "$build_dir/autobuild-package.xml" ]
|
||||
then
|
||||
begin_section "Autobuild metadata"
|
||||
upload_item docs "$build_dir/autobuild-package.xml" text/xml
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Autobuild Metadata" "$build_dir/autobuild-package.xml" --mimetype text/xml \
|
||||
|| fatal "Upload of autobuild metadata failed"
|
||||
if [ "$arch" != "Linux" ]
|
||||
then
|
||||
record_dependencies_graph # defined in buildscripts/hg/bin/build.sh
|
||||
record_dependencies_graph "$build_dir/autobuild-package.xml" # defined in buildscripts/hg/bin/build.sh
|
||||
else
|
||||
record_event "TBD - no dependency graph for linux (probable python version dependency)"
|
||||
fi
|
||||
|
|
@ -250,17 +274,25 @@ do
|
|||
else
|
||||
record_event "no autobuild metadata at '$build_dir/autobuild-package.xml'"
|
||||
fi
|
||||
if [ -r "$build_dir/newview/viewer_version.txt" ]
|
||||
then
|
||||
begin_section "Viewer Version"
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Viewer Version" "$(<"$build_dir/newview/viewer_version.txt")" --mimetype inline-text \
|
||||
|| fatal "Upload of viewer version failed"
|
||||
end_section "Viewer Version"
|
||||
fi
|
||||
;;
|
||||
Doxygen)
|
||||
if [ -r "$build_dir/doxygen_warnings.log" ]
|
||||
then
|
||||
record_event "Doxygen warnings generated; see doxygen_warnings.log"
|
||||
upload_item log "$build_dir/doxygen_warnings.log" text/plain
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Doxygen Log" "$build_dir/doxygen_warnings.log" --mimetype text/plain ## TBD
|
||||
fi
|
||||
if [ -d "$build_dir/doxygen/html" ]
|
||||
then
|
||||
tar -c -f "$build_dir/viewer-doxygen.tar.bz2" --strip-components 3 "$build_dir/doxygen/html"
|
||||
upload_item docs "$build_dir/viewer-doxygen.tar.bz2" binary/octet-stream
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Doxygen Tarball" "$build_dir/viewer-doxygen.tar.bz2" \
|
||||
|| fatal "Upload of doxygen tarball failed"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
|
|
@ -270,7 +302,8 @@ do
|
|||
else
|
||||
record_failure "Build of \"$variant\" failed."
|
||||
fi
|
||||
end_section "Build $variant"
|
||||
end_section "post-build $variant"
|
||||
|
||||
else
|
||||
record_event "configure for $variant failed: build skipped"
|
||||
fi
|
||||
|
|
@ -290,7 +323,7 @@ then
|
|||
if $build_viewer_deb && [ "$last_built_variant" == "Release" ]
|
||||
then
|
||||
begin_section "Build Viewer Debian Package"
|
||||
# have_private_repo=false - <FS:TM> FS doesnt use this
|
||||
|
||||
# mangle the changelog
|
||||
dch --force-bad-version \
|
||||
--distribution unstable \
|
||||
|
|
@ -316,47 +349,26 @@ then
|
|||
|
||||
# upload debian package and create repository
|
||||
begin_section "Upload Debian Repository"
|
||||
for deb_file in ../*.deb; do
|
||||
upload_item debian $deb_file binary/octet-stream
|
||||
for deb_file in `/bin/ls ../packages_public/*.deb ../*.deb 2>/dev/null`; do
|
||||
deb_pkg=$(basename "$deb_file" | sed 's,_.*,,')
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Debian $deb_pkg" $deb_file \
|
||||
|| fatal "Upload of debian $deb_pkg failed"
|
||||
done
|
||||
for deb_file in `/bin/ls ../packages_private/*.deb 2>/dev/null`; do
|
||||
deb_pkg=$(basename "$deb_file" | sed 's,_.*,,')
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Debian $deb_pkg" "$deb_file" --private \
|
||||
|| fatal "Upload of debian $deb_pkg failed"
|
||||
done
|
||||
if [ -d "$build_log_dir/debian_repo" ]
|
||||
then
|
||||
pushd "$build_log_dir/debian_repo"
|
||||
cat > Release <<EOF
|
||||
Archive: stable
|
||||
Component: main
|
||||
Origin: Teamcity
|
||||
Label: Teamcity built .debs
|
||||
Architecture: i386 amd64 any
|
||||
EOF
|
||||
if dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz \
|
||||
&& dpkg-scansources . /dev/null | gzip -9c > Sources.gz
|
||||
then
|
||||
begin_section Packages.gz
|
||||
gunzip --stdout Packages.gz
|
||||
for file in *.deb
|
||||
do
|
||||
stat "$file" | sed 2q
|
||||
md5sum "$file"
|
||||
done
|
||||
end_section Packages.gz
|
||||
|
||||
for file in *
|
||||
do
|
||||
upload_item debian_repo "$file" binary/octet-stream
|
||||
done
|
||||
else
|
||||
record_failure 'Unable to generate Packages.gz or Sources.gz'
|
||||
create_deb_repo
|
||||
|
||||
# Rename the local debian_repo* directories so that the master buildscript
|
||||
# doesn't make a remote repo again.
|
||||
for debian_repo_type in debian_repo debian_repo_private; do
|
||||
if [ -d "$build_log_dir/$debian_repo_type" ]; then
|
||||
mv $build_log_dir/$debian_repo_type $build_log_dir/${debian_repo_type}_pushed
|
||||
fi
|
||||
popd
|
||||
|
||||
process_pending_uploads
|
||||
|
||||
# Rename the local debian_repo directory so that the master buildscript
|
||||
# doesn't make a remote repo again.
|
||||
|
||||
mv $build_log_dir/debian_repo $build_log_dir/debian_repo_pushed
|
||||
fi
|
||||
done
|
||||
end_section "Upload Debian Repository"
|
||||
|
||||
else
|
||||
|
|
@ -372,18 +384,17 @@ if $succeeded
|
|||
then
|
||||
if $build_viewer
|
||||
then
|
||||
begin_section Upload Installer
|
||||
begin_section "Uploads"
|
||||
# Upload installer
|
||||
package=$(installer_$arch)
|
||||
if [ x"$package" = x ] || test -d "$package"
|
||||
then
|
||||
record_event "??? mystery event $package // $build_coverity"
|
||||
fatal "No installer found from `pwd`"
|
||||
succeeded=$build_coverity
|
||||
else
|
||||
# Upload base package.
|
||||
upload_item installer "$package" binary/octet-stream
|
||||
upload_item quicklink "$package" binary/octet-stream
|
||||
[ -f $build_dir/summary.json ] && upload_item installer $build_dir/summary.json text/plain
|
||||
python_cmd "$helpers/codeticket.py" addoutput Installer "$package" \
|
||||
|| fatal "Upload of installer failed"
|
||||
|
||||
# Upload additional packages.
|
||||
for package_id in $additional_packages
|
||||
|
|
@ -391,32 +402,44 @@ then
|
|||
package=$(installer_$arch "$package_id")
|
||||
if [ x"$package" != x ]
|
||||
then
|
||||
upload_item installer "$package" binary/octet-stream
|
||||
upload_item quicklink "$package" binary/octet-stream
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Installer $package_id" "$package" \
|
||||
|| fatal "Upload of installer $package_id failed"
|
||||
else
|
||||
record_failure "Failed to find additional package for '$package_id'."
|
||||
fi
|
||||
done
|
||||
|
||||
case "$last_built_variant" in
|
||||
Release)
|
||||
# Upload crash reporter files
|
||||
for symbolfile in $symbolfiles
|
||||
do
|
||||
upload_item symbolfile "$build_dir/$symbolfile" binary/octet-stream
|
||||
done
|
||||
if [ "$last_built_variant" = "Release" ]
|
||||
then
|
||||
# nat 2016-12-22: without RELEASE_CRASH_REPORTING, we have no symbol file.
|
||||
if [ "${RELEASE_CRASH_REPORTING:-}" != "OFF" ]
|
||||
then
|
||||
# Upload crash reporter file
|
||||
# These names must match the set of VIEWER_SYMBOL_FILE in indra/newview/CMakeLists.txt
|
||||
case "$arch" in
|
||||
CYGWIN)
|
||||
symbolfile="$build_dir/newview/Release/secondlife-symbols-windows-${AUTOBUILD_ADDRSIZE}.tar.bz2"
|
||||
;;
|
||||
Darwin)
|
||||
symbolfile="$build_dir/newview/Release/secondlife-symbols-darwin-${AUTOBUILD_ADDRSIZE}.tar.bz2"
|
||||
;;
|
||||
Linux)
|
||||
symbolfile="$build_dir/newview/Release/secondlife-symbols-linux-${AUTOBUILD_ADDRSIZE}.tar.bz2"
|
||||
;;
|
||||
esac
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Symbolfile" "$symbolfile" \
|
||||
|| fatal "Upload of symbolfile failed"
|
||||
fi
|
||||
|
||||
# Upload the llphysicsextensions_tpv package, if one was produced
|
||||
# *TODO: Make this an upload-extension
|
||||
if [ -r "$build_dir/llphysicsextensions_package" ]
|
||||
then
|
||||
llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
|
||||
upload_item private_artifact "$llphysicsextensions_package" binary/octet-stream
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
# Upload the llphysicsextensions_tpv package, if one was produced
|
||||
# *TODO: Make this an upload-extension
|
||||
if [ -r "$build_dir/llphysicsextensions_package" ]
|
||||
then
|
||||
llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
|
||||
python_cmd "$helpers/codeticket.py" addoutput "Physics Extensions Package" "$llphysicsextensions_package" --private \
|
||||
|| fatal "Upload of physics extensions package failed"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Run upload extensions
|
||||
if [ -d ${build_dir}/packages/upload-extensions ]; then
|
||||
|
|
@ -427,7 +450,7 @@ then
|
|||
done
|
||||
fi
|
||||
fi
|
||||
end_section Upload Installer
|
||||
end_section "Uploads"
|
||||
else
|
||||
record_event "skipping upload of installer"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -187,7 +187,6 @@ Ansariel Hiller
|
|||
STORM-1984
|
||||
STORM-1979
|
||||
STORM-2083
|
||||
STORM-2105
|
||||
MAINT-5533
|
||||
STORM-2094
|
||||
MAINT-5756
|
||||
|
|
@ -365,7 +364,6 @@ Cinder Roxley
|
|||
STORM-2037
|
||||
STORM-2053
|
||||
STORM-2098
|
||||
STORM-2105
|
||||
STORM-2113
|
||||
STORM-2124
|
||||
STORM-2127
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
# cmake_minimum_required should appear before any
|
||||
# other commands to guarantee full compatibility
|
||||
# with the version specified
|
||||
## prior to 2.8, the add_custom_target commands used in setting the version did not work correctly
|
||||
cmake_minimum_required(VERSION 2.8.8 FATAL_ERROR)
|
||||
## prior to 3.4, the Windows manifest handling was missing
|
||||
cmake_minimum_required(VERSION 3.4.0 FATAL_ERROR)
|
||||
|
||||
# [FS:CR] Shut up Cmake 2.8.12+ by using the old policy.
|
||||
if(${CMAKE_VERSION} VERSION_GREATER 2.8.12 OR ${CMAKE_VERSION} VERSION_EQUAL 2.8.12)
|
||||
|
|
@ -102,7 +102,7 @@ if (LINUX)
|
|||
include(LLAppearanceUtility)
|
||||
add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
|
||||
endif (INSTALL_PROPRIETARY)
|
||||
add_dependencies(viewer linux-crash-logger-strip-target linux-updater)
|
||||
add_dependencies(viewer linux-crash-logger-strip-target)
|
||||
elseif (DARWIN)
|
||||
add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
|
||||
add_dependencies(viewer mac-crash-logger)
|
||||
|
|
@ -114,9 +114,6 @@ elseif (WINDOWS)
|
|||
endif (EXISTS ${VIEWER_DIR}win_setup)
|
||||
# add_dependencies(viewer windows-setup windows-crash-logger)
|
||||
add_dependencies(viewer windows-crash-logger)
|
||||
elseif (SOLARIS)
|
||||
add_subdirectory(solaris_crash_logger)
|
||||
add_dependencies(viewer solaris-crash-logger)
|
||||
endif (LINUX)
|
||||
|
||||
add_subdirectory(${VIEWER_PREFIX}newview)
|
||||
|
|
|
|||
|
|
@ -48,8 +48,8 @@ Compilation
|
|||
LL_WINDOWS=1 " "
|
||||
UNICODE " "
|
||||
_UNICODE " "
|
||||
WINVER=0x0501 " "
|
||||
_WIN32_WINNT=0x0501 " "
|
||||
WINVER=0x0600 " "
|
||||
_WIN32_WINNT=0x0600 " "
|
||||
LL_OS_DRAGDROP_ENABLED=1 " "
|
||||
LIB_NDOF=1 " "
|
||||
|
||||
|
|
|
|||
|
|
@ -2,18 +2,39 @@
|
|||
#
|
||||
# Compilation options shared by all Second Life components.
|
||||
|
||||
#*****************************************************************************
|
||||
# It's important to realize that CMake implicitly concatenates
|
||||
# CMAKE_CXX_FLAGS with (e.g.) CMAKE_CXX_FLAGS_RELEASE for Release builds. So
|
||||
# set switches in CMAKE_CXX_FLAGS that should affect all builds, but in
|
||||
# CMAKE_CXX_FLAGS_RELEASE or CMAKE_CXX_FLAGS_RELWITHDEBINFO for switches
|
||||
# that should affect only that build variant.
|
||||
#
|
||||
# Also realize that CMAKE_CXX_FLAGS may already be partially populated on
|
||||
# entry to this file.
|
||||
#*****************************************************************************
|
||||
|
||||
if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||
set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
|
||||
|
||||
include(Variables)
|
||||
|
||||
# Portable compilation flags.
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
"-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DNDEBUG")
|
||||
# We go to some trouble to set LL_BUILD to the set of relevant compiler flags.
|
||||
# <FS:Ansariel> Use the previous version for Windows or the compile command line will be screwed up royally
|
||||
if (WINDOWS)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{LL_BUILD_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "$ENV{LL_BUILD_RELWITHDEBINFO}")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{LL_BUILD_DEBUG}")
|
||||
else (WINDOWS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}")
|
||||
endif (WINDOWS)
|
||||
# Given that, all the flags you see added below are flags NOT present in
|
||||
# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables.
|
||||
# Before adding new ones here, it's important to ask: can this flag really be
|
||||
# applied to the viewer only, or should/must it be applied to all 3p libraries
|
||||
# as well?
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
"-DLL_RELEASE=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
|
||||
# Portable compilation flags.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DADDRESS_SIZE=${ADDRESS_SIZE}")
|
||||
|
||||
# Configure crash reporting
|
||||
set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
|
||||
|
|
@ -46,17 +67,13 @@ if (WINDOWS)
|
|||
# http://www.cmake.org/pipermail/cmake/2009-September/032143.html
|
||||
string(REPLACE "/Zm1000" " " CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP -D_SCL_SECURE_NO_WARNINGS=1"
|
||||
CACHE STRING "C++ compiler debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
#<FS:LO> Change MSVC multi processor from a hardcoded 8 to no number to allow the compiler to spawn a number equal to the number of thread execution units the computer has.
|
||||
#${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /Zo /MD /MP8 /Ob0 -D_SECURE_STL=0"
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /Zo /MD /MP /Ob0 -D_SECURE_STL=0"
|
||||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo"
|
||||
CACHE STRING "C++ compiler release-with-debug options" FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE
|
||||
#<FS:LO> Change MSVC multi processor from a hardcoded 8 to no number to allow the compiler to spawn a number equal to the number of thread execution units the computer has.
|
||||
#"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /Zo /MD /MP8 /Ob2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /Zo /MD /MP /Ob2 -D_SECURE_STL=0 -D_HAS_ITERATOR_DEBUGGING=0"
|
||||
"${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /Zo"
|
||||
CACHE STRING "C++ compiler release options" FORCE)
|
||||
# zlib has assembly-language object files incompatible with SAFESEH
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE /SAFESEH:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099")
|
||||
|
|
@ -64,200 +81,96 @@ if (WINDOWS)
|
|||
set(CMAKE_CXX_STANDARD_LIBRARIES "")
|
||||
set(CMAKE_C_STANDARD_LIBRARIES "")
|
||||
|
||||
# <FS:Ansariel> [AVX Optimization]
|
||||
# add_definitions(
|
||||
# /DLL_WINDOWS=1
|
||||
# /DDOM_DYNAMIC
|
||||
# /DUNICODE
|
||||
# /D_UNICODE
|
||||
# /GS
|
||||
# /TP
|
||||
# /W3
|
||||
# /c
|
||||
# /Zc:forScope
|
||||
# /nologo
|
||||
# /Oy-
|
||||
# /Zc:wchar_t-
|
||||
# /arch:SSE2
|
||||
# /fp:fast
|
||||
# )
|
||||
if (USE_AVX_OPTIMIZATION)
|
||||
add_definitions(
|
||||
/DLL_WINDOWS=1
|
||||
add_definitions(
|
||||
/DNOMINMAX
|
||||
# /DDOM_DYNAMIC # For shared library colladadom
|
||||
/DUNICODE
|
||||
/D_UNICODE
|
||||
/GS
|
||||
/TP
|
||||
/W3
|
||||
/c
|
||||
/Zc:forScope
|
||||
/nologo
|
||||
/Oy-
|
||||
/Zc:wchar_t-
|
||||
/arch:AVX
|
||||
# /fp:fast
|
||||
)
|
||||
elseif (USE_AVX2_OPTIMIZATION)
|
||||
add_definitions(
|
||||
/DLL_WINDOWS=1
|
||||
/DNOMINMAX
|
||||
# /DDOM_DYNAMIC # For shared library colladadom
|
||||
/DUNICODE
|
||||
/D_UNICODE
|
||||
/GS
|
||||
/TP
|
||||
/W3
|
||||
/c
|
||||
/Zc:forScope
|
||||
/nologo
|
||||
/Oy-
|
||||
/Zc:wchar_t-
|
||||
/arch:AVX2
|
||||
# /fp:fast
|
||||
)
|
||||
else (USE_AVX_OPTIMIZATION)
|
||||
add_definitions(
|
||||
/DLL_WINDOWS=1
|
||||
/DNOMINMAX
|
||||
# /DDOM_DYNAMIC
|
||||
/DUNICODE
|
||||
/D_UNICODE
|
||||
/GS
|
||||
/TP
|
||||
/W3
|
||||
/c
|
||||
/Zc:forScope
|
||||
/nologo
|
||||
/Oy-
|
||||
/Zc:wchar_t-
|
||||
# /arch:SSE2
|
||||
# /fp:fast
|
||||
)
|
||||
if( NOT ND_BUILD64BIT_ARCH )
|
||||
add_definitions( /arch:SSE2 )
|
||||
endif( NOT ND_BUILD64BIT_ARCH )
|
||||
)
|
||||
|
||||
# <FS:Ansariel> AVX/AVX2 support
|
||||
if (USE_AVX_OPTIMIZATION)
|
||||
add_compile_options(
|
||||
/GS
|
||||
/TP
|
||||
/W3
|
||||
/c
|
||||
/Zc:forScope
|
||||
/nologo
|
||||
/Oy-
|
||||
/arch:AVX
|
||||
/fp:fast
|
||||
)
|
||||
elseif (USE_AVX2_OPTIMIZATION)
|
||||
add_compile_options(
|
||||
/GS
|
||||
/TP
|
||||
/W3
|
||||
/c
|
||||
/Zc:forScope
|
||||
/nologo
|
||||
/Oy-
|
||||
/arch:AVX2
|
||||
# /fp:fast
|
||||
)
|
||||
else (USE_AVX_OPTIMIZATION)
|
||||
# </FS:Ansariel> AVX/AVX2 support
|
||||
add_compile_options(
|
||||
/GS
|
||||
/TP
|
||||
/W3
|
||||
/c
|
||||
/Zc:forScope
|
||||
/nologo
|
||||
/Oy-
|
||||
# /arch:SSE2
|
||||
/fp:fast
|
||||
)
|
||||
|
||||
# Nicky: x64 implies SSE2
|
||||
if( ADDRESS_SIZE EQUAL 32 )
|
||||
add_definitions( /arch:SSE2 )
|
||||
endif()
|
||||
# <FS:Ansariel> AVX/AVX2 support
|
||||
endif (USE_AVX_OPTIMIZATION)
|
||||
# </FS:Ansariel> [AVX Optimization]
|
||||
|
||||
# Are we using the crummy Visual Studio KDU build workaround?
|
||||
if (NOT VS_DISABLE_FATAL_WARNINGS)
|
||||
add_definitions(/WX)
|
||||
endif (NOT VS_DISABLE_FATAL_WARNINGS)
|
||||
|
||||
# configure Win32 API for Windows Vista+ compatibility
|
||||
set(WINVER "0x0600" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
|
||||
add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
|
||||
|
||||
if( ND_BUILD64BIT_ARCH )
|
||||
add_definitions("/wd4267 /DND_BUILD64BIT_ARCH" )
|
||||
else( ND_BUILD64BIT_ARCH )
|
||||
add_definitions("/fp:fast" )
|
||||
endif( ND_BUILD64BIT_ARCH )
|
||||
|
||||
endif (WINDOWS)
|
||||
|
||||
|
||||
if (LINUX)
|
||||
set(CMAKE_SKIP_RPATH TRUE)
|
||||
|
||||
# Here's a giant hack for Fedora 8, where we can't use
|
||||
# _FORTIFY_SOURCE if we're using a compiler older than gcc 4.1.
|
||||
|
||||
find_program(GXX g++)
|
||||
mark_as_advanced(GXX)
|
||||
|
||||
if (GXX)
|
||||
execute_process(
|
||||
COMMAND ${GXX} --version
|
||||
COMMAND sed "s/^[gc+ ]*//"
|
||||
COMMAND head -1
|
||||
OUTPUT_VARIABLE GXX_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
else (GXX)
|
||||
set(GXX_VERSION x)
|
||||
endif (GXX)
|
||||
|
||||
# The quoting hack here is necessary in case we're using distcc or
|
||||
# ccache as our compiler. CMake doesn't pass the command line
|
||||
# through the shell by default, so we end up trying to run "distcc"
|
||||
# " g++" - notice the leading space. Ugh.
|
||||
|
||||
# <FS:ND/>
|
||||
# And another hack for FORTIFY_SOURCE. Some distributions (for example Gentoo) define FORTIFY_SOURCE by default.
|
||||
# Check if this is the case, if yes, do not define it again.
|
||||
execute_process(
|
||||
COMMAND sh -c "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} --version"
|
||||
COMMAND sed "s/^[gc+ ]*//"
|
||||
COMMAND head -1
|
||||
OUTPUT_VARIABLE CXX_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
COMMAND echo "int main( char **a, int c ){ \n#ifdef _FORTIFY_SOURCE\n#error FORTITY_SOURCE_SET\n#else\nreturn 0;\n#endif\n}"
|
||||
COMMAND sh -c "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} -xc++ -w - -o /dev/null"
|
||||
OUTPUT_VARIABLE FORTIFY_SOURCE_OUT
|
||||
ERROR_VARIABLE FORTIFY_SOURCE_ERR
|
||||
RESULT_VARIABLE FORTIFY_SOURCE_RES
|
||||
)
|
||||
|
||||
#<FS:ND> Gentoo defines _FORTIFY_SOURCE by default
|
||||
if (NOT ND_SYSTEM_DEFINES_FORTIFY_SOURCE)
|
||||
#</FS:ND>
|
||||
|
||||
if (${GXX_VERSION} STREQUAL ${CXX_VERSION})
|
||||
add_definitions(-D_FORTIFY_SOURCE=2)
|
||||
else (${GXX_VERSION} STREQUAL ${CXX_VERSION})
|
||||
if (NOT ${GXX_VERSION} MATCHES " 4.1.*Red Hat")
|
||||
add_definitions(-D_FORTIFY_SOURCE=2)
|
||||
endif (NOT ${GXX_VERSION} MATCHES " 4.1.*Red Hat")
|
||||
endif (${GXX_VERSION} STREQUAL ${CXX_VERSION})
|
||||
|
||||
#<FS:ND> Gentoo defines _FORTIFY_SOURCE by default
|
||||
endif (NOT ND_SYSTEM_DEFINES_FORTIFY_SOURCE)
|
||||
#</FS:ND>
|
||||
|
||||
# Let's actually get a numerical version of gxx's version
|
||||
STRING(REGEX REPLACE ".* ([0-9])\\.([0-9])\\.([0-9]).*" "\\1\\2\\3" CXX_VERSION_NUMBER ${CXX_VERSION})
|
||||
|
||||
# Hacks to work around gcc 4.1 TC build pool machines which can't process pragma warning disables
|
||||
# This is pure rubbish; I wish there was another way.
|
||||
#
|
||||
if(${CXX_VERSION_NUMBER} LESS 420)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-uninitialized -Wno-unused-variable -Wno-unused-function ${CMAKE_CXX_FLAGS}")
|
||||
endif (${CXX_VERSION_NUMBER} LESS 420)
|
||||
|
||||
if(${CXX_VERSION_NUMBER} GREATER 459)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}")
|
||||
endif (${CXX_VERSION_NUMBER} GREATER 459)
|
||||
if ( ${FORTIFY_SOURCE_RES} EQUAL 0 )
|
||||
add_definitions(-D_FORTIFY_SOURCE=2)
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# gcc 4.3 and above don't like the LL boost and also
|
||||
# cause warnings due to our use of deprecated headers
|
||||
if(${CXX_VERSION_NUMBER} GREATER 429)
|
||||
add_definitions(-Wno-parentheses)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-deprecated ${CMAKE_CXX_FLAGS}")
|
||||
endif (${CXX_VERSION_NUMBER} GREATER 429)
|
||||
|
||||
#<FS:ND> Disable unused-but-set-variable for GCC >= 4.6. It causes a lot of warning/errors all over the source. Fixing that would result in changing a good amount of files.
|
||||
if(${CXX_VERSION_NUMBER} GREATER 460)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-unused-but-set-variable ${CMAKE_CXX_FLAGS}")
|
||||
endif (${CXX_VERSION_NUMBER} GREATER 460)
|
||||
#</FS:ND>
|
||||
#<FS:ND> Disable attribute warnings for GCC >= 4.7. It causes a lot of warning/errors in boost.
|
||||
if(${CXX_VERSION_NUMBER} GREATER 470)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-attributes ${CMAKE_CXX_FLAGS}")
|
||||
endif (${CXX_VERSION_NUMBER} GREATER 470)
|
||||
#</FS:ND>
|
||||
#<FS:ND> Disable unsed local typedef warnings for GCC >= 4.8. It causes a lot of warning/errors in boost.
|
||||
if(${CXX_VERSION_NUMBER} GREATER 480)
|
||||
set(CMAKE_CXX_FLAGS "-Wno-unused-local-typedefs ${CMAKE_CXX_FLAGS}")
|
||||
endif (${CXX_VERSION_NUMBER} GREATER 480)
|
||||
#</FS:ND>
|
||||
|
||||
|
||||
|
||||
# End of hacks.
|
||||
add_definitions(-Wno-parentheses)
|
||||
|
||||
add_definitions(
|
||||
-DLL_LINUX=1
|
||||
-D_REENTRANT
|
||||
)
|
||||
add_compile_options(
|
||||
-fexceptions
|
||||
-fno-math-errno
|
||||
-fno-strict-aliasing
|
||||
-fsigned-char
|
||||
-g
|
||||
-msse2
|
||||
-mfpmath=sse
|
||||
-pthread
|
||||
|
|
@ -272,80 +185,47 @@ if (LINUX)
|
|||
|
||||
|
||||
add_definitions(-DAPPID=secondlife)
|
||||
add_definitions(-fvisibility=hidden)
|
||||
# don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The viewer doesn't need to catch SIGCHLD anyway.
|
||||
add_compile_options(-fvisibility=hidden)
|
||||
# don't catch SIGCHLD in our base application class for the viewer - some of
|
||||
# our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The
|
||||
# viewer doesn't need to catch SIGCHLD anyway.
|
||||
add_definitions(-DLL_IGNORE_SIGCHLD)
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
add_definitions(-march=pentium4)
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
add_definitions(-mfpmath=sse)
|
||||
#add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
add_compile_options(-march=pentium4)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
#add_compile_options(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
|
||||
if (NOT USESYSTEMLIBS)
|
||||
# this stops us requiring a really recent glibc at runtime
|
||||
add_definitions(-fno-stack-protector)
|
||||
add_compile_options(-fno-stack-protector)
|
||||
# linking can be very memory-hungry, especially the final viewer link
|
||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory -Wl,--build-id -Wl,-rpath,'$ORIGIN:$ORIGIN/../lib' -Wl,--exclude-libs,ALL")
|
||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
|
||||
endif (NOT USESYSTEMLIBS)
|
||||
|
||||
# <FS:TS> Enable AVX optimizations if requested and at least GCC 4.6.
|
||||
if (USE_AVX_OPTIMIZATION)
|
||||
if (NOT (${CXX_VERSION_NUMBER} LESS 460))
|
||||
add_definitions(-mavx)
|
||||
else (NOT (${CXX_VERSION_NUMBER} LESS 460))
|
||||
error ("AVX optimizations require at least version 4.6.0 of GCC.")
|
||||
endif (NOT (${CXX_VERSION_NUMBER} LESS 460))
|
||||
endif (USE_AVX_OPTIMIZATION)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
|
||||
# <FS:ND> Build without frame pointer if requested. Otherwise profiling might not work reliable. N.B. Win32 uses FP based calling by default.
|
||||
if( NO_OMIT_FRAMEPOINTER )
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-fno-omit-frame-pointer ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
endif( NO_OMIT_FRAMEPOINTER )
|
||||
# </FS:ND>
|
||||
endif (LINUX)
|
||||
|
||||
|
||||
if (DARWIN)
|
||||
add_definitions(-DLL_DARWIN=1)
|
||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,-no_compact_unwind -Wl,-headerpad_max_install_names,-search_paths_first")
|
||||
set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
|
||||
set(DARWIN_extra_cstar_flags "-g -Wno-unused-local-typedef -Wno-deprecated-declarations")
|
||||
# <FS:TS> Take a deep breath and turn on C++11...
|
||||
set(DARWIN_extra_cstar_flags "-std=c++11 -stdlib=libc++ -Wno-overloaded-virtual ${DARWIN_extra_cstar_flags}")
|
||||
# </FS:TS>
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}")
|
||||
set(DARWIN_extra_cstar_flags "-Wno-unused-local-typedef -Wno-deprecated-declarations")
|
||||
# Ensure that CMAKE_CXX_FLAGS has the correct -g debug information format --
|
||||
# see Variables.cmake.
|
||||
string(REPLACE "-gdwarf-2" "-g${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}"
|
||||
CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
# The viewer code base can now be successfully compiled with -std=c++14. But
|
||||
# turning that on in the generic viewer-build-variables/variables file would
|
||||
# potentially require tweaking each of our ~50 third-party library builds.
|
||||
# Until we decide to set -std=c++14 in viewer-build-variables/variables, set
|
||||
# it locally here: we want to at least prevent inadvertently reintroducing
|
||||
# viewer code that would fail with C++14.
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags} -std=c++14")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${DARWIN_extra_cstar_flags}")
|
||||
# NOTE: it's critical that the optimization flag is put in front.
|
||||
# NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O0 ${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
if (USE_AVX_OPTIMIZATION)
|
||||
if (XCODE_VERSION GREATER 4.9)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS AVX)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL -Ofast)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -mavx ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-Ofast -mavx ${CMAKE_C_FLAGS_RELEASE}")
|
||||
else (XCODE_VERSION GREATER 4.9)
|
||||
error("Darwin AVX Optimizations only available on Xcode5 with Clang, silly person!")
|
||||
endif (XCODE_VERSION GREATER 4.9)
|
||||
else (USE_AVX_OPTIMIZATION)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS SSE3)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL -O3)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -msse3 ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "-O3 -msse3 ${CMAKE_C_FLAGS_RELEASE}")
|
||||
endif (USE_AVX_OPTIMIZATION)
|
||||
set(ENABLE_SIGNING TRUE)
|
||||
# <FS:TS> Sign with our identity, not LL's...
|
||||
# set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.")
|
||||
set(SIGNING_IDENTITY "Developer ID Application: Phoenix Firestorm Project, Inc., The")
|
||||
# <FS:ND> Build without frame pointer if requested. Otherwise profiling might not work reliable. N.B. Win32 uses FP based calling by default.
|
||||
if( NO_OMIT_FRAMEPOINTER )
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-fno-omit-frame-pointer ${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
endif( NO_OMIT_FRAMEPOINTER )
|
||||
# </FS:ND>
|
||||
|
||||
## Really?? On developer machines too?
|
||||
##set(ENABLE_SIGNING TRUE)
|
||||
##set(SIGNING_IDENTITY "Developer ID Application: Phoenix Firestorm Project, Inc., The"")
|
||||
endif (DARWIN)
|
||||
|
||||
|
||||
|
|
@ -374,26 +254,17 @@ if (LINUX OR DARWIN)
|
|||
set(CMAKE_C_FLAGS "${GCC_WARNINGS} ${CMAKE_C_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${GCC_CXX_WARNINGS} ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
|
||||
elseif (WORD_SIZE EQUAL 64)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m64")
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
|
||||
if (ND_BUILD64BIT_ARCH)
|
||||
add_definitions(-DND_BUILD64BIT_ARCH)
|
||||
endif (ND_BUILD64BIT_ARCH)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m${ADDRESS_SIZE}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m${ADDRESS_SIZE}")
|
||||
endif (LINUX OR DARWIN)
|
||||
|
||||
|
||||
if (USESYSTEMLIBS)
|
||||
add_definitions(-DLL_USESYSTEMLIBS=1)
|
||||
|
||||
if (LINUX AND ${ARCH} STREQUAL "i686")
|
||||
if (LINUX AND ADDRESS_SIZE EQUAL 32)
|
||||
add_definitions(-march=pentiumpro)
|
||||
endif (LINUX AND ${ARCH} STREQUAL "i686")
|
||||
endif (LINUX AND ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
else (USESYSTEMLIBS)
|
||||
set(${ARCH}_linux_INCLUDES
|
||||
|
|
|
|||
|
|
@ -8,12 +8,10 @@ if (USESYSTEMLIBS)
|
|||
else (USESYSTEMLIBS)
|
||||
if (LINUX)
|
||||
# Need to add dependency pthread explicitely to support ld.gold.
|
||||
if( NOT ND_BUILD64BIT_ARCH )
|
||||
use_prebuilt_binary(db)
|
||||
set(DB_LIBRARIES db-5.1 pthread)
|
||||
endif( NOT ND_BUILD64BIT_ARCH )
|
||||
# use_prebuilt_binary(db)
|
||||
# set(DB_LIBRARIES db-5.1 pthread)
|
||||
else (LINUX)
|
||||
set(DB_LIBRARIES db-4.2)
|
||||
# set(DB_LIBRARIES db-4.2)
|
||||
endif (LINUX)
|
||||
set(DB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
|
|
|||
|
|
@ -2,15 +2,18 @@
|
|||
# Construct the version and copyright information based on package data.
|
||||
include(Python)
|
||||
|
||||
if( ND_BUILD64BIT_ARCH )
|
||||
set( ND_PKG_FLAGS "-m64" )
|
||||
else( ND_BUILD64BIT_ARCH )
|
||||
set( ND_PKG_FLAGS "" )
|
||||
endif( ND_BUILD64BIT_ARCH )
|
||||
|
||||
# packages-formatter.py runs autobuild install --versions, which needs to know
|
||||
# the build_directory, which (on Windows) depends on AUTOBUILD_ADDRSIZE.
|
||||
# Within an autobuild build, AUTOBUILD_ADDRSIZE is already set. But when
|
||||
# building in an IDE, it probably isn't. Set it explicitly using
|
||||
# run_build_test.py.
|
||||
add_custom_command(OUTPUT packages-info.txt
|
||||
COMMENT Generating packages-info.txt for the about box
|
||||
MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/../autobuild.xml
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py ${ND_PKG_FLAGS} > packages-info.txt
|
||||
${CMAKE_SOURCE_DIR}/../autobuild.xml
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
${CMAKE_SOURCE_DIR}/cmake/run_build_test.py -DAUTOBUILD_ADDRSIZE=${ADDRESS_SIZE}
|
||||
${PYTHON_EXECUTABLE}
|
||||
${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" > packages-info.txt
|
||||
)
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
|
|||
set(VIEWER_VERSION_REVISION $ENV{revision})
|
||||
message("Revision (from environment): ${VIEWER_VERSION_REVISION}")
|
||||
|
||||
# <FS:Ansariel> Don't use Autobuild build ID - make sure we use the Mercurial revision
|
||||
#elseif (DEFINED ENV{AUTOBUILD_BUILD_ID})
|
||||
# set(VIEWER_VERSION_REVISION $ENV{AUTOBUILD_BUILD_ID})
|
||||
# message(STATUS "Revision (from autobuild environment): ${VIEWER_VERSION_REVISION}")
|
||||
|
||||
else (DEFINED ENV{revision})
|
||||
find_program(MERCURIAL hg)
|
||||
find_program(SED sed)
|
||||
|
|
@ -55,7 +60,7 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
|
|||
endif ("${VIEWER_VERSION_REVISION}" STREQUAL "")
|
||||
|
||||
set(VIEWER_CHANNEL_VERSION_DEFINES
|
||||
"LL_VIEWER_CHANNEL=\"${VIEWER_CHANNEL}\""
|
||||
"LL_VIEWER_CHANNEL=${VIEWER_CHANNEL}"
|
||||
"LL_VIEWER_VERSION_MAJOR=${VIEWER_VERSION_MAJOR}"
|
||||
"LL_VIEWER_VERSION_MINOR=${VIEWER_VERSION_MINOR}"
|
||||
"LL_VIEWER_VERSION_PATCH=${VIEWER_VERSION_PATCH}"
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ if (USESYSTEMLIBS)
|
|||
set(CEFPLUGIN OFF CACHE BOOL
|
||||
"CEFPLUGIN support for the llplugin/llmedia test apps.")
|
||||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(llceflib)
|
||||
use_prebuilt_binary(dullahan)
|
||||
set(CEFPLUGIN ON CACHE BOOL
|
||||
"CEFPLUGIN support for the llplugin/llmedia test apps.")
|
||||
set(CEF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/cef)
|
||||
|
|
@ -16,7 +16,7 @@ if (WINDOWS)
|
|||
set(CEF_PLUGIN_LIBRARIES
|
||||
libcef.lib
|
||||
libcef_dll_wrapper.lib
|
||||
llceflib.lib
|
||||
dullahan.lib
|
||||
)
|
||||
elseif (DARWIN)
|
||||
FIND_LIBRARY(APPKIT_LIBRARY AppKit)
|
||||
|
|
@ -31,7 +31,7 @@ elseif (DARWIN)
|
|||
|
||||
set(CEF_PLUGIN_LIBRARIES
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libLLCefLib.a
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a
|
||||
${APPKIT_LIBRARY}
|
||||
${CEF_LIBRARY}
|
||||
)
|
||||
|
|
@ -40,6 +40,6 @@ elseif (LINUX)
|
|||
set(CEF_PLUGIN_LIBRARIES
|
||||
cef
|
||||
cef_dll_wrapper.a
|
||||
llceflib
|
||||
dullahan
|
||||
)
|
||||
endif (WINDOWS)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ set(cmake_SOURCE_FILES
|
|||
FindFMODEX.cmake
|
||||
FindGLH.cmake
|
||||
FindGoogleBreakpad.cmake
|
||||
FindGooglePerfTools.cmake
|
||||
FindHUNSPELL.cmake
|
||||
FindJsonCpp.cmake
|
||||
FindNDOF.cmake
|
||||
|
|
@ -46,12 +45,8 @@ set(cmake_SOURCE_FILES
|
|||
GLH.cmake
|
||||
GLOD.cmake
|
||||
## GStreamer010Plugin.cmake
|
||||
GetPrerequisites_2_8.cmake
|
||||
## Glui.cmake
|
||||
Glut.cmake
|
||||
GoogleBreakpad.cmake
|
||||
GoogleMock.cmake
|
||||
GooglePerfTools.cmake
|
||||
Growl.cmake
|
||||
Havok.cmake
|
||||
Hunspell.cmake
|
||||
|
|
@ -92,7 +87,6 @@ set(cmake_SOURCE_FILES
|
|||
Prebuilt.cmake
|
||||
PulseAudio.cmake
|
||||
Python.cmake
|
||||
QuickTimePlugin.cmake
|
||||
TemplateCheck.cmake
|
||||
Tut.cmake
|
||||
UI.cmake
|
||||
|
|
@ -102,7 +96,6 @@ set(cmake_SOURCE_FILES
|
|||
ViewerMiscLibs.cmake
|
||||
VisualLeakDetector.cmake
|
||||
LibVLCPlugin.cmake
|
||||
WinManifest.cmake
|
||||
XmlRpcEpi.cmake
|
||||
ZLIB.cmake
|
||||
)
|
||||
|
|
|
|||
|
|
@ -8,21 +8,12 @@ if (USESYSTEMLIBS)
|
|||
include(FindCURL)
|
||||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(curl)
|
||||
# if (DARWIN)
|
||||
# use_prebuilt_binary(libidn)
|
||||
# endif (DARWIN)
|
||||
if (WINDOWS)
|
||||
set(CURL_LIBRARIES
|
||||
debug libcurld.lib
|
||||
optimized libcurl.lib)
|
||||
else (WINDOWS)
|
||||
set(CURL_LIBRARIES libcurl.a)
|
||||
# if (DARWIN)
|
||||
# list(APPEND CURL_LIBRARIES
|
||||
# idn
|
||||
# iconv
|
||||
# )
|
||||
# endif (DARWIN)
|
||||
if (LINUX)
|
||||
list(APPEND CURL_LIBRARIES
|
||||
pthread
|
||||
|
|
|
|||
|
|
@ -6,17 +6,17 @@ SET(DEBUG_PKG_CONFIG "YES")
|
|||
IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
|
||||
|
||||
# Guess at architecture-specific system library paths.
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib)
|
||||
SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib)
|
||||
SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu)
|
||||
SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu)
|
||||
else (WORD_SIZE EQUAL 32)
|
||||
else (ADDRESS_SIZE EQUAL 32)
|
||||
SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib)
|
||||
SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib)
|
||||
SET(PKG_CONFIG_MULTI_GUESS /usr/lib/x86_64-linux-gnu)
|
||||
SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu)
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
# Use DPKG architecture, if available.
|
||||
IF (${DPKG_ARCH})
|
||||
|
|
|
|||
|
|
@ -27,18 +27,6 @@ if(WINDOWS)
|
|||
#*******************************
|
||||
# Misc shared libs
|
||||
|
||||
set(debug_src_dir "${ARCH_PREBUILT_DIRS_DEBUG}")
|
||||
set(debug_files
|
||||
#openjpegd.dll
|
||||
libapr-1.dll
|
||||
libaprutil-1.dll
|
||||
libapriconv-1.dll
|
||||
ssleay32.dll
|
||||
libeay32.dll
|
||||
#glod.dll
|
||||
libhunspell.dll
|
||||
)
|
||||
|
||||
set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
set(release_files
|
||||
#openjpeg.dll
|
||||
|
|
@ -47,120 +35,128 @@ if(WINDOWS)
|
|||
libapriconv-1.dll
|
||||
ssleay32.dll
|
||||
libeay32.dll
|
||||
nghttp2.dll
|
||||
glod.dll
|
||||
libhunspell.dll
|
||||
)
|
||||
|
||||
if( NOT ND_USE_OPENJPEG2 )
|
||||
set(debug_files ${debug_files} openjpegd.dll )
|
||||
set(release_files ${release_files} openjpeg.dll )
|
||||
else()
|
||||
set(debug_files ${debug_files} openjp2.dll )
|
||||
set(release_files ${release_files} openjp2.dll )
|
||||
endif( NOT ND_USE_OPENJPEG2 )
|
||||
|
||||
set(debug_files ${debug_files} growl++.dll growl.dll )
|
||||
set(release_files ${release_files} growl++.dll growl.dll )
|
||||
|
||||
if(USE_TCMALLOC)
|
||||
set(debug_files ${debug_files} libtcmalloc_minimal-debug.dll)
|
||||
set(release_files ${release_files} libtcmalloc_minimal.dll)
|
||||
endif(USE_TCMALLOC)
|
||||
|
||||
if (FMODSTUDIO)
|
||||
if( NOT ND_BUILD64BIT_ARCH )
|
||||
if(ADDRESS_SIZE EQUAL 32)
|
||||
set(debug_files ${debug_files} fmodL.dll)
|
||||
set(release_files ${release_files} fmod.dll)
|
||||
else( NOT ND_BUILD64BIT_ARCH )
|
||||
else(ADDRESS_SIZE EQUAL 32)
|
||||
set(debug_files ${debug_files} fmodL64.dll)
|
||||
set(release_files ${release_files} fmod64.dll)
|
||||
endif( NOT ND_BUILD64BIT_ARCH )
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (FMODSTUDIO)
|
||||
|
||||
if (FMODEX)
|
||||
if( NOT ND_BUILD64BIT_ARCH )
|
||||
set(debug_files ${debug_files} fmodexL.dll)
|
||||
set(release_files ${release_files} fmodex.dll)
|
||||
else( NOT ND_BUILD64BIT_ARCH )
|
||||
set(debug_files ${debug_files} fmodexL64.dll)
|
||||
set(release_files ${release_files} fmodex64.dll)
|
||||
endif( NOT ND_BUILD64BIT_ARCH )
|
||||
|
||||
if(ADDRESS_SIZE EQUAL 32)
|
||||
set(release_files ${release_files} fmodex.dll)
|
||||
else(ADDRESS_SIZE EQUAL 32)
|
||||
set(release_files ${release_files} fmodex64.dll)
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (FMODEX)
|
||||
|
||||
#*******************************
|
||||
# Copy MS C runtime dlls, required for packaging.
|
||||
# *TODO - Adapt this to support VC9
|
||||
if (MSVC80)
|
||||
set(MSVC_VER 80)
|
||||
set(MSVC_VERDOT 8.0)
|
||||
list(APPEND LMSVC_VER 80)
|
||||
list(APPEND LMSVC_VERDOT 8.0)
|
||||
elseif (MSVC_VERSION EQUAL 1600) # VisualStudio 2010
|
||||
set(MSVC_VER 100)
|
||||
set(MSVC_VERDOT 10.0)
|
||||
MESSAGE(STATUS "MSVC_VERSION ${MSVC_VERSION}")
|
||||
elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12
|
||||
set(MSVC_VER 120)
|
||||
set(MSVC_VERDOT 12.0)
|
||||
list(APPEND LMSVC_VER 120)
|
||||
list(APPEND LMSVC_VERDOT 12.0)
|
||||
else (MSVC80)
|
||||
MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake")
|
||||
endif (MSVC80)
|
||||
|
||||
FIND_PATH(debug_msvc_redist_path msvcr${MSVC_VER}d.dll
|
||||
PATHS
|
||||
${MSVC_DEBUG_REDIST_PATH}
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${MSVC_VERDOT}\\Setup\\VC;ProductDir]/redist/Debug_NonRedist/x86/Microsoft.VC${MSVC_VER}.DebugCRT
|
||||
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64
|
||||
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
if(EXISTS ${debug_msvc_redist_path})
|
||||
set(debug_msvc_files
|
||||
msvcr${MSVC_VER}d.dll
|
||||
msvcp${MSVC_VER}d.dll
|
||||
# try to copy VS2010 redist independently of system version
|
||||
# maint-7360 CP
|
||||
# list(APPEND LMSVC_VER 100)
|
||||
# list(APPEND LMSVC_VERDOT 10.0)
|
||||
|
||||
list(LENGTH LMSVC_VER count)
|
||||
math(EXPR count "${count}-1")
|
||||
foreach(i RANGE ${count})
|
||||
list(GET LMSVC_VER ${i} MSVC_VER)
|
||||
list(GET LMSVC_VERDOT ${i} MSVC_VERDOT)
|
||||
MESSAGE(STATUS "Copying redist libs for VC ${MSVC_VERDOT}")
|
||||
FIND_PATH(debug_msvc_redist_path NAME msvcr${MSVC_VER}d.dll
|
||||
PATHS
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${MSVC_VERDOT}\\Setup\\VC;ProductDir]/redist/Debug_NonRedist/x86/Microsoft.VC${MSVC_VER}.DebugCRT
|
||||
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64
|
||||
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32
|
||||
${MSVC_DEBUG_REDIST_PATH}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
copy_if_different(
|
||||
${debug_msvc_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_DEBUG}"
|
||||
out_targets
|
||||
${debug_msvc_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
if(EXISTS ${debug_msvc_redist_path})
|
||||
set(debug_msvc_files
|
||||
msvcr${MSVC_VER}d.dll
|
||||
msvcp${MSVC_VER}d.dll
|
||||
)
|
||||
|
||||
endif ()
|
||||
copy_if_different(
|
||||
${debug_msvc_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_DEBUG}"
|
||||
out_targets
|
||||
${debug_msvc_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
FIND_PATH(release_msvc_redist_path msvcr${MSVC_VER}.dll
|
||||
PATHS
|
||||
${MSVC_REDIST_PATH}
|
||||
[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${MSVC_VERDOT}\\Setup\\VC;ProductDir]/redist/x86/Microsoft.VC${MSVC_VER}.CRT
|
||||
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64
|
||||
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
unset(debug_msvc_redist_path CACHE)
|
||||
endif()
|
||||
|
||||
if(EXISTS ${release_msvc_redist_path})
|
||||
set(release_msvc_files
|
||||
msvcr${MSVC_VER}.dll
|
||||
msvcp${MSVC_VER}.dll
|
||||
if(ADDRESS_SIZE EQUAL 32)
|
||||
# this folder contains the 32bit DLLs.. (yes really!)
|
||||
set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64")
|
||||
else(ADDRESS_SIZE EQUAL 32)
|
||||
# this folder contains the 64bit DLLs.. (yes really!)
|
||||
set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32")
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
FIND_PATH(release_msvc_redist_path NAME msvcr${MSVC_VER}.dll
|
||||
PATHS
|
||||
${registry_find_path}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
copy_if_different(
|
||||
${release_msvc_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_RELEASE}"
|
||||
out_targets
|
||||
${release_msvc_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
if(EXISTS ${release_msvc_redist_path})
|
||||
set(release_msvc_files
|
||||
msvcr${MSVC_VER}.dll
|
||||
msvcp${MSVC_VER}.dll
|
||||
)
|
||||
|
||||
copy_if_different(
|
||||
${release_msvc_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}"
|
||||
out_targets
|
||||
${release_msvc_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
endif ()
|
||||
copy_if_different(
|
||||
${release_msvc_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_RELEASE}"
|
||||
out_targets
|
||||
${release_msvc_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
copy_if_different(
|
||||
${release_msvc_redist_path}
|
||||
"${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}"
|
||||
out_targets
|
||||
${release_msvc_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
unset(release_msvc_redist_path CACHE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
elseif(DARWIN)
|
||||
set(SHARED_LIB_STAGING_DIR_DEBUG "${SHARED_LIB_STAGING_DIR}/Debug/Resources")
|
||||
|
|
@ -184,11 +180,12 @@ elseif(DARWIN)
|
|||
libaprutil-1.0.dylib
|
||||
libaprutil-1.dylib
|
||||
libexception_handler.dylib
|
||||
libexpat.1.5.2.dylib
|
||||
libexpat.dylib
|
||||
${EXPAT_COPY}
|
||||
libGLOD.dylib
|
||||
libhunspell-1.3.0.dylib
|
||||
libndofdev.dylib
|
||||
libnghttp2.dylib
|
||||
libnghttp2.14.dylib
|
||||
libnghttp2.14.14.0.dylib
|
||||
libgrowl.dylib
|
||||
libgrowl++.dylib
|
||||
)
|
||||
|
|
@ -233,8 +230,7 @@ elseif(LINUX)
|
|||
#libaprutil-1.so.0
|
||||
libatk-1.0.so
|
||||
#libdb-5.1.so
|
||||
libexpat.so
|
||||
libexpat.so.1
|
||||
${EXPAT_COPY}
|
||||
#libfreetype.so.6.6.2
|
||||
#libfreetype.so.6
|
||||
libGLOD.so
|
||||
|
|
@ -248,23 +244,6 @@ elseif(LINUX)
|
|||
libfontconfig.so.1.8.0
|
||||
libfontconfig.so.1
|
||||
)
|
||||
if( NOT ND_BUILD64BIT_ARCH )
|
||||
set(release_files ${release_files}
|
||||
libapr-1.so.0
|
||||
libaprutil-1.so.0
|
||||
libdb-5.1.so
|
||||
libfreetype.so.6.6.2
|
||||
libfreetype.so.6
|
||||
)
|
||||
endif( NOT ND_BUILD64BIT_ARCH )
|
||||
if( NOT ND_USE_OPENJPEG2 )
|
||||
set(release_files ${release_files} libopenjpeg.so )
|
||||
endif( NOT ND_USE_OPENJPEG2 )
|
||||
|
||||
|
||||
if (USE_TCMALLOC)
|
||||
set(release_files ${release_files} "libtcmalloc_minimal.so")
|
||||
endif (USE_TCMALLOC)
|
||||
|
||||
if (FMODSTUDIO)
|
||||
set(debug_files ${debug_files} "libfmodL.so")
|
||||
|
|
@ -276,13 +255,13 @@ elseif(LINUX)
|
|||
# set(release_files ${release_files} "libfmodex.so")
|
||||
#endif (FMODEX)
|
||||
if (FMODEX)
|
||||
if( NOT ND_BUILD64BIT_ARCH )
|
||||
if(ADDRESS_SIZE EQUAL 32)
|
||||
set(debug_files ${debug_files} "libfmodexL.so")
|
||||
set(release_files ${release_files} "libfmodex.so")
|
||||
else( NOT ND_BUILD64BIT_ARCH )
|
||||
else(ADDRESS_SIZE EQUAL 32)
|
||||
set(debug_files ${debug_files} "libfmodexL64.so")
|
||||
set(release_files ${release_files} "libfmodex64.so")
|
||||
endif( NOT ND_BUILD64BIT_ARCH )
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (FMODEX)
|
||||
|
||||
else(WINDOWS)
|
||||
|
|
@ -336,13 +315,13 @@ set(third_party_targets ${third_party_targets} ${out_targets})
|
|||
|
||||
|
||||
|
||||
copy_if_different(
|
||||
${debug_src_dir}
|
||||
"${SHARED_LIB_STAGING_DIR_DEBUG}"
|
||||
out_targets
|
||||
${debug_files}
|
||||
)
|
||||
set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
#copy_if_different(
|
||||
# ${debug_src_dir}
|
||||
# "${SHARED_LIB_STAGING_DIR_DEBUG}"
|
||||
# out_targets
|
||||
# ${debug_files}
|
||||
# )
|
||||
#set(third_party_targets ${third_party_targets} ${out_targets})
|
||||
|
||||
copy_if_different(
|
||||
${release_src_dir}
|
||||
|
|
|
|||
|
|
@ -7,12 +7,9 @@
|
|||
# SEARCH_DIRS= The full paths to dirs to search for dependencies.
|
||||
# DST_PATH= The full path where the dependecies will be copied.
|
||||
|
||||
# *FIX:Mani - I pulled in the CMake 2.8 GetPrerequisites.cmake script here, because it works on windows where 2.6 did not.
|
||||
# Once we have officially upgraded to 2.8 we can just use that version of GetPrerequisites.cmake.
|
||||
get_filename_component(current_dir ${CMAKE_CURRENT_LIST_FILE} PATH)
|
||||
include(${current_dir}/GetPrerequisites_2_8.cmake)
|
||||
include(GetPrerequisites)
|
||||
|
||||
message("Getting recursive dependencies for file: ${BIN_NAME}")
|
||||
message(STATUS "Getting recursive dependencies for file: ${BIN_NAME}")
|
||||
|
||||
set(EXCLUDE_SYSTEM 1)
|
||||
set(RECURSE 1)
|
||||
|
|
@ -27,7 +24,7 @@ endif(WIN32)
|
|||
get_prerequisites( ${BIN_NAME} RESULTS ${EXCLUDE_SYSTEM} ${RECURSE} "${EXE_PATH}" "${SEARCH_DIRS}" )
|
||||
|
||||
foreach(DEP ${RESULTS})
|
||||
Message("Processing dependency: ${DEP}")
|
||||
Message(STATUS "Processing dependency: ${DEP}")
|
||||
get_filename_component(DEP_FILE ${DEP} NAME)
|
||||
set(DEP_FILES ${DEP_FILES} ${DEP_FILE})
|
||||
endforeach(DEP)
|
||||
|
|
@ -70,10 +67,10 @@ if(FOUND_FILES)
|
|||
foreach(FILE ${FOUND_FILES})
|
||||
get_filename_component(DST_FILE ${FILE} NAME)
|
||||
set(DST_FILE "${DST_PATH}/${DST_FILE}")
|
||||
message("Copying ${FILE} to ${DST_FILE}")
|
||||
message(STATUS "Copying ${FILE} to ${DST_FILE}")
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FILE} ${DST_FILE}
|
||||
)
|
||||
endforeach(FILE ${FOUND_FILES})
|
||||
endif(FOUND_FILES)
|
||||
message("Success!")
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@
|
|||
add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
|
||||
endif (DARWIN)
|
||||
|
||||
if (LINUX)
|
||||
add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
|
||||
endif (LINUX)
|
||||
#if (LINUX)
|
||||
# add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
|
||||
#endif (LINUX)
|
||||
|
||||
endif (OS_DRAG_DROP)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,8 +10,14 @@ else (USESYSTEMLIBS)
|
|||
use_prebuilt_binary(expat)
|
||||
if (WINDOWS)
|
||||
set(EXPAT_LIBRARIES libexpatMT)
|
||||
set(EXPAT_COPY libexpatMT.dll)
|
||||
else (WINDOWS)
|
||||
set(EXPAT_LIBRARIES expat)
|
||||
if (DARWIN)
|
||||
set(EXPAT_COPY libexpat.1.dylib libexpat.dylib)
|
||||
else ()
|
||||
set(EXPAT_COPY libexpat.so.1 libexpat.so)
|
||||
endif ()
|
||||
endif (WINDOWS)
|
||||
set(EXPAT_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
|
|
|||
|
|
@ -30,29 +30,29 @@ if (FMODEX)
|
|||
include(Prebuilt)
|
||||
use_prebuilt_binary(fmodex)
|
||||
if (WINDOWS)
|
||||
if( NOT ND_BUILD64BIT_ARCH )
|
||||
if( ADDRESS_SIZE EQUAL 32 )
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL_vc
|
||||
optimized fmodex_vc)
|
||||
else( NOT ND_BUILD64BIT_ARCH )
|
||||
else( )
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL64_vc
|
||||
optimized fmodex64_vc)
|
||||
endif( NOT ND_BUILD64BIT_ARCH )
|
||||
endif( )
|
||||
elseif (DARWIN)
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL
|
||||
optimized fmodex)
|
||||
elseif (LINUX)
|
||||
if(ND_BUILD64BIT_ARCH)
|
||||
if( ADDRESS_SIZE EQUAL 64 )
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL64
|
||||
optimized fmodex64)
|
||||
else(ND_BUILD64BIT_ARCH)
|
||||
else( )
|
||||
set(FMODEX_LIBRARY
|
||||
debug fmodexL
|
||||
optimized fmodex)
|
||||
endif(ND_BUILD64BIT_ARCH)
|
||||
endif( )
|
||||
endif (WINDOWS)
|
||||
set(FMODEX_LIBRARIES ${FMODEX_LIBRARY})
|
||||
set(FMODEX_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodex)
|
||||
|
|
|
|||
|
|
@ -27,23 +27,29 @@ if (FMODSTUDIO)
|
|||
include(Prebuilt)
|
||||
use_prebuilt_binary(fmodstudio)
|
||||
if (WINDOWS)
|
||||
if (NOT ND_BUILD64BIT_ARCH)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
debug fmodL_vc
|
||||
optimized fmod_vc)
|
||||
elseif (ND_BUILD64BIT_ARCH)
|
||||
elseif (ADDRESS_SIZE EQUAL 64)
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
debug fmodL64_vc
|
||||
optimized fmod64_vc)
|
||||
endif(NOT ND_BUILD64BIT_ARCH)
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
elseif (DARWIN)
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
debug fmodL
|
||||
optimized fmod)
|
||||
elseif (LINUX)
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
debug fmodL
|
||||
optimized fmod)
|
||||
elseif (ADDRESS_SIZE EQUAL 64)
|
||||
set(FMODSTUDIO_LIBRARY
|
||||
debug fmodL64
|
||||
optimized fmod64)
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (WINDOWS)
|
||||
set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY})
|
||||
set(FMODSTUDIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ find_path(HUNSPELL_INCLUDE_DIR hunspell.h
|
|||
PATH_SUFFIXES hunspell
|
||||
)
|
||||
|
||||
set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3.0 libhunspell hunspell)
|
||||
set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3 libhunspell)
|
||||
find_library(HUNSPELL_LIBRARY
|
||||
NAMES ${HUNSPELL_NAMES}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@ if (NOT USESYSTEMLIBS)
|
|||
if (WINDOWS OR LINUX)
|
||||
use_prebuilt_binary(glext)
|
||||
endif (WINDOWS OR LINUX)
|
||||
use_prebuilt_binary(glh-linear)
|
||||
use_prebuilt_binary(glh_linear)
|
||||
set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
|
||||
endif (NOT USESYSTEMLIBS)
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ set(GLH_FIND_QUIETLY TRUE)
|
|||
if (USESYSTEMLIBS)
|
||||
include(FindGLH)
|
||||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(glh-linear)
|
||||
use_prebuilt_binary(glh_linear)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
|
|
|||
|
|
@ -1,786 +0,0 @@
|
|||
# GetPrerequisites.cmake
|
||||
#
|
||||
# This script provides functions to list the .dll, .dylib or .so files that an
|
||||
# executable or shared library file depends on. (Its prerequisites.)
|
||||
#
|
||||
# It uses various tools to obtain the list of required shared library files:
|
||||
# dumpbin (Windows)
|
||||
# ldd (Linux/Unix)
|
||||
# otool (Mac OSX)
|
||||
#
|
||||
# The following functions are provided by this script:
|
||||
# gp_append_unique
|
||||
# is_file_executable
|
||||
# gp_item_default_embedded_path
|
||||
# (projects can override with gp_item_default_embedded_path_override)
|
||||
# gp_resolve_item
|
||||
# (projects can override with gp_resolve_item_override)
|
||||
# gp_resolved_file_type
|
||||
# gp_file_type
|
||||
# get_prerequisites
|
||||
# list_prerequisites
|
||||
# list_prerequisites_by_glob
|
||||
#
|
||||
# Requires CMake 2.6 or greater because it uses function, break, return and
|
||||
# PARENT_SCOPE.
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2008-2009 Kitware, Inc.
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distributed this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
# gp_append_unique list_var value
|
||||
#
|
||||
# Append value to the list variable ${list_var} only if the value is not
|
||||
# already in the list.
|
||||
#
|
||||
function(gp_append_unique list_var value)
|
||||
set(contains 0)
|
||||
|
||||
foreach(item ${${list_var}})
|
||||
if("${item}" STREQUAL "${value}")
|
||||
set(contains 1)
|
||||
break()
|
||||
endif("${item}" STREQUAL "${value}")
|
||||
endforeach(item)
|
||||
|
||||
if(NOT contains)
|
||||
set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
|
||||
endif(NOT contains)
|
||||
endfunction(gp_append_unique)
|
||||
|
||||
|
||||
# is_file_executable file result_var
|
||||
#
|
||||
# Return 1 in ${result_var} if ${file} is a binary executable.
|
||||
#
|
||||
# Return 0 in ${result_var} otherwise.
|
||||
#
|
||||
function(is_file_executable file result_var)
|
||||
#
|
||||
# A file is not executable until proven otherwise:
|
||||
#
|
||||
set(${result_var} 0 PARENT_SCOPE)
|
||||
|
||||
get_filename_component(file_full "${file}" ABSOLUTE)
|
||||
string(TOLOWER "${file_full}" file_full_lower)
|
||||
|
||||
# If file name ends in .exe on Windows, *assume* executable:
|
||||
#
|
||||
if(WIN32)
|
||||
if("${file_full_lower}" MATCHES "\\.exe$")
|
||||
set(${result_var} 1 PARENT_SCOPE)
|
||||
return()
|
||||
endif("${file_full_lower}" MATCHES "\\.exe$")
|
||||
|
||||
# A clause could be added here that uses output or return value of dumpbin
|
||||
# to determine ${result_var}. In 99%+? practical cases, the exe name
|
||||
# match will be sufficient...
|
||||
#
|
||||
endif(WIN32)
|
||||
|
||||
# Use the information returned from the Unix shell command "file" to
|
||||
# determine if ${file_full} should be considered an executable file...
|
||||
#
|
||||
# If the file command's output contains "executable" and does *not* contain
|
||||
# "text" then it is likely an executable suitable for prerequisite analysis
|
||||
# via the get_prerequisites macro.
|
||||
#
|
||||
if(UNIX)
|
||||
if(NOT file_cmd)
|
||||
find_program(file_cmd "file")
|
||||
endif(NOT file_cmd)
|
||||
|
||||
if(file_cmd)
|
||||
execute_process(COMMAND "${file_cmd}" "${file_full}"
|
||||
OUTPUT_VARIABLE file_ov
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Replace the name of the file in the output with a placeholder token
|
||||
# (the string " _file_full_ ") so that just in case the path name of
|
||||
# the file contains the word "text" or "executable" we are not fooled
|
||||
# into thinking "the wrong thing" because the file name matches the
|
||||
# other 'file' command output we are looking for...
|
||||
#
|
||||
string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
|
||||
string(TOLOWER "${file_ov}" file_ov)
|
||||
|
||||
#message(STATUS "file_ov='${file_ov}'")
|
||||
if("${file_ov}" MATCHES "executable")
|
||||
#message(STATUS "executable!")
|
||||
if("${file_ov}" MATCHES "text")
|
||||
#message(STATUS "but text, so *not* a binary executable!")
|
||||
else("${file_ov}" MATCHES "text")
|
||||
set(${result_var} 1 PARENT_SCOPE)
|
||||
return()
|
||||
endif("${file_ov}" MATCHES "text")
|
||||
endif("${file_ov}" MATCHES "executable")
|
||||
else(file_cmd)
|
||||
message(STATUS "warning: No 'file' command, skipping execute_process...")
|
||||
endif(file_cmd)
|
||||
endif(UNIX)
|
||||
endfunction(is_file_executable)
|
||||
|
||||
|
||||
# gp_item_default_embedded_path item default_embedded_path_var
|
||||
#
|
||||
# Return the path that others should refer to the item by when the item
|
||||
# is embedded inside a bundle.
|
||||
#
|
||||
# Override on a per-project basis by providing a project-specific
|
||||
# gp_item_default_embedded_path_override function.
|
||||
#
|
||||
function(gp_item_default_embedded_path item default_embedded_path_var)
|
||||
|
||||
# On Windows and Linux, "embed" prerequisites in the same directory
|
||||
# as the executable by default:
|
||||
#
|
||||
set(path "@executable_path")
|
||||
set(overridden 0)
|
||||
|
||||
# On the Mac, relative to the executable depending on the type
|
||||
# of the thing we are embedding:
|
||||
#
|
||||
if(APPLE)
|
||||
#
|
||||
# The assumption here is that all executables in the bundle will be
|
||||
# in same-level-directories inside the bundle. The parent directory
|
||||
# of an executable inside the bundle should be MacOS or a sibling of
|
||||
# MacOS and all embedded paths returned from here will begin with
|
||||
# "@executable_path/../" and will work from all executables in all
|
||||
# such same-level-directories inside the bundle.
|
||||
#
|
||||
|
||||
# By default, embed things right next to the main bundle executable:
|
||||
#
|
||||
set(path "@executable_path/../../Contents/MacOS")
|
||||
|
||||
# Embed .dylibs right next to the main bundle executable:
|
||||
#
|
||||
if(item MATCHES "\\.dylib$")
|
||||
set(path "@executable_path/../MacOS")
|
||||
set(overridden 1)
|
||||
endif(item MATCHES "\\.dylib$")
|
||||
|
||||
# Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
|
||||
#
|
||||
if(NOT overridden)
|
||||
if(item MATCHES "[^/]+\\.framework/")
|
||||
set(path "@executable_path/../Frameworks")
|
||||
set(overridden 1)
|
||||
endif(item MATCHES "[^/]+\\.framework/")
|
||||
endif(NOT overridden)
|
||||
endif()
|
||||
|
||||
# Provide a hook so that projects can override the default embedded location
|
||||
# of any given library by whatever logic they choose:
|
||||
#
|
||||
if(COMMAND gp_item_default_embedded_path_override)
|
||||
gp_item_default_embedded_path_override("${item}" path)
|
||||
endif(COMMAND gp_item_default_embedded_path_override)
|
||||
|
||||
set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
|
||||
endfunction(gp_item_default_embedded_path)
|
||||
|
||||
|
||||
# gp_resolve_item context item exepath dirs resolved_item_var
|
||||
#
|
||||
# Resolve an item into an existing full path file.
|
||||
#
|
||||
# Override on a per-project basis by providing a project-specific
|
||||
# gp_resolve_item_override function.
|
||||
#
|
||||
function(gp_resolve_item context item exepath dirs resolved_item_var)
|
||||
set(resolved 0)
|
||||
set(resolved_item "${item}")
|
||||
|
||||
# Is it already resolved?
|
||||
#
|
||||
if(EXISTS "${resolved_item}")
|
||||
set(resolved 1)
|
||||
endif(EXISTS "${resolved_item}")
|
||||
|
||||
if(NOT resolved)
|
||||
if(item MATCHES "@executable_path")
|
||||
#
|
||||
# @executable_path references are assumed relative to exepath
|
||||
#
|
||||
string(REPLACE "@executable_path" "${exepath}" ri "${item}")
|
||||
get_filename_component(ri "${ri}" ABSOLUTE)
|
||||
|
||||
if(EXISTS "${ri}")
|
||||
#message(STATUS "info: embedded item exists (${ri})")
|
||||
set(resolved 1)
|
||||
set(resolved_item "${ri}")
|
||||
else(EXISTS "${ri}")
|
||||
message(STATUS "warning: embedded item does not exist '${ri}'")
|
||||
endif(EXISTS "${ri}")
|
||||
endif(item MATCHES "@executable_path")
|
||||
endif(NOT resolved)
|
||||
|
||||
if(NOT resolved)
|
||||
if(item MATCHES "@loader_path")
|
||||
#
|
||||
# @loader_path references are assumed relative to the
|
||||
# PATH of the given "context" (presumably another library)
|
||||
#
|
||||
get_filename_component(contextpath "${context}" PATH)
|
||||
string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
|
||||
get_filename_component(ri "${ri}" ABSOLUTE)
|
||||
|
||||
if(EXISTS "${ri}")
|
||||
#message(STATUS "info: embedded item exists (${ri})")
|
||||
set(resolved 1)
|
||||
set(resolved_item "${ri}")
|
||||
else(EXISTS "${ri}")
|
||||
message(STATUS "warning: embedded item does not exist '${ri}'")
|
||||
endif(EXISTS "${ri}")
|
||||
endif(item MATCHES "@loader_path")
|
||||
endif(NOT resolved)
|
||||
|
||||
if(NOT resolved)
|
||||
set(ri "ri-NOTFOUND")
|
||||
find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
|
||||
find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
|
||||
if(ri)
|
||||
#message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
|
||||
set(resolved 1)
|
||||
set(resolved_item "${ri}")
|
||||
set(ri "ri-NOTFOUND")
|
||||
endif(ri)
|
||||
endif(NOT resolved)
|
||||
|
||||
if(NOT resolved)
|
||||
if(item MATCHES "[^/]+\\.framework/")
|
||||
set(fw "fw-NOTFOUND")
|
||||
find_file(fw "${item}"
|
||||
"~/Library/Frameworks"
|
||||
"/Library/Frameworks"
|
||||
"/System/Library/Frameworks"
|
||||
)
|
||||
if(fw)
|
||||
#message(STATUS "info: 'find_file' found framework (${fw})")
|
||||
set(resolved 1)
|
||||
set(resolved_item "${fw}")
|
||||
set(fw "fw-NOTFOUND")
|
||||
endif(fw)
|
||||
endif(item MATCHES "[^/]+\\.framework/")
|
||||
endif(NOT resolved)
|
||||
|
||||
# Using find_program on Windows will find dll files that are in the PATH.
|
||||
# (Converting simple file names into full path names if found.)
|
||||
#
|
||||
if(WIN32)
|
||||
if(NOT resolved)
|
||||
set(ri "ri-NOTFOUND")
|
||||
find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
|
||||
find_program(ri "${item}" PATHS "${exepath};${dirs}")
|
||||
if(ri)
|
||||
#message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
|
||||
set(resolved 1)
|
||||
set(resolved_item "${ri}")
|
||||
set(ri "ri-NOTFOUND")
|
||||
endif(ri)
|
||||
endif(NOT resolved)
|
||||
endif(WIN32)
|
||||
|
||||
# Provide a hook so that projects can override item resolution
|
||||
# by whatever logic they choose:
|
||||
#
|
||||
if(COMMAND gp_resolve_item_override)
|
||||
gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
|
||||
endif(COMMAND gp_resolve_item_override)
|
||||
|
||||
if(NOT resolved)
|
||||
message(STATUS "
|
||||
warning: cannot resolve item '${item}'
|
||||
|
||||
possible problems:
|
||||
need more directories?
|
||||
need to use InstallRequiredSystemLibraries?
|
||||
run in install tree instead of build tree?
|
||||
")
|
||||
# message(STATUS "
|
||||
#******************************************************************************
|
||||
#warning: cannot resolve item '${item}'
|
||||
#
|
||||
# possible problems:
|
||||
# need more directories?
|
||||
# need to use InstallRequiredSystemLibraries?
|
||||
# run in install tree instead of build tree?
|
||||
#
|
||||
# context='${context}'
|
||||
# item='${item}'
|
||||
# exepath='${exepath}'
|
||||
# dirs='${dirs}'
|
||||
# resolved_item_var='${resolved_item_var}'
|
||||
#******************************************************************************
|
||||
#")
|
||||
endif(NOT resolved)
|
||||
|
||||
set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
|
||||
endfunction(gp_resolve_item)
|
||||
|
||||
|
||||
# gp_resolved_file_type original_file file exepath dirs type_var
|
||||
#
|
||||
# Return the type of ${file} with respect to ${original_file}. String
|
||||
# describing type of prerequisite is returned in variable named ${type_var}.
|
||||
#
|
||||
# Use ${exepath} and ${dirs} if necessary to resolve non-absolute ${file}
|
||||
# values -- but only for non-embedded items.
|
||||
#
|
||||
# Possible types are:
|
||||
# system
|
||||
# local
|
||||
# embedded
|
||||
# other
|
||||
#
|
||||
function(gp_resolved_file_type original_file file exepath dirs type_var)
|
||||
#message(STATUS "**")
|
||||
|
||||
if(NOT IS_ABSOLUTE "${original_file}")
|
||||
message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
|
||||
endif()
|
||||
|
||||
set(is_embedded 0)
|
||||
set(is_local 0)
|
||||
set(is_system 0)
|
||||
|
||||
set(resolved_file "${file}")
|
||||
|
||||
if("${file}" MATCHES "^@(executable|loader)_path")
|
||||
set(is_embedded 1)
|
||||
endif()
|
||||
|
||||
if(NOT is_embedded)
|
||||
if(NOT IS_ABSOLUTE "${file}")
|
||||
gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
|
||||
endif()
|
||||
|
||||
string(TOLOWER "${original_file}" original_lower)
|
||||
string(TOLOWER "${resolved_file}" lower)
|
||||
|
||||
if(UNIX)
|
||||
if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/)")
|
||||
set(is_system 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
|
||||
set(is_system 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
string(TOLOWER "$ENV{SystemRoot}" sysroot)
|
||||
string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
|
||||
|
||||
string(TOLOWER "$ENV{windir}" windir)
|
||||
string(REGEX REPLACE "\\\\" "/" windir "${windir}")
|
||||
|
||||
if(lower MATCHES "^(${sysroot}/system|${windir}/system|${sysroot}/syswow|${windir}/syswow|(.*/)*msvc[^/]+dll)")
|
||||
set(is_system 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT is_system)
|
||||
get_filename_component(original_path "${original_lower}" PATH)
|
||||
get_filename_component(path "${lower}" PATH)
|
||||
if("${original_path}" STREQUAL "${path}")
|
||||
set(is_local 1)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Return type string based on computed booleans:
|
||||
#
|
||||
set(type "other")
|
||||
|
||||
if(is_system)
|
||||
set(type "system")
|
||||
elseif(is_embedded)
|
||||
set(type "embedded")
|
||||
elseif(is_local)
|
||||
set(type "local")
|
||||
endif()
|
||||
|
||||
#message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
|
||||
#message(STATUS " type: '${type}'")
|
||||
|
||||
if(NOT is_embedded)
|
||||
if(NOT IS_ABSOLUTE "${resolved_file}")
|
||||
if(lower MATCHES "^msvc[^/]+dll" AND is_system)
|
||||
message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
|
||||
else()
|
||||
message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(${type_var} "${type}" PARENT_SCOPE)
|
||||
|
||||
#message(STATUS "**")
|
||||
endfunction()
|
||||
|
||||
|
||||
# gp_file_type original_file file type_var
|
||||
#
|
||||
# Return the type of ${file} with respect to ${original_file}. String
|
||||
# describing type of prerequisite is returned in variable named ${type_var}.
|
||||
#
|
||||
# Possible types are:
|
||||
# system
|
||||
# local
|
||||
# embedded
|
||||
# other
|
||||
#
|
||||
function(gp_file_type original_file file type_var)
|
||||
if(NOT IS_ABSOLUTE "${original_file}")
|
||||
message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
|
||||
endif()
|
||||
|
||||
get_filename_component(exepath "${original_file}" PATH)
|
||||
|
||||
set(type "")
|
||||
gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
|
||||
|
||||
set(${type_var} "${type}" PARENT_SCOPE)
|
||||
endfunction(gp_file_type)
|
||||
|
||||
|
||||
# get_prerequisites target prerequisites_var exclude_system recurse dirs
|
||||
#
|
||||
# Get the list of shared library files required by ${target}. The list in
|
||||
# the variable named ${prerequisites_var} should be empty on first entry to
|
||||
# this function. On exit, ${prerequisites_var} will contain the list of
|
||||
# required shared library files.
|
||||
#
|
||||
# target is the full path to an executable file
|
||||
#
|
||||
# prerequisites_var is the name of a CMake variable to contain the results
|
||||
#
|
||||
# exclude_system is 0 or 1: 0 to include "system" prerequisites , 1 to
|
||||
# exclude them
|
||||
#
|
||||
# recurse is 0 or 1: 0 for direct prerequisites only, 1 for all prerequisites
|
||||
# recursively
|
||||
#
|
||||
# exepath is the path to the top level executable used for @executable_path
|
||||
# replacment on the Mac
|
||||
#
|
||||
# dirs is a list of paths where libraries might be found: these paths are
|
||||
# searched first when a target without any path info is given. Then standard
|
||||
# system locations are also searched: PATH, Framework locations, /usr/lib...
|
||||
#
|
||||
function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
|
||||
set(verbose 0)
|
||||
set(eol_char "E")
|
||||
|
||||
if(NOT IS_ABSOLUTE "${target}")
|
||||
message("warning: target '${target}' is not absolute...")
|
||||
endif(NOT IS_ABSOLUTE "${target}")
|
||||
|
||||
if(NOT EXISTS "${target}")
|
||||
message("warning: target '${target}' does not exist...")
|
||||
endif(NOT EXISTS "${target}")
|
||||
|
||||
# <setup-gp_tool-vars>
|
||||
#
|
||||
# Try to choose the right tool by default. Caller can set gp_tool prior to
|
||||
# calling this function to force using a different tool.
|
||||
#
|
||||
if("${gp_tool}" STREQUAL "")
|
||||
set(gp_tool "ldd")
|
||||
if(APPLE)
|
||||
set(gp_tool "otool")
|
||||
endif(APPLE)
|
||||
if(WIN32)
|
||||
set(gp_tool "dumpbin")
|
||||
endif(WIN32)
|
||||
endif("${gp_tool}" STREQUAL "")
|
||||
|
||||
set(gp_tool_known 0)
|
||||
|
||||
if("${gp_tool}" STREQUAL "ldd")
|
||||
set(gp_cmd_args "")
|
||||
set(gp_regex "^[\t ]*[^\t ]+ => ([^\t ]+).*${eol_char}$")
|
||||
set(gp_regex_cmp_count 1)
|
||||
set(gp_tool_known 1)
|
||||
endif("${gp_tool}" STREQUAL "ldd")
|
||||
|
||||
if("${gp_tool}" STREQUAL "otool")
|
||||
set(gp_cmd_args "-L")
|
||||
set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
|
||||
set(gp_regex_cmp_count 3)
|
||||
set(gp_tool_known 1)
|
||||
endif("${gp_tool}" STREQUAL "otool")
|
||||
|
||||
if("${gp_tool}" STREQUAL "dumpbin")
|
||||
set(gp_cmd_args "/dependents")
|
||||
set(gp_regex "^ ([^ ].*[Dd][Ll][Ll])${eol_char}$")
|
||||
set(gp_regex_cmp_count 1)
|
||||
set(gp_tool_known 1)
|
||||
set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
|
||||
endif("${gp_tool}" STREQUAL "dumpbin")
|
||||
|
||||
if(NOT gp_tool_known)
|
||||
message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
|
||||
message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
|
||||
message(STATUS "Valid gp_tool values are dumpbin, ldd and otool.")
|
||||
return()
|
||||
endif(NOT gp_tool_known)
|
||||
|
||||
set(gp_cmd_paths ${gp_cmd_paths}
|
||||
"C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
|
||||
"C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
|
||||
"C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
|
||||
"C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
|
||||
"/usr/local/bin"
|
||||
"/usr/bin"
|
||||
)
|
||||
|
||||
find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
|
||||
|
||||
if(NOT gp_cmd)
|
||||
message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
|
||||
return()
|
||||
endif(NOT gp_cmd)
|
||||
|
||||
if("${gp_tool}" STREQUAL "dumpbin")
|
||||
# When running dumpbin, it also needs the "Common7/IDE" directory in the
|
||||
# PATH. It will already be in the PATH if being run from a Visual Studio
|
||||
# command prompt. Add it to the PATH here in case we are running from a
|
||||
# different command prompt.
|
||||
#
|
||||
get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
|
||||
get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
|
||||
if(EXISTS "${gp_cmd_dlls_dir}")
|
||||
# only add to the path if it is not already in the path
|
||||
if(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
|
||||
set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
|
||||
endif(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
|
||||
endif(EXISTS "${gp_cmd_dlls_dir}")
|
||||
endif("${gp_tool}" STREQUAL "dumpbin")
|
||||
#
|
||||
# </setup-gp_tool-vars>
|
||||
|
||||
if("${gp_tool}" STREQUAL "ldd")
|
||||
set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
|
||||
foreach(dir ${exepath} ${dirs})
|
||||
set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}")
|
||||
endforeach(dir)
|
||||
endif("${gp_tool}" STREQUAL "ldd")
|
||||
|
||||
|
||||
# Track new prerequisites at each new level of recursion. Start with an
|
||||
# empty list at each level:
|
||||
#
|
||||
set(unseen_prereqs)
|
||||
|
||||
# Run gp_cmd on the target:
|
||||
#
|
||||
execute_process(
|
||||
COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
|
||||
OUTPUT_VARIABLE gp_cmd_ov
|
||||
)
|
||||
|
||||
if("${gp_tool}" STREQUAL "ldd")
|
||||
set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
|
||||
endif("${gp_tool}" STREQUAL "ldd")
|
||||
|
||||
if(verbose)
|
||||
message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
|
||||
message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
|
||||
message(STATUS "</RawOutput>")
|
||||
endif(verbose)
|
||||
|
||||
get_filename_component(target_dir "${target}" PATH)
|
||||
|
||||
# Convert to a list of lines:
|
||||
#
|
||||
string(REGEX REPLACE ";" "\\\\;" candidates "${gp_cmd_ov}")
|
||||
string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
|
||||
|
||||
# Analyze each line for file names that match the regular expression:
|
||||
#
|
||||
foreach(candidate ${candidates})
|
||||
if("${candidate}" MATCHES "${gp_regex}")
|
||||
# Extract information from each candidate:
|
||||
string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}")
|
||||
|
||||
if(gp_regex_cmp_count GREATER 1)
|
||||
string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}")
|
||||
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}")
|
||||
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}")
|
||||
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}")
|
||||
endif(gp_regex_cmp_count GREATER 1)
|
||||
|
||||
if(gp_regex_cmp_count GREATER 2)
|
||||
string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}")
|
||||
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}")
|
||||
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}")
|
||||
string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}")
|
||||
endif(gp_regex_cmp_count GREATER 2)
|
||||
|
||||
# Use the raw_item as the list entries returned by this function. Use the
|
||||
# gp_resolve_item function to resolve it to an actual full path file if
|
||||
# necessary.
|
||||
#
|
||||
set(item "${raw_item}")
|
||||
|
||||
# Add each item unless it is excluded:
|
||||
#
|
||||
set(add_item 1)
|
||||
|
||||
if(${exclude_system})
|
||||
set(type "")
|
||||
gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
|
||||
if("${type}" STREQUAL "system")
|
||||
set(add_item 0)
|
||||
endif("${type}" STREQUAL "system")
|
||||
endif(${exclude_system})
|
||||
|
||||
if(add_item)
|
||||
list(LENGTH ${prerequisites_var} list_length_before_append)
|
||||
gp_append_unique(${prerequisites_var} "${item}")
|
||||
list(LENGTH ${prerequisites_var} list_length_after_append)
|
||||
|
||||
if(${recurse})
|
||||
# If item was really added, this is the first time we have seen it.
|
||||
# Add it to unseen_prereqs so that we can recursively add *its*
|
||||
# prerequisites...
|
||||
#
|
||||
# But first: resolve its name to an absolute full path name such
|
||||
# that the analysis tools can simply accept it as input.
|
||||
#
|
||||
if(NOT list_length_before_append EQUAL list_length_after_append)
|
||||
gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item)
|
||||
set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
|
||||
endif(NOT list_length_before_append EQUAL list_length_after_append)
|
||||
endif(${recurse})
|
||||
endif(add_item)
|
||||
else("${candidate}" MATCHES "${gp_regex}")
|
||||
if(verbose)
|
||||
message(STATUS "ignoring non-matching line: '${candidate}'")
|
||||
endif(verbose)
|
||||
endif("${candidate}" MATCHES "${gp_regex}")
|
||||
endforeach(candidate)
|
||||
|
||||
list(LENGTH ${prerequisites_var} prerequisites_var_length)
|
||||
if(prerequisites_var_length GREATER 0)
|
||||
list(SORT ${prerequisites_var})
|
||||
endif(prerequisites_var_length GREATER 0)
|
||||
if(${recurse})
|
||||
set(more_inputs ${unseen_prereqs})
|
||||
foreach(input ${more_inputs})
|
||||
get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
|
||||
endforeach(input)
|
||||
endif(${recurse})
|
||||
|
||||
set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
|
||||
endfunction(get_prerequisites)
|
||||
|
||||
|
||||
# list_prerequisites target all exclude_system verbose
|
||||
#
|
||||
# ARGV0 (target) is the full path to an executable file
|
||||
#
|
||||
# optional ARGV1 (all) is 0 or 1: 0 for direct prerequisites only,
|
||||
# 1 for all prerequisites recursively
|
||||
#
|
||||
# optional ARGV2 (exclude_system) is 0 or 1: 0 to include "system"
|
||||
# prerequisites , 1 to exclude them
|
||||
#
|
||||
# optional ARGV3 (verbose) is 0 or 1: 0 to print only full path
|
||||
# names of prerequisites, 1 to print extra information
|
||||
#
|
||||
function(list_prerequisites target)
|
||||
if("${ARGV1}" STREQUAL "")
|
||||
set(all 1)
|
||||
else("${ARGV1}" STREQUAL "")
|
||||
set(all "${ARGV1}")
|
||||
endif("${ARGV1}" STREQUAL "")
|
||||
|
||||
if("${ARGV2}" STREQUAL "")
|
||||
set(exclude_system 0)
|
||||
else("${ARGV2}" STREQUAL "")
|
||||
set(exclude_system "${ARGV2}")
|
||||
endif("${ARGV2}" STREQUAL "")
|
||||
|
||||
if("${ARGV3}" STREQUAL "")
|
||||
set(verbose 0)
|
||||
else("${ARGV3}" STREQUAL "")
|
||||
set(verbose "${ARGV3}")
|
||||
endif("${ARGV3}" STREQUAL "")
|
||||
|
||||
set(count 0)
|
||||
set(count_str "")
|
||||
set(print_count "${verbose}")
|
||||
set(print_prerequisite_type "${verbose}")
|
||||
set(print_target "${verbose}")
|
||||
set(type_str "")
|
||||
|
||||
get_filename_component(exepath "${target}" PATH)
|
||||
|
||||
set(prereqs "")
|
||||
get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")
|
||||
|
||||
if(print_target)
|
||||
message(STATUS "File '${target}' depends on:")
|
||||
endif(print_target)
|
||||
|
||||
foreach(d ${prereqs})
|
||||
math(EXPR count "${count} + 1")
|
||||
|
||||
if(print_count)
|
||||
set(count_str "${count}. ")
|
||||
endif(print_count)
|
||||
|
||||
if(print_prerequisite_type)
|
||||
gp_file_type("${target}" "${d}" type)
|
||||
set(type_str " (${type})")
|
||||
endif(print_prerequisite_type)
|
||||
|
||||
message(STATUS "${count_str}${d}${type_str}")
|
||||
endforeach(d)
|
||||
endfunction(list_prerequisites)
|
||||
|
||||
|
||||
# list_prerequisites_by_glob glob_arg glob_exp
|
||||
#
|
||||
# glob_arg is GLOB or GLOB_RECURSE
|
||||
#
|
||||
# glob_exp is a globbing expression used with "file(GLOB" to retrieve a list
|
||||
# of matching files. If a matching file is executable, its prerequisites are
|
||||
# listed.
|
||||
#
|
||||
# Any additional (optional) arguments provided are passed along as the
|
||||
# optional arguments to the list_prerequisites calls.
|
||||
#
|
||||
function(list_prerequisites_by_glob glob_arg glob_exp)
|
||||
message(STATUS "=============================================================================")
|
||||
message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
|
||||
message(STATUS "")
|
||||
file(${glob_arg} file_list ${glob_exp})
|
||||
foreach(f ${file_list})
|
||||
is_file_executable("${f}" is_f_executable)
|
||||
if(is_f_executable)
|
||||
message(STATUS "=============================================================================")
|
||||
list_prerequisites("${f}" ${ARGN})
|
||||
message(STATUS "")
|
||||
endif(is_f_executable)
|
||||
endforeach(f)
|
||||
endfunction(list_prerequisites_by_glob)
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
include(Linking)
|
||||
include(Prebuilt)
|
||||
|
||||
if (USESYSTEMLIBS)
|
||||
set(GLUI OFF CACHE BOOL
|
||||
"GLUI support for the llplugin/llmedia test apps.")
|
||||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(glui)
|
||||
set(GLUI ON CACHE BOOL
|
||||
"GLUI support for the llplugin/llmedia test apps.")
|
||||
endif (USESYSTEMLIBS)
|
||||
|
||||
if (LINUX)
|
||||
set(GLUI ON CACHE BOOL
|
||||
"llplugin media apps HACK for Linux.")
|
||||
endif (LINUX)
|
||||
|
||||
if (DARWIN OR LINUX)
|
||||
set(GLUI_LIBRARY
|
||||
glui)
|
||||
endif (DARWIN OR LINUX)
|
||||
|
||||
if (WINDOWS)
|
||||
set(GLUI_LIBRARY
|
||||
debug glui32.lib
|
||||
optimized glui32.lib)
|
||||
endif (WINDOWS)
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
include(Linking)
|
||||
include(Prebuilt)
|
||||
|
||||
if (WINDOWS)
|
||||
use_prebuilt_binary(freeglut)
|
||||
set(GLUT_LIBRARY
|
||||
debug freeglut_static.lib
|
||||
optimized freeglut_static.lib)
|
||||
endif (WINDOWS)
|
||||
|
||||
if (LINUX)
|
||||
FIND_LIBRARY(GLUT_LIBRARY glut)
|
||||
endif (LINUX)
|
||||
|
||||
if (DARWIN)
|
||||
include(CMakeFindFrameworks)
|
||||
find_library(GLUT_LIBRARY GLUT)
|
||||
endif (DARWIN)
|
||||
|
|
@ -1,63 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
# If you want to enable or disable TCMALLOC in viewer builds, this is the place.
|
||||
# set ON or OFF as desired.
|
||||
#set (USE_TCMALLOC ON)
|
||||
set (USE_TCMALLOC OFF) # <FS:ND> tcmalloc removal
|
||||
|
||||
if (USESYSTEMLIBS)
|
||||
include(FindGooglePerfTools)
|
||||
else (USESYSTEMLIBS)
|
||||
if (WINDOWS)
|
||||
if (USE_TCMALLOC)
|
||||
use_prebuilt_binary(gperftools)
|
||||
set(TCMALLOC_LIBRARIES
|
||||
debug libtcmalloc_minimal-debug
|
||||
optimized libtcmalloc_minimal)
|
||||
set(TCMALLOC_LINK_FLAGS "/INCLUDE:__tcmalloc")
|
||||
else (USE_TCMALLOC)
|
||||
set(TCMALLOC_LIBRARIES)
|
||||
set(TCMALLOC_LINK_FLAGS)
|
||||
endif (USE_TCMALLOC)
|
||||
set(GOOGLE_PERFTOOLS_FOUND "YES")
|
||||
endif (WINDOWS)
|
||||
if (LINUX)
|
||||
if (USE_TCMALLOC)
|
||||
use_prebuilt_binary(gperftools)
|
||||
set(TCMALLOC_LIBRARIES
|
||||
tcmalloc)
|
||||
else (USE_TCMALLOC)
|
||||
set(TCMALLOC_LIBRARIES)
|
||||
endif (USE_TCMALLOC)
|
||||
set(PROFILER_LIBRARIES profiler)
|
||||
set(GOOGLE_PERFTOOLS_INCLUDE_DIR
|
||||
${LIBS_PREBUILT_DIR}/include)
|
||||
set(GOOGLE_PERFTOOLS_FOUND "YES")
|
||||
endif (LINUX)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
||||
if (GOOGLE_PERFTOOLS_FOUND)
|
||||
# XXX Disable temporarily, until we have compilation issues on 64-bit
|
||||
# Etch sorted.
|
||||
set(USE_GOOGLE_PERFTOOLS OFF CACHE BOOL "Build with Google PerfTools support.")
|
||||
endif (GOOGLE_PERFTOOLS_FOUND)
|
||||
|
||||
if (WINDOWS)
|
||||
set(USE_GOOGLE_PERFTOOLS ON)
|
||||
endif (WINDOWS)
|
||||
|
||||
if (USE_GOOGLE_PERFTOOLS)
|
||||
if (USE_TCMALLOC)
|
||||
set(TCMALLOC_FLAG -DLL_USE_TCMALLOC=1)
|
||||
else (USE_TCMALLOC)
|
||||
set(TCMALLOC_FLAG -ULL_USE_TCMALLOC)
|
||||
endif (USE_TCMALLOC)
|
||||
endif (USE_GOOGLE_PERFTOOLS)
|
||||
|
||||
if (USE_GOOGLE_PERFTOOLS)
|
||||
include_directories(${GOOGLE_PERFTOOLS_INCLUDE_DIR})
|
||||
set(GOOGLE_PERFTOOLS_LIBRARIES ${TCMALLOC_LIBRARIES} ${STACKTRACE_LIBRARIES} ${PROFILER_LIBRARIES})
|
||||
else (USE_GOOGLE_PERFTOOLS)
|
||||
endif (USE_GOOGLE_PERFTOOLS)
|
||||
|
||||
|
|
@ -8,6 +8,11 @@ use_prebuilt_binary(havok-source)
|
|||
set(Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Source)
|
||||
list(APPEND Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Demo)
|
||||
|
||||
# HK_DISABLE_IMPLICIT_VVECTOR3_CONVERSION suppresses an intended conversion
|
||||
# function which Xcode scolds us will unconditionally enter infinite
|
||||
# recursion if called. This hides that function.
|
||||
add_definitions("-DHK_DISABLE_IMPLICIT_VVECTOR3_CONVERSION")
|
||||
|
||||
set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
|
||||
set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
|
||||
|
||||
|
|
@ -49,89 +54,74 @@ unset(HK_DEBUG_LIBRARIES)
|
|||
unset(HK_RELEASE_LIBRARIES)
|
||||
unset(HK_RELWITHDEBINFO_LIBRARIES)
|
||||
|
||||
if (DEBUG_PREBUILT)
|
||||
# DEBUG_MESSAGE() displays debugging message
|
||||
function(DEBUG_MESSAGE)
|
||||
# prints message args separated by semicolons rather than spaces,
|
||||
# but making it pretty is a lot more work
|
||||
message(STATUS "${ARGN}")
|
||||
endfunction(DEBUG_MESSAGE)
|
||||
else (DEBUG_PREBUILT)
|
||||
# without DEBUG_PREBUILT, DEBUG_MESSAGE() is a no-op
|
||||
function(DEBUG_MESSAGE)
|
||||
endfunction(DEBUG_MESSAGE)
|
||||
endif (DEBUG_PREBUILT)
|
||||
|
||||
# DEBUG_EXEC() reports each execute_process() before invoking
|
||||
function(DEBUG_EXEC)
|
||||
DEBUG_MESSAGE(${ARGN})
|
||||
execute_process(COMMAND ${ARGN})
|
||||
endfunction(DEBUG_EXEC)
|
||||
|
||||
# *TODO: Figure out why we need to extract like this...
|
||||
foreach(HAVOK_LIB ${HAVOK_LIBS})
|
||||
find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
|
||||
find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
|
||||
find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
|
||||
|
||||
if(LINUX)
|
||||
set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
|
||||
set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
|
||||
set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
|
||||
find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
|
||||
find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
|
||||
find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
|
||||
|
||||
if(LINUX)
|
||||
set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
|
||||
set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
|
||||
set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
|
||||
|
||||
# Try to avoid extracting havok library each time we run cmake.
|
||||
if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted")
|
||||
file(READ ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted "havok_${HAVOK_LIB}_extracted")
|
||||
if(DEBUG_PREBUILT)
|
||||
message(STATUS "havok_${HAVOK_LIB}_extracted: \"${havok_${HAVOK_LIB}_extracted}\"")
|
||||
endif(DEBUG_PREBUILT)
|
||||
DEBUG_MESSAGE("havok_${HAVOK_LIB}_extracted: \"${havok_${HAVOK_LIB}_extracted}\"")
|
||||
endif("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted")
|
||||
|
||||
if(${PREBUILD_TRACKING_DIR}/havok_source_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
|
||||
if(DEBUG_PREBUILT)
|
||||
MESSAGE(STATUS "Extracting ${HAVOK_LIB}...")
|
||||
endif(DEBUG_PREBUILT)
|
||||
set(cmd "mkdir")
|
||||
DEBUG_MESSAGE("Extracting ${HAVOK_LIB}...")
|
||||
|
||||
if(DEBUG_PREBUILT)
|
||||
MESSAGE(STATUS "${cmd} ${debug_dir}")
|
||||
endif(DEBUG_PREBUILT)
|
||||
exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
|
||||
|
||||
if(DEBUG_PREBUILT)
|
||||
MESSAGE(STATUS "${cmd} ${release_dir}")
|
||||
endif(DEBUG_PREBUILT)
|
||||
exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
|
||||
|
||||
if(DEBUG_PREBUILT)
|
||||
MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}")
|
||||
endif(DEBUG_PREBUILT)
|
||||
exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
|
||||
|
||||
set(cmd "ar")
|
||||
set(arg " -xv")
|
||||
set(arg "${arg} ../lib${HAVOK_LIB}.a")
|
||||
if(DEBUG_PREBUILT)
|
||||
MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}")
|
||||
endif(DEBUG_PREBUILT)
|
||||
exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
|
||||
|
||||
if(DEBUG_PREBUILT)
|
||||
MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}")
|
||||
endif(DEBUG_PREBUILT)
|
||||
exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
|
||||
|
||||
if(DEBUG_PREBUILT)
|
||||
MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}")
|
||||
endif(DEBUG_PREBUILT)
|
||||
exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
|
||||
foreach(lib ${debug_dir} ${release_dir} ${relwithdebinfo_dir})
|
||||
DEBUG_EXEC("mkdir" ${lib})
|
||||
DEBUG_EXEC("ar" "-xv" "../lib${HAVOK_LIB}.a"
|
||||
WORKING_DIRECTORY ${lib})
|
||||
endforeach(lib)
|
||||
|
||||
# Just assume success for now.
|
||||
set(havok_${HAVOK_LIB}_extracted 0)
|
||||
file(WRITE ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted "${havok_${HAVOK_LIB}_extracted}")
|
||||
|
||||
endif(${PREBUILD_TRACKING_DIR}/havok_source_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
|
||||
endif()
|
||||
|
||||
file(GLOB extracted_debug "${debug_dir}/*.o")
|
||||
file(GLOB extracted_release "${release_dir}/*.o")
|
||||
file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
|
||||
file(GLOB extracted_debug "${debug_dir}/*.o")
|
||||
file(GLOB extracted_release "${release_dir}/*.o")
|
||||
file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
|
||||
|
||||
if(DEBUG_PREBUILT)
|
||||
MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o")
|
||||
MESSAGE(STATUS "extracted_release ${release_dir}/*.o")
|
||||
MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
|
||||
endif(DEBUG_PREBUILT)
|
||||
DEBUG_MESSAGE("extracted_debug ${debug_dir}/*.o")
|
||||
DEBUG_MESSAGE("extracted_release ${release_dir}/*.o")
|
||||
DEBUG_MESSAGE("extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
|
||||
|
||||
list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
|
||||
list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
|
||||
list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
|
||||
else(LINUX)
|
||||
# Win32
|
||||
list(APPEND HK_DEBUG_LIBRARIES ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
|
||||
list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
|
||||
list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
|
||||
endif (LINUX)
|
||||
list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
|
||||
list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
|
||||
list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
|
||||
else(LINUX)
|
||||
# Win32
|
||||
list(APPEND HK_DEBUG_LIBRARIES ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
|
||||
list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
|
||||
list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
|
||||
endif (LINUX)
|
||||
endforeach(HAVOK_LIB)
|
||||
|
||||
endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ else (USESYSTEMLIBS)
|
|||
if (WINDOWS)
|
||||
set(HUNSPELL_LIBRARY libhunspell)
|
||||
elseif(DARWIN)
|
||||
set(HUNSPELL_LIBRARY hunspell-1.3.0)
|
||||
set(HUNSPELL_LIBRARY hunspell-1.3)
|
||||
elseif(LINUX)
|
||||
set(HUNSPELL_LIBRARY hunspell-1.3)
|
||||
else()
|
||||
|
|
|
|||
|
|
@ -10,23 +10,17 @@ if (USESYSTEMLIBS)
|
|||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(jsoncpp)
|
||||
if (WINDOWS)
|
||||
if (ND_BUILD64BIT_ARCH)
|
||||
set(JSONCPP_LIBRARIES
|
||||
debug json_libmtd.lib
|
||||
optimized json_libmt.lib)
|
||||
else (ND_BUILD64BIT_ARCH)
|
||||
set(JSONCPP_LIBRARIES
|
||||
debug json_libmdd.lib
|
||||
optimized json_libmd.lib)
|
||||
endif (ND_BUILD64BIT_ARCH)
|
||||
set(JSONCPP_LIBRARIES
|
||||
debug json_libmdd.lib
|
||||
optimized json_libmd.lib)
|
||||
elseif (DARWIN)
|
||||
set(JSONCPP_LIBRARIES libjson_darwin_libmt.a)
|
||||
elseif (LINUX)
|
||||
if (ND_BUILD64BIT_ARCH)
|
||||
if ( ADDRESS_SIZE EQUAL 64 )
|
||||
set(JSONCPP_LIBRARIES libjson_linux-gcc-4.6_libmt.a)
|
||||
else (ND_BUILD64BIT_ARCH)
|
||||
else ( )
|
||||
set(JSONCPP_LIBRARIES libjson_linux-gcc-4.1.3_libmt.a)
|
||||
endif (ND_BUILD64BIT_ARCH)
|
||||
endif ( )
|
||||
endif (WINDOWS)
|
||||
set(JSONCPP_INCLUDE_DIR "${LIBS_PREBUILT_DIR}/include/jsoncpp" "${LIBS_PREBUILT_DIR}/include/json")
|
||||
set(JSONCPP_INCLUDE_DIR "${LIBS_PREBUILT_DIR}/include/")
|
||||
endif (USESYSTEMLIBS)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ include(LLTestCommand)
|
|||
|
||||
include(Tut)
|
||||
|
||||
#*****************************************************************************
|
||||
# LL_ADD_PROJECT_UNIT_TESTS
|
||||
#*****************************************************************************
|
||||
MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
||||
# Given a project name and a list of sourcefiles (with optional properties on each),
|
||||
# add targets to build and run the tests specified.
|
||||
|
|
@ -40,7 +43,6 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
|||
${APRUTIL_LIBRARIES}
|
||||
${APR_LIBRARIES}
|
||||
llcommon
|
||||
llcorehttp
|
||||
)
|
||||
IF(NOT "${project}" STREQUAL "llmath")
|
||||
# add llmath as a dep unless the tested module *is* llmath!
|
||||
|
|
@ -80,19 +82,17 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
|||
# Per-codefile additional / external source, header, and include dir property extraction
|
||||
#
|
||||
# Source
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
|
||||
IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_SOURCE_FILES "")
|
||||
ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_SOURCE_FILES ${source} tests/${name}_test.${extension} ${alltest_SOURCE_FILES} ${${name}_test_additional_SOURCE_FILES} )
|
||||
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
|
||||
SET(${name}_test_SOURCE_FILES
|
||||
${source}
|
||||
tests/${name}_test.${extension}
|
||||
${alltest_SOURCE_FILES}
|
||||
${${name}_test_additional_SOURCE_FILES} )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Headers
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
|
||||
IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_HEADER_FILES "")
|
||||
ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
|
||||
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
|
||||
SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
|
||||
set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
|
||||
LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
|
||||
|
|
@ -100,10 +100,7 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
|||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
# Include dirs
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
|
||||
IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_INCLUDE_DIRS "")
|
||||
ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
|
||||
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
|
||||
INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${${name}_test_additional_INCLUDE_DIRS} )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")
|
||||
|
|
@ -119,15 +116,9 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
|||
#
|
||||
# WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
|
||||
# Projects
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
|
||||
IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_PROJECTS "")
|
||||
ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
|
||||
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
|
||||
# Libraries
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
|
||||
IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
|
||||
SET(${name}_test_additional_LIBRARIES "")
|
||||
ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
|
||||
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
|
||||
|
|
@ -135,13 +126,14 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
|||
# Add to project
|
||||
TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
|
||||
# Compile-time Definitions
|
||||
GET_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS)
|
||||
IF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
|
||||
SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES COMPILE_FLAGS ${${name}_test_additional_CFLAGS} )
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
ENDIF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
|
||||
GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS)
|
||||
SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name}
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${${name}_test_additional_CFLAGS}"
|
||||
COMPILE_DEFINITIONS "LL_TEST=${name};LL_TEST_${name}")
|
||||
IF(LL_TEST_VERBOSE)
|
||||
MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
|
||||
ENDIF(LL_TEST_VERBOSE)
|
||||
|
||||
#
|
||||
# Setup test targets
|
||||
|
|
@ -181,6 +173,19 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
|||
ADD_DEPENDENCIES(${project} ${project}_tests)
|
||||
ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
|
||||
|
||||
#*****************************************************************************
|
||||
# GET_OPT_SOURCE_FILE_PROPERTY
|
||||
#*****************************************************************************
|
||||
MACRO(GET_OPT_SOURCE_FILE_PROPERTY var filename property)
|
||||
GET_SOURCE_FILE_PROPERTY(${var} "${filename}" "${property}")
|
||||
IF("${${var}}" MATCHES NOTFOUND)
|
||||
SET(${var} "")
|
||||
ENDIF("${${var}}" MATCHES NOTFOUND)
|
||||
ENDMACRO(GET_OPT_SOURCE_FILE_PROPERTY)
|
||||
|
||||
#*****************************************************************************
|
||||
# LL_ADD_INTEGRATION_TEST
|
||||
#*****************************************************************************
|
||||
FUNCTION(LL_ADD_INTEGRATION_TEST
|
||||
testname
|
||||
additional_source_files
|
||||
|
|
@ -190,7 +195,7 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
|
|||
if(TEST_DEBUG)
|
||||
message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
|
||||
endif(TEST_DEBUG)
|
||||
|
||||
|
||||
SET(source_files
|
||||
tests/${testname}_test.cpp
|
||||
${CMAKE_SOURCE_DIR}/test/test.cpp
|
||||
|
|
@ -212,7 +217,11 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
|
|||
message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
|
||||
endif(TEST_DEBUG)
|
||||
ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
|
||||
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
|
||||
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname}
|
||||
PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
|
||||
COMPILE_DEFINITIONS "LL_TEST=${testname};LL_TEST_${testname}"
|
||||
)
|
||||
|
||||
if(USESYSTEMLIBS)
|
||||
SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
|
||||
|
|
@ -274,6 +283,9 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
|
|||
|
||||
ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
|
||||
|
||||
#*****************************************************************************
|
||||
# SET_TEST_PATH
|
||||
#*****************************************************************************
|
||||
MACRO(SET_TEST_PATH LISTVAR)
|
||||
IF(WINDOWS)
|
||||
# We typically build/package only Release variants of third-party
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
use_prebuilt_binary(llbase)
|
||||
|
|
@ -4,7 +4,6 @@ include(APR)
|
|||
include(Boost)
|
||||
include(EXPAT)
|
||||
include(ZLIB)
|
||||
include(GooglePerfTools)
|
||||
|
||||
set(LLCOMMON_INCLUDE_DIRS
|
||||
${LIBS_OPEN_DIR}/llcommon
|
||||
|
|
@ -34,8 +33,6 @@ else (LINUX)
|
|||
${BOOST_SYSTEM_LIBRARY} )
|
||||
endif (LINUX)
|
||||
|
||||
# add_definitions(${TCMALLOC_FLAG})
|
||||
|
||||
set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.")
|
||||
if(LLCOMMON_LINK_SHARED)
|
||||
add_definitions(-DLL_COMMON_LINK_SHARED=1)
|
||||
|
|
|
|||
|
|
@ -8,13 +8,12 @@ if (INSTALL_PROPRIETARY)
|
|||
endif (INSTALL_PROPRIETARY)
|
||||
|
||||
set( ND_KDU_SUFFIX "" )
|
||||
if( ND_BUILD64BIT_ARCH )
|
||||
if( ADDRESS_SIZE EQUAL 64 )
|
||||
if( WINDOWS OR LINUX )
|
||||
set( ND_KDU_SUFFIX "_x64" )
|
||||
endif( WINDOWS OR LINUX )
|
||||
endif( ND_BUILD64BIT_ARCH )
|
||||
endif( ADDRESS_SIZE EQUAL 64 )
|
||||
|
||||
|
||||
if (USE_KDU)
|
||||
if (USESYSTEMLIBS)
|
||||
include(FindKDU)
|
||||
|
|
|
|||
|
|
@ -3,35 +3,38 @@
|
|||
macro(ll_deploy_sharedlibs_command target_exe)
|
||||
set(TARGET_LOCATION $<TARGET_FILE:${target_exe}>)
|
||||
get_filename_component(OUTPUT_PATH ${TARGET_LOCATION} PATH) #<FS:ND> TARGET_LOCATION is a generator expression and will not expand during configure, thus OUTPUT_PATH will always be empty, for Windows (where this a a problem) DeploySharedLibs.cmake will take care of this.
|
||||
|
||||
if(DARWIN)
|
||||
SET_TEST_PATH(SEARCH_DIRS)
|
||||
get_target_property(IS_BUNDLE ${target_exe} MACOSX_BUNDLE)
|
||||
if(IS_BUNDLE)
|
||||
# If its a bundle the exe is not in the target location, this should find it.
|
||||
get_filename_component(TARGET_FILE ${TARGET_LOCATION} NAME)
|
||||
set(OUTPUT_PATH ${TARGET_LOCATION}.app/Contents/MacOS)
|
||||
set(TARGET_LOCATION ${OUTPUT_PATH}/${TARGET_FILE})
|
||||
set(OUTPUT_PATH ${OUTPUT_PATH}/../Resources)
|
||||
endif(IS_BUNDLE)
|
||||
elseif(WINDOWS)
|
||||
SET_TEST_PATH(SEARCH_DIRS)
|
||||
LIST(APPEND SEARCH_DIRS "$ENV{SystemRoot}/system32")
|
||||
elseif(LINUX)
|
||||
SET_TEST_PATH(SEARCH_DIRS)
|
||||
set(OUTPUT_PATH ${OUTPUT_PATH}/lib)
|
||||
endif(DARWIN)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${target_exe} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS
|
||||
"-DBIN_NAME=\"${TARGET_LOCATION}\""
|
||||
"-DSEARCH_DIRS=\"${SEARCH_DIRS}\""
|
||||
"-DDST_PATH=\"${OUTPUT_PATH}\""
|
||||
"-P"
|
||||
"${CMAKE_SOURCE_DIR}/cmake/DeploySharedLibs.cmake"
|
||||
)
|
||||
# It's not clear that this does anything useful for us on Darwin. It has
|
||||
# been broken for some time now; the BIN_NAME was being constructed as a
|
||||
# ridiculous nonexistent path with duplicated segments. Fixing that only
|
||||
# produces ominous spammy warnings: at the time the command below is run, we
|
||||
# have not yet populated the nested mac-crash-logger.app/Contents/Resources
|
||||
# with the .dylibs with which it was linked. Moreover, the form of the
|
||||
# embedded @executable_path/../Resources/mumble.dylib pathname confuses the
|
||||
# GetPrerequisites.cmake tool invoked by DeploySharedLibs.cmake. It seems
|
||||
# clear that we have long since accomplished by other means what this was
|
||||
# originally supposed to do. Skipping it only eliminates an annoying
|
||||
# non-fatal error.
|
||||
if(NOT DARWIN)
|
||||
if(WINDOWS)
|
||||
SET_TEST_PATH(SEARCH_DIRS)
|
||||
LIST(APPEND SEARCH_DIRS "$ENV{SystemRoot}/system32")
|
||||
elseif(LINUX)
|
||||
SET_TEST_PATH(SEARCH_DIRS)
|
||||
set(OUTPUT_PATH ${OUTPUT_PATH}/lib)
|
||||
endif(WINDOWS)
|
||||
|
||||
add_custom_command(
|
||||
TARGET ${target_exe} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS
|
||||
"-DBIN_NAME=\"${TARGET_LOCATION}\""
|
||||
"-DSEARCH_DIRS=\"${SEARCH_DIRS}\""
|
||||
"-DDST_PATH=\"${OUTPUT_PATH}\""
|
||||
"-P"
|
||||
"${CMAKE_SOURCE_DIR}/cmake/DeploySharedLibs.cmake"
|
||||
)
|
||||
endif(NOT DARWIN)
|
||||
|
||||
endmacro(ll_deploy_sharedlibs_command)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ if (WINDOWS)
|
|||
libvlccore.lib
|
||||
)
|
||||
elseif (DARWIN)
|
||||
set(VLC_PLUGIN_LIBRARIES
|
||||
libvlc.dylib
|
||||
libvlccore.dylib
|
||||
)
|
||||
elseif (LINUX)
|
||||
# Specify a full path to make sure we get a static link
|
||||
set(VLC_PLUGIN_LIBRARIES
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
include(Prebuilt)
|
||||
|
||||
set(NGHTTP2_FIND_QUIETLY ON)
|
||||
set(NGHTTP2_FIND_REQUIRED ON)
|
||||
|
||||
if (USESYSTEMLIBS)
|
||||
include(FindNGHTTP2)
|
||||
else (USESYSTEMLIBS)
|
||||
use_prebuilt_binary(nghttp2)
|
||||
if (WINDOWS)
|
||||
set(NGHTTP2_LIBRARIES
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/nghttp2.lib
|
||||
)
|
||||
elseif (DARWIN)
|
||||
set(NGHTTP2_LIBRARIES libnghttp2.dylib)
|
||||
else (WINDOWS)
|
||||
set(NGHTTP2_LIBRARIES libnghttp2.a)
|
||||
endif (WINDOWS)
|
||||
set(NGHTTP2_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/nghttp2)
|
||||
endif (USESYSTEMLIBS)
|
||||
|
|
@ -6,11 +6,7 @@ set(NVAPI ON CACHE BOOL "Use NVAPI.")
|
|||
if (NVAPI)
|
||||
if (WINDOWS)
|
||||
use_prebuilt_binary(nvapi)
|
||||
if( NOT ND_BUILD64BIT_ARCH )
|
||||
set(NVAPI_LIBRARY nvapi)
|
||||
else( NOT ND_BUILD64BIT_ARCH )
|
||||
set(NVAPI_LIBRARY nvapi64 )
|
||||
endif( NOT ND_BUILD64BIT_ARCH )
|
||||
set(NVAPI_LIBRARY nvapi)
|
||||
else (WINDOWS)
|
||||
set(NVAPI_LIBRARY "")
|
||||
endif (WINDOWS)
|
||||
|
|
|
|||
|
|
@ -39,13 +39,12 @@ macro (use_prebuilt_binary _binary)
|
|||
|
||||
if(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0)
|
||||
if(DEBUG_PREBUILT)
|
||||
message("cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install ${autobuild_install_platform}
|
||||
message(STATUS "cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install
|
||||
--install-dir=${AUTOBUILD_INSTALL_DIR}
|
||||
${_binary} ")
|
||||
endif(DEBUG_PREBUILT)
|
||||
execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}"
|
||||
install
|
||||
${autobuild_install_platform}
|
||||
--install-dir=${AUTOBUILD_INSTALL_DIR}
|
||||
${_binary}
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
|
|
|
|||
|
|
@ -1,53 +0,0 @@
|
|||
# -*- cmake -*-
|
||||
|
||||
if(INSTALL_PROPRIETARY)
|
||||
include(Prebuilt)
|
||||
if (WINDOWS)
|
||||
use_prebuilt_binary(quicktime)
|
||||
endif (WINDOWS)
|
||||
endif(INSTALL_PROPRIETARY)
|
||||
|
||||
if(HAVE_QUICKTIME_3P AND WINDOWS)
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(quicktime)
|
||||
endif(HAVE_QUICKTIME_3P AND WINDOWS)
|
||||
|
||||
if (DARWIN)
|
||||
include(CMakeFindFrameworks)
|
||||
find_library(QUICKTIME_LIBRARY QuickTime)
|
||||
elseif (WINDOWS)
|
||||
set(QUICKTIME_SDK_DIR "$ENV{PROGRAMFILES}/QuickTime SDK"
|
||||
CACHE PATH "Location of the QuickTime SDK.")
|
||||
|
||||
find_library(DEBUG_QUICKTIME_LIBRARY qtmlclient.lib
|
||||
PATHS
|
||||
${ARCH_PREBUILT_DIRS_DEBUG}
|
||||
"${QUICKTIME_SDK_DIR}\\libraries"
|
||||
)
|
||||
|
||||
find_library(RELEASE_QUICKTIME_LIBRARY qtmlclient.lib
|
||||
PATHS
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}
|
||||
"${QUICKTIME_SDK_DIR}\\libraries"
|
||||
)
|
||||
|
||||
if (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY)
|
||||
set(QUICKTIME_LIBRARY
|
||||
optimized ${RELEASE_QUICKTIME_LIBRARY}
|
||||
debug ${DEBUG_QUICKTIME_LIBRARY}
|
||||
)
|
||||
|
||||
endif (DEBUG_QUICKTIME_LIBRARY AND RELEASE_QUICKTIME_LIBRARY)
|
||||
|
||||
include_directories(
|
||||
${LIBS_PREBUILT_DIR}/include/quicktime
|
||||
"${QUICKTIME_SDK_DIR}\\CIncludes"
|
||||
)
|
||||
endif (DARWIN)
|
||||
|
||||
mark_as_advanced(QUICKTIME_LIBRARY)
|
||||
|
||||
if (QUICKTIME_LIBRARY)
|
||||
set(QUICKTIME ON CACHE BOOL "Build with QuickTime streaming media support.")
|
||||
endif (QUICKTIME_LIBRARY)
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
if (DARWIN)
|
||||
include (Prebuilt)
|
||||
use_prebuilt_binary(requests)
|
||||
use_prebuilt_binary(urllib3)
|
||||
use_prebuilt_binary(chardet)
|
||||
use_prebuilt_binary(idna)
|
||||
endif (DARWIN)
|
||||
|
|
@ -32,9 +32,9 @@ if (USESYSTEMLIBS)
|
|||
add_definitions(${${pkg}_CFLAGS_OTHERS})
|
||||
endforeach(pkg)
|
||||
else (USESYSTEMLIBS)
|
||||
if (LINUX OR WINDOWS)
|
||||
if (LINUX)
|
||||
use_prebuilt_binary(gtk-atk-pango-glib)
|
||||
endif (LINUX OR WINDOWS)
|
||||
endif (LINUX)
|
||||
|
||||
if (LINUX)
|
||||
set(UI_LIB_NAMES
|
||||
|
|
|
|||
|
|
@ -9,15 +9,15 @@
|
|||
# LINUX - Linux
|
||||
# WINDOWS - Windows
|
||||
|
||||
set(NDTARGET_ARCH "x86" CACHE STRING "Build 64 or 32 bit viewer. Defaults to 32 bit.")
|
||||
set(ND_USE_OPENJPEG2 OFF CACHE BOOL "Use OpenJPEG 2.1 instead of 1.4. Default off.")
|
||||
|
||||
if( ${NDTARGET_ARCH} STREQUAL "x64" )
|
||||
set( ND_BUILD64BIT_ARCH ON )
|
||||
elseif( ${NDTARGET_ARCH} STREQUAL "universal" )
|
||||
set( ND_BUILD64BIT_ARCH ON )
|
||||
set( OSX_UNIVERSAL_ARCH ON )
|
||||
endif()
|
||||
# Switches set here and in 00-Common.cmake must agree with
|
||||
# https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables
|
||||
# Reading $LL_BUILD is an attempt to directly use those switches.
|
||||
# <FS:Ansariel> This causes CMP0054 warning
|
||||
#if ("$ENV{LL_BUILD}" STREQUAL "")
|
||||
if ($ENV{LL_BUILD} STREQUAL "")
|
||||
# </FS:Ansariel>
|
||||
message(FATAL_ERROR "Environment variable LL_BUILD must be set")
|
||||
endif ()
|
||||
|
||||
# Relative and absolute paths to subtrees.
|
||||
|
||||
|
|
@ -35,16 +35,7 @@ set(VIEWER_PREFIX)
|
|||
set(INTEGRATION_TESTS_PREFIX)
|
||||
set(LL_TESTS OFF CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
|
||||
set(INCREMENTAL_LINK OFF CACHE BOOL "Use incremental linking on win32 builds (enable for faster links on some machines)")
|
||||
|
||||
# <FS:ND> When building for Linux x64 we enable building the media plugins, in all other cases we use the prebuild 32 bit packages
|
||||
# set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
|
||||
|
||||
if (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
|
||||
set( ENABLE_MEDIA_PLUGINS OFF CACHE FORCE "Build with media plugins" )
|
||||
else (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
|
||||
set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
|
||||
endif (ND_BUILD64BIT_ARCH AND ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
|
||||
# </FS:ND>
|
||||
set(ENABLE_MEDIA_PLUGINS ON CACHE BOOL "Turn off building media plugins if they are imported by third-party library mechanism")
|
||||
|
||||
if(LIBS_CLOSED_DIR)
|
||||
file(TO_CMAKE_PATH "${LIBS_CLOSED_DIR}" LIBS_CLOSED_DIR)
|
||||
|
|
@ -78,49 +69,55 @@ if (NOT CMAKE_BUILD_TYPE)
|
|||
"Build type. One of: Debug Release RelWithDebInfo" FORCE)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
|
||||
# If someone has specified an address size, use that to determine the
|
||||
# architecture. Otherwise, let the architecture specify the address size.
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
#message(STATUS "ADDRESS_SIZE is 32")
|
||||
set(ARCH i686)
|
||||
elseif (ADDRESS_SIZE EQUAL 64)
|
||||
#message(STATUS "ADDRESS_SIZE is 64")
|
||||
set(ARCH x86_64)
|
||||
else (ADDRESS_SIZE EQUAL 32)
|
||||
#message(STATUS "ADDRESS_SIZE is UNRECOGNIZED: '${ADDRESS_SIZE}'")
|
||||
# Use Python's platform.machine() since uname -m isn't available everywhere.
|
||||
# Even if you can assume cygwin uname -m, the answer depends on whether
|
||||
# you're running 32-bit cygwin or 64-bit cygwin! But even 32-bit Python will
|
||||
# report a 64-bit processor.
|
||||
execute_process(COMMAND
|
||||
"${PYTHON_EXECUTABLE}" "-c"
|
||||
"import platform; print platform.machine()"
|
||||
OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
# We expect values of the form i386, i686, x86_64, AMD64.
|
||||
# In CMake, expressing ARCH.endswith('64') is awkward:
|
||||
string(LENGTH "${ARCH}" ARCH_LENGTH)
|
||||
math(EXPR ARCH_LEN_2 "${ARCH_LENGTH} - 2")
|
||||
string(SUBSTRING "${ARCH}" ${ARCH_LEN_2} 2 ARCH_LAST_2)
|
||||
if (ARCH_LAST_2 STREQUAL 64)
|
||||
#message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}")
|
||||
set(ADDRESS_SIZE 64)
|
||||
else ()
|
||||
#message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}")
|
||||
set(ADDRESS_SIZE 32)
|
||||
endif ()
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
set(WINDOWS ON BOOL FORCE)
|
||||
set(ARCH i686)
|
||||
set(LL_ARCH ${ARCH}_win32)
|
||||
set(LL_ARCH_DIR ${ARCH}-win32)
|
||||
set(WORD_SIZE 32)
|
||||
if( ND_BUILD64BIT_ARCH )
|
||||
set(WORD_SIZE 64)
|
||||
endif( ND_BUILD64BIT_ARCH )
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set(LINUX ON BOOl FORCE)
|
||||
|
||||
# If someone has specified a word size, use that to determine the
|
||||
# architecture. Otherwise, let the architecture specify the word size.
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
#message(STATUS "WORD_SIZE is 32")
|
||||
set(ARCH i686)
|
||||
elseif (WORD_SIZE EQUAL 64)
|
||||
#message(STATUS "WORD_SIZE is 64")
|
||||
set(ARCH x86_64)
|
||||
else (WORD_SIZE EQUAL 32)
|
||||
#message(STATUS "WORD_SIZE is UNDEFINED")
|
||||
execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/
|
||||
OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (ARCH STREQUAL x86_64)
|
||||
#message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}")
|
||||
set(WORD_SIZE 64)
|
||||
else (ARCH STREQUAL x86_64)
|
||||
#message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}")
|
||||
set(WORD_SIZE 32)
|
||||
endif (ARCH STREQUAL x86_64)
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
|
||||
if (WORD_SIZE EQUAL 32)
|
||||
if (ADDRESS_SIZE EQUAL 32)
|
||||
set(DEB_ARCHITECTURE i386)
|
||||
set(FIND_LIBRARY_USE_LIB64_PATHS OFF)
|
||||
set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib32 ${CMAKE_SYSTEM_LIBRARY_PATH})
|
||||
else (WORD_SIZE EQUAL 32)
|
||||
else (ADDRESS_SIZE EQUAL 32)
|
||||
set(DEB_ARCHITECTURE amd64)
|
||||
set(FIND_LIBRARY_USE_LIB64_PATHS ON)
|
||||
endif (WORD_SIZE EQUAL 32)
|
||||
endif (ADDRESS_SIZE EQUAL 32)
|
||||
|
||||
execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH
|
||||
RESULT_VARIABLE DPKG_RESULT
|
||||
|
|
@ -150,71 +147,59 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(DARWIN 1)
|
||||
|
||||
# now we only support Xcode 6.0 using 10.9 (Mavericks), minimum OS 10.7 (Lion)
|
||||
#<FS:TS> Be a bit more flexible: support Xcode 6 or 7 and SDKs from 10.9 to 10.11
|
||||
#set(XCODE_VERSION 6.0)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7)
|
||||
#set(CMAKE_OSX_SYSROOT macosx10.9)
|
||||
if(IS_DIRECTORY "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk")
|
||||
# Assume Xcode 7 if Sierra SDK is present
|
||||
set(XCODE_VERSION 7.3)
|
||||
set(CMAKE_OSX_SYSROOT macosx10.12)
|
||||
message(STATUS "OS X SDK 10.12 found.")
|
||||
elseif(IS_DIRECTORY "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk")
|
||||
# Assume Xcode 7 if El Capitan SDK is present
|
||||
set(XCODE_VERSION 7.3)
|
||||
set(CMAKE_OSX_SYSROOT macosx10.11)
|
||||
message(STATUS "OS X SDK 10.11 found.")
|
||||
elseif(IS_DIRECTORY "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk")
|
||||
# Assume Xcode 7 if Yosemite SDK is present
|
||||
set(XCODE_VERSION 7.0)
|
||||
set(CMAKE_OSX_SYSROOT macosx10.10)
|
||||
message(STATUS "OS X SDK 10.10 found.")
|
||||
elseif(IS_DIRECTORY "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk")
|
||||
# Assume Xcode 6 if only Mavericks SDK is present
|
||||
set(XCODE_VERSION 6.0)
|
||||
set(CMAKE_OSX_SYSROOT macosx10.9)
|
||||
message(STATUS "OS X SDK 10.9 found.")
|
||||
else(IS_DIRECTORY "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk")
|
||||
message(FATAL_ERROR "Unable to determine which OS X SDK to use. Giving up.")
|
||||
endif(IS_DIRECTORY "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk")
|
||||
|
||||
string(REGEX MATCH "-mmacosx-version-min=([^ ]+)" scratch "$ENV{LL_BUILD}")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "${CMAKE_MATCH_1}")
|
||||
message(STATUS "CMAKE_OSX_DEPLOYMENT_TARGET = '${CMAKE_OSX_DEPLOYMENT_TARGET}'")
|
||||
|
||||
string(REGEX MATCH "-stdlib=([^ ]+)" scratch "$ENV{LL_BUILD}")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "${CMAKE_MATCH_1}")
|
||||
message(STATUS "CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY = '${CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY}'")
|
||||
|
||||
string(REGEX MATCH " -g([^ ]*)" scratch "$ENV{LL_BUILD}")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "${CMAKE_MATCH_1}")
|
||||
# -gdwarf-2 is passed in LL_BUILD according to 00-COMPILE-LINK-RUN.txt.
|
||||
# However, when CMake 3.9.2 sees -gdwarf-2, it silently deletes the whole -g
|
||||
# switch, producing no symbols at all! The same thing happens if we specify
|
||||
# plain -g ourselves, i.e. CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT is
|
||||
# the empty string. Specifying -gdwarf-with-dsym or just -gdwarf drives a
|
||||
# different CMake behavior: it substitutes plain -g. As of 2017-09-19,
|
||||
# viewer-build-variables/variables still passes -gdwarf-2, which is the
|
||||
# no-symbols case. Set -gdwarf, triggering CMake to substitute plain -g --
|
||||
# at least that way we should get symbols, albeit mangled ones. It Would Be
|
||||
# Nice if CMake's behavior could be predicted from a consistent mental
|
||||
# model, instead of only observed experimentally.
|
||||
string(REPLACE "dwarf-2" "dwarf"
|
||||
CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT
|
||||
"${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}")
|
||||
message(STATUS "CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT = '${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}'")
|
||||
|
||||
string(REGEX MATCH "-O([^ ]*)" scratch "$ENV{LL_BUILD}")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL "${CMAKE_MATCH_1}")
|
||||
message(STATUS "CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL = '${CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL}'")
|
||||
|
||||
string(REGEX MATCHALL "[^ ]+" LL_BUILD_LIST "$ENV{LL_BUILD}")
|
||||
list(FIND LL_BUILD_LIST "-iwithsysroot" sysroot_idx)
|
||||
if ("${sysroot_idx}" LESS 0)
|
||||
message(FATAL_ERROR "Environment variable LL_BUILD must contain '-iwithsysroot'")
|
||||
endif ()
|
||||
math(EXPR sysroot_idx "${sysroot_idx} + 1")
|
||||
list(GET LL_BUILD_LIST "${sysroot_idx}" CMAKE_OSX_SYSROOT)
|
||||
message(STATUS "CMAKE_OSX_SYSROOT = '${CMAKE_OSX_SYSROOT}'")
|
||||
|
||||
set(XCODE_VERSION 7.0)
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_OPTIMIZATION_LEVEL 3)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_STRICT_ALIASING NO)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_FAST_MATH NO)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS ssse3)
|
||||
# <FS:TS> Need libc++ for C++11 and Boost
|
||||
#set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libstdc++")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT dwarf-with-dsym)
|
||||
|
||||
# Build only for i386 by default, system default on MacOSX 10.6+ is x86_64
|
||||
if (NOT CMAKE_OSX_ARCHITECTURES)
|
||||
set(CMAKE_OSX_ARCHITECTURES "i386")
|
||||
if(ND_BUILD64BIT_ARCH)
|
||||
set(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
endif(ND_BUILD64BIT_ARCH)
|
||||
if(OSX_UNIVERSAL_ARCH)
|
||||
set(CMAKE_OSX_ARCHITECTURES "i386;x86_64")
|
||||
endif(OSX_UNIVERSAL_ARCH)
|
||||
endif (NOT CMAKE_OSX_ARCHITECTURES)
|
||||
set(CMAKE_OSX_ARCHITECTURES "${ARCH}")
|
||||
string(REPLACE "i686" "i386" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}")
|
||||
string(REPLACE "AMD64" "x86_64" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}")
|
||||
|
||||
set(ARCH ${CMAKE_OSX_ARCHITECTURES})
|
||||
if(ND_BUILD64BIT_ARCH)
|
||||
set(ARCH x86_64)
|
||||
endif(ND_BUILD64BIT_ARCH)
|
||||
if(OSX_UNIVERSAL_ARCH)
|
||||
set(ARCH universal)
|
||||
endif(OSX_UNIVERSAL_ARCH)
|
||||
set(LL_ARCH ${ARCH}_darwin)
|
||||
set(LL_ARCH_DIR universal-darwin)
|
||||
if(ND_BUILD64BIT_ARCH)
|
||||
set(WORD_SIZE 64)
|
||||
else (ND_BUILD64BIT_ARCH)
|
||||
set(WORD_SIZE 32)
|
||||
endif(ND_BUILD64BIT_ARCH)
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
||||
# Default deploy grid
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
include (Prebuilt)
|
||||
use_prebuilt_binary(viewer-manager)
|
||||
|
||||
|
|
@ -10,10 +10,10 @@ if (NOT USESYSTEMLIBS)
|
|||
use_prebuilt_binary(slvoice)
|
||||
# use_prebuilt_binary(libidn)
|
||||
|
||||
if( ND_BUILD64BIT_ARCH )
|
||||
if( ADDRESS_SIZE EQUAL 64 )
|
||||
if( DARWIN )
|
||||
use_prebuilt_binary( slplugin_x86 )
|
||||
endif( DARWIN )
|
||||
endif( ND_BUILD64BIT_ARCH )
|
||||
endif( )
|
||||
endif(NOT USESYSTEMLIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
# - Embeds a specific manifest file in a Windows binary
|
||||
# Defines the following:
|
||||
# EMBED_MANIFEST - embed manifest in a windows binary with mt
|
||||
# Parameters - _target is the target file, resourceid specifies the resource identifier
|
||||
|
||||
MACRO(EMBED_MANIFEST _target resourceid)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET ${_target}
|
||||
POST_BUILD
|
||||
COMMAND "mt.exe"
|
||||
ARGS
|
||||
-manifest \"${CMAKE_SOURCE_DIR}\\tools\\manifests\\compatibility.manifest\"
|
||||
-inputresource:\"$<TARGET_FILE:${_target}>\"\;\#${resourceid}
|
||||
-outputresource:\"$<TARGET_FILE:${_target}>\"\;\#${resourceid}
|
||||
COMMENT "Adding compatibility manifest to ${_target}"
|
||||
)
|
||||
ENDMACRO(EMBED_MANIFEST _target resourceid)
|
||||
|
|
@ -51,11 +51,13 @@ import HTMLParser
|
|||
import re
|
||||
import signal
|
||||
import subprocess
|
||||
import logging
|
||||
|
||||
def main(command, libpath=[], vars={}):
|
||||
def main(command, arguments=[], libpath=[], vars={}):
|
||||
"""Pass:
|
||||
command is a sequence (e.g. a list) of strings. The first item in the list
|
||||
must be the command name, the rest are its arguments.
|
||||
command is the command to be executed
|
||||
|
||||
argument is a sequence (e.g. a list) of strings to be passed to command
|
||||
|
||||
libpath is a sequence of directory pathnames. These will be appended to
|
||||
the platform-specific dynamic library search path environment variable.
|
||||
|
|
@ -85,7 +87,7 @@ def main(command, libpath=[], vars={}):
|
|||
# might not exist; instead of KeyError, just use an empty string.
|
||||
dirs = os.environ.get(var, "").split(os.pathsep)
|
||||
# Append the sequence in libpath
|
||||
print "%s += %r" % (var, libpath)
|
||||
log.info("%s += %r" % (var, libpath))
|
||||
for dir in libpath:
|
||||
# append system paths at the end
|
||||
if dir in ('/lib', '/usr/lib'):
|
||||
|
|
@ -103,20 +105,20 @@ def main(command, libpath=[], vars={}):
|
|||
# Now rebuild the path string. This way we use a minimum of separators
|
||||
# -- and we avoid adding a pointless separator when libpath is empty.
|
||||
os.environ[var] = os.pathsep.join(clean_dirs)
|
||||
print "%s = %r" % (var, os.environ[var])
|
||||
log.info("%s = %r" % (var, os.environ[var]))
|
||||
# Now handle arbitrary environment variables. The tricky part is ensuring
|
||||
# that all the keys and values we try to pass are actually strings.
|
||||
if vars:
|
||||
print "Setting:"
|
||||
for key, value in vars.iteritems():
|
||||
print "%s=%s" % (key, value)
|
||||
log.info("Setting: %s" % ("\n".join(["%s=%s" % (key, value) for key, value in vars.iteritems()])))
|
||||
os.environ.update(dict([(str(key), str(value)) for key, value in vars.iteritems()]))
|
||||
# Run the child process.
|
||||
print "Running: %s" % " ".join(command)
|
||||
command_list = [command]
|
||||
command_list.extend(arguments)
|
||||
log.info("Running: %s" % " ".join(command_list))
|
||||
# Make sure we see all relevant output *before* child-process output.
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
return subprocess.call(command)
|
||||
return subprocess.call(command_list)
|
||||
except OSError as err:
|
||||
# If the caller is trying to execute a test program that doesn't
|
||||
# exist, we want to produce a reasonable error message rather than a
|
||||
|
|
@ -126,9 +128,9 @@ def main(command, libpath=[], vars={}):
|
|||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
# In practice, the pathnames into CMake's build tree are so long as to
|
||||
# obscure the name of the test program. Just print its basename.
|
||||
print "No such program %s; check for preceding build errors" % \
|
||||
os.path.basename(command[0])
|
||||
# obscure the name of the test program. Just log its basename.
|
||||
log.warn("No such program %s; check for preceding build errors" % \
|
||||
os.path.basename(command[0]))
|
||||
# What rc should we simulate for missing executable? Windows produces
|
||||
# 9009.
|
||||
return 9009
|
||||
|
|
@ -172,10 +174,10 @@ def translate_rc(rc):
|
|||
table = get_windows_table()
|
||||
symbol, desc = table[hexrc]
|
||||
except Exception, err:
|
||||
print >>sys.stderr, "(%s -- carrying on)" % err
|
||||
return "terminated with rc %s (%s)" % (rc, hexrc)
|
||||
log.error("(%s -- carrying on)" % err)
|
||||
log.error("terminated with rc %s (%s)" % (rc, hexrc))
|
||||
else:
|
||||
return "terminated with rc %s: %s: %s" % (hexrc, symbol, desc)
|
||||
log.info("terminated with rc %s: %s: %s" % (hexrc, symbol, desc))
|
||||
|
||||
else:
|
||||
# On Posix, negative rc means the child was terminated by signal -rc.
|
||||
|
|
@ -303,22 +305,26 @@ def get_windows_table():
|
|||
|
||||
return _windows_table
|
||||
|
||||
log=logging.getLogger(__name__)
|
||||
logging.basicConfig()
|
||||
|
||||
if __name__ == "__main__":
|
||||
from optparse import OptionParser
|
||||
parser = OptionParser(usage="usage: %prog [options] command args...")
|
||||
# We want optparse support for the options we ourselves handle -- but we
|
||||
# DO NOT want it looking at options for the executable we intend to run,
|
||||
# rejecting them as invalid because we don't define them. So configure the
|
||||
# parser to stop looking for options as soon as it sees the first
|
||||
# positional argument (traditional Unix syntax).
|
||||
parser.disable_interspersed_args()
|
||||
parser.add_option("-D", "--define", dest="vars", default=[], action="append",
|
||||
metavar="VAR=value",
|
||||
help="Add VAR=value to the env variables defined")
|
||||
parser.add_option("-l", "--libpath", dest="libpath", default=[], action="append",
|
||||
metavar="DIR",
|
||||
help="Add DIR to the platform-dependent DLL search path")
|
||||
opts, args = parser.parse_args()
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("-d", "--debug", dest="loglevel", action="store_const",
|
||||
const=logging.DEBUG, default=logging.WARNING)
|
||||
parser.add_argument("-D", "--define", dest="vars", default=[], action="append",
|
||||
metavar="VAR=value",
|
||||
help="Add VAR=value to the env variables defined")
|
||||
parser.add_argument("-l", "--libpath", dest="libpath", default=[], action="append",
|
||||
metavar="DIR",
|
||||
help="Add DIR to the platform-dependent DLL search path")
|
||||
parser.add_argument("command")
|
||||
parser.add_argument('args', nargs=argparse.REMAINDER)
|
||||
args = parser.parse_args()
|
||||
|
||||
log.setLevel(args.loglevel)
|
||||
|
||||
# What we have in opts.vars is a list of strings of the form "VAR=value"
|
||||
# or possibly just "VAR". What we want is a dict. We can build that dict by
|
||||
# constructing a list of ["VAR", "value"] pairs -- so split each
|
||||
|
|
@ -326,9 +332,9 @@ if __name__ == "__main__":
|
|||
# "VAR=some=user=string"). To handle the case of just "VAR", append "" to
|
||||
# the list returned by split(), then slice off anything after the pair we
|
||||
# want.
|
||||
rc = main(command=args, libpath=opts.libpath,
|
||||
vars=dict([(pair.split('=', 1) + [""])[:2] for pair in opts.vars]))
|
||||
rc = main(command=args.command, arguments=args.args, libpath=args.libpath,
|
||||
vars=dict([(pair.split('=', 1) + [""])[:2] for pair in args.vars]))
|
||||
if rc not in (None, 0):
|
||||
print >>sys.stderr, "Failure running: %s" % " ".join(args)
|
||||
print >>sys.stderr, "Error %s: %s" % (rc, translate_rc(rc))
|
||||
log.error("Failure running: %s" % " ".join([args.command] + args.args))
|
||||
log.error("Error %s: %s" % (rc, translate_rc(rc)))
|
||||
sys.exit((rc < 0) and 255 or rc)
|
||||
|
|
|
|||
|
|
@ -104,21 +104,23 @@ add_custom_command(TARGET llimage_libtest POST_BUILD
|
|||
if (DARWIN)
|
||||
# Copy the required libraries to the package app
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib
|
||||
)
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib
|
||||
)
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib
|
||||
)
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib
|
||||
)
|
||||
foreach(expat ${EXPAT_COPY})
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat}
|
||||
)
|
||||
endforeach(expat)
|
||||
endif (DARWIN)
|
||||
|
||||
if (WINDOWS)
|
||||
|
|
|
|||
|
|
@ -43,7 +43,9 @@ import subprocess
|
|||
|
||||
class ManifestError(RuntimeError):
|
||||
"""Use an exception more specific than generic Python RuntimeError"""
|
||||
pass
|
||||
def __init__(self, msg):
|
||||
self.msg = msg
|
||||
super(ManifestError, self).__init__(self.msg)
|
||||
|
||||
class MissingError(ManifestError):
|
||||
"""You specified a file that doesn't exist"""
|
||||
|
|
@ -143,6 +145,10 @@ ARGUMENTS=[
|
|||
default=None),
|
||||
dict(name='versionfile',
|
||||
description="""The name of a file containing the full version number."""),
|
||||
# <FS:Ansariel> Don't pass the bundle ID so we sign the Mac DMG file with the developer certificate
|
||||
#dict(name='bundleid',
|
||||
# description="""The Mac OS X Bundle identifier.""",
|
||||
# default="com.secondlife.indra.viewer"),
|
||||
dict(name='signature',
|
||||
description="""This specifies an identity to sign the viewer with, if any.
|
||||
If no value is supplied, the default signature will be used, if any. Currently
|
||||
|
|
@ -175,8 +181,6 @@ def main():
|
|||
option_names = [arg['name'] + '=' for arg in ARGUMENTS]
|
||||
option_names.append('help')
|
||||
|
||||
option_names.append('m64')
|
||||
|
||||
options, remainder = getopt.getopt(sys.argv[1:], "", option_names)
|
||||
|
||||
# convert options to a hash
|
||||
|
|
@ -312,8 +316,11 @@ def main():
|
|||
continue
|
||||
if touch:
|
||||
print 'Creating additional package for "', package_id, '" in ', args['dest']
|
||||
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
|
||||
wm.do(*args['actions'])
|
||||
try:
|
||||
wm = LLManifest.for_platform(args['platform'], args.get('arch'))(args)
|
||||
wm.do(*args['actions'])
|
||||
except Exception as err:
|
||||
sys.exit(str(err))
|
||||
if touch:
|
||||
print 'Created additional package ', wm.package_file, ' for ', package_id
|
||||
faketouch = base_touch_prefix + '/' + package_id + '/' + base_touch_postfix
|
||||
|
|
@ -374,12 +381,30 @@ class LLManifest(object):
|
|||
self.excludes.append(glob)
|
||||
|
||||
def prefix(self, src='', build=None, dst=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
|
||||
prefixes can be different, though if only one is provided they
|
||||
are both equal. To specify a no-op, use an empty string, not
|
||||
None."""
|
||||
"""
|
||||
Usage:
|
||||
|
||||
with self.prefix(...args as described...):
|
||||
self.path(...)
|
||||
|
||||
For the duration of the 'with' block, pushes a prefix onto the stack.
|
||||
Within that block, all relevant method calls (esp. to path()) will
|
||||
prefix paths with the entire prefix stack. Source and destination
|
||||
prefixes can be different, though if only one is provided they are
|
||||
both equal. To specify a no-op, use an empty string, not None.
|
||||
|
||||
Also supports the older (pre-Python-2.5) syntax:
|
||||
|
||||
if self.prefix(...args as described...):
|
||||
self.path(...)
|
||||
self.end_prefix(...)
|
||||
|
||||
Before the arrival of the 'with' statement, one was required to code
|
||||
self.prefix() and self.end_prefix() in matching pairs to push and to
|
||||
pop the prefix stacks, respectively. The older prefix() method
|
||||
returned True specifically so that the caller could indent the
|
||||
relevant block of code with 'if', just for aesthetic purposes.
|
||||
"""
|
||||
if dst is None:
|
||||
dst = src
|
||||
if build is None:
|
||||
|
|
@ -388,7 +413,57 @@ class LLManifest(object):
|
|||
self.artwork_prefix.append(src)
|
||||
self.build_prefix.append(build)
|
||||
self.dst_prefix.append(dst)
|
||||
return True # so that you can wrap it in an if to get indentation
|
||||
|
||||
# The above code is unchanged from the original implementation. What's
|
||||
# new is the return value. We're going to return an instance of
|
||||
# PrefixManager that binds this LLManifest instance and Does The Right
|
||||
# Thing on exit.
|
||||
return self.PrefixManager(self)
|
||||
|
||||
class PrefixManager(object):
|
||||
def __init__(self, manifest):
|
||||
self.manifest = manifest
|
||||
# stack attributes we manage in this LLManifest (sub)class
|
||||
# instance
|
||||
stacks = ("src_prefix", "artwork_prefix", "build_prefix", "dst_prefix")
|
||||
# If the caller wrote:
|
||||
# with self.prefix(...):
|
||||
# as intended, then bind the state of each prefix stack as it was
|
||||
# just BEFORE the call to prefix(). Since prefix() appended an
|
||||
# entry to each prefix stack, capture len()-1.
|
||||
self.prevlen = { stack: len(getattr(self.manifest, stack)) - 1
|
||||
for stack in stacks }
|
||||
|
||||
def __nonzero__(self):
|
||||
# If the caller wrote:
|
||||
# if self.prefix(...):
|
||||
# then a value of this class had better evaluate as 'True'.
|
||||
return True
|
||||
|
||||
def __enter__(self):
|
||||
# nobody uses 'with self.prefix(...) as variable:'
|
||||
return None
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
# First, if the 'with' block raised an exception, just propagate.
|
||||
# Do NOT swallow it.
|
||||
if type is not None:
|
||||
return False
|
||||
|
||||
# Okay, 'with' block completed successfully. Restore previous
|
||||
# state of each of the prefix stacks in self.stacks.
|
||||
# Note that we do NOT simply call pop() on them as end_prefix()
|
||||
# does. This is to cope with the possibility that the coder
|
||||
# changed 'if self.prefix(...):' to 'with self.prefix(...):' yet
|
||||
# forgot to remove the self.end_prefix(...) call at the bottom of
|
||||
# the block. In that case, calling pop() again would be Bad! But
|
||||
# if we restore the length of each stack to what it was before the
|
||||
# current prefix() block, it doesn't matter whether end_prefix()
|
||||
# was called or not.
|
||||
for stack, prevlen in self.prevlen.items():
|
||||
# find the attribute in 'self.manifest' named by 'stack', and
|
||||
# truncate that list back to 'prevlen'
|
||||
del getattr(self.manifest, stack)[prevlen:]
|
||||
|
||||
def end_prefix(self, descr=None):
|
||||
"""Pops a prefix off the stack. If given an argument, checks
|
||||
|
|
@ -452,29 +527,32 @@ class LLManifest(object):
|
|||
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
|
||||
output as it is received."""
|
||||
"""
|
||||
Runs an external command.
|
||||
Raises ManifestError exception if the command returns a nonzero status.
|
||||
"""
|
||||
print "Running command:", command
|
||||
sys.stdout.flush()
|
||||
child = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
shell=True)
|
||||
lines = []
|
||||
while True:
|
||||
lines.append(child.stdout.readline())
|
||||
if lines[-1] == '':
|
||||
break
|
||||
else:
|
||||
print lines[-1],
|
||||
output = ''.join(lines)
|
||||
child.stdout.close()
|
||||
status = child.wait()
|
||||
if status:
|
||||
raise ManifestError(
|
||||
"Command %s returned non-zero status (%s) \noutput:\n%s"
|
||||
% (command, status, output) )
|
||||
return output
|
||||
try:
|
||||
subprocess.check_call(command)
|
||||
except subprocess.CalledProcessError as err:
|
||||
raise ManifestError( "Command %s returned non-zero status (%s)"
|
||||
% (command, err.returncode) )
|
||||
|
||||
# <FS:Ansariel> Added for compatibility reasons
|
||||
def run_command_shell(self, command):
|
||||
"""
|
||||
Runs an external command.
|
||||
Raises ManifestError exception if the command returns a nonzero status.
|
||||
"""
|
||||
print "Running command:", command
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
subprocess.check_call(command, shell=True)
|
||||
except subprocess.CalledProcessError as err:
|
||||
raise ManifestError( "Command %s returned non-zero status (%s)"
|
||||
% (command, err.returncode) )
|
||||
# </FS:Ansariel>
|
||||
|
||||
def created_path(self, path):
|
||||
""" Declare that you've created a path in order to
|
||||
|
|
@ -487,6 +565,7 @@ class LLManifest(object):
|
|||
def put_in_file(self, contents, dst, src=None):
|
||||
# write contents as dst
|
||||
dst_path = self.dst_path_of(dst)
|
||||
self.cmakedirs(os.path.dirname(dst_path))
|
||||
f = open(dst_path, "wb")
|
||||
try:
|
||||
f.write(contents)
|
||||
|
|
@ -624,7 +703,7 @@ class LLManifest(object):
|
|||
if self.includes(src, dst):
|
||||
try:
|
||||
os.unlink(dst)
|
||||
except OSError, err:
|
||||
except OSError as err:
|
||||
if err.errno != errno.ENOENT:
|
||||
raise
|
||||
|
||||
|
|
@ -645,7 +724,7 @@ class LLManifest(object):
|
|||
dstname = os.path.join(dst, name)
|
||||
try:
|
||||
self.ccopymumble(srcname, dstname)
|
||||
except (IOError, os.error), why:
|
||||
except (IOError, os.error) as why:
|
||||
errors.append((srcname, dstname, why))
|
||||
if errors:
|
||||
raise ManifestError, errors
|
||||
|
|
|
|||
|
|
@ -2155,6 +2155,3 @@ LLAvatarAppearance::LLMaskedMorph::LLMaskedMorph(LLVisualParam *morph_target, BO
|
|||
target->addPendingMorphMask();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -267,4 +267,3 @@ LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIn
|
|||
{
|
||||
return getInstance()->getTexture(index)->mWearableType;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ include(Boost)
|
|||
include(LLSharedLibs)
|
||||
include(JsonCpp)
|
||||
include(GoogleBreakpad)
|
||||
include(GooglePerfTools)
|
||||
include(Copy3rdPartyLibs)
|
||||
include(ZLIB)
|
||||
include(URIPARSER)
|
||||
|
|
@ -227,6 +226,7 @@ set(llcommon_HEADER_FILES
|
|||
llstring.h
|
||||
llstringtable.h
|
||||
llstaticstringtable.h
|
||||
llstatsaccumulator.h
|
||||
llsys.h
|
||||
llthread.h
|
||||
llthreadlocalstorage.h
|
||||
|
|
@ -291,6 +291,13 @@ list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
|
|||
|
||||
if(LLCOMMON_LINK_SHARED)
|
||||
add_library (llcommon SHARED ${llcommon_SOURCE_FILES})
|
||||
if(NOT ADDRESS_SIZE EQUAL 32)
|
||||
if(WINDOWS)
|
||||
##add_definitions(/FIXED:NO)
|
||||
else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
|
||||
add_definitions(-fPIC)
|
||||
endif(WINDOWS)
|
||||
endif(NOT ADDRESS_SIZE EQUAL 32)
|
||||
if(WINDOWS)
|
||||
# always generate llcommon.pdb, even for "Release" builds
|
||||
set_target_properties(llcommon PROPERTIES LINK_FLAGS "/DEBUG")
|
||||
|
|
@ -386,8 +393,4 @@ if (LL_TESTS)
|
|||
## throwing and catching exceptions.
|
||||
##LL_ADD_INTEGRATION_TEST(llexception "" "${test_libs}")
|
||||
|
||||
# *TODO - reenable these once tcmalloc libs no longer break the build.
|
||||
#ADD_BUILD_TEST(llallocator llcommon)
|
||||
#ADD_BUILD_TEST(llallocator_heap_profile llcommon)
|
||||
#ADD_BUILD_TEST(llmemtype llcommon)
|
||||
endif (LL_TESTS)
|
||||
|
|
|
|||
|
|
@ -27,47 +27,6 @@
|
|||
#include "linden_common.h"
|
||||
#include "llallocator.h"
|
||||
|
||||
#if (LL_USE_TCMALLOC && LL_USE_HEAP_PROFILER)
|
||||
|
||||
#include "google/heap-profiler.h"
|
||||
#include "google/commandlineflags_public.h"
|
||||
|
||||
DECLARE_bool(heap_profile_use_stack_trace);
|
||||
//DECLARE_double(tcmalloc_release_rate);
|
||||
|
||||
void LLAllocator::setProfilingEnabled(bool should_enable)
|
||||
{
|
||||
// NULL disables dumping to disk
|
||||
static char const * const PREFIX = NULL;
|
||||
if(should_enable)
|
||||
{
|
||||
HeapProfilerSetUseStackTrace(false);
|
||||
HeapProfilerStart(PREFIX);
|
||||
}
|
||||
else
|
||||
{
|
||||
HeapProfilerStop();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLAllocator::isProfiling()
|
||||
{
|
||||
return IsHeapProfilerRunning();
|
||||
}
|
||||
|
||||
std::string LLAllocator::getRawProfile()
|
||||
{
|
||||
// *TODO - fix google-perftools to accept an buffer to avoid this
|
||||
// malloc-copy-free cycle.
|
||||
char * buffer = GetHeapProfile();
|
||||
std::string ret = buffer;
|
||||
free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else // LL_USE_TCMALLOC
|
||||
|
||||
//
|
||||
// stub implementations for when tcmalloc is disabled
|
||||
//
|
||||
|
|
@ -87,8 +46,6 @@ std::string LLAllocator::getRawProfile()
|
|||
return std::string();
|
||||
}
|
||||
|
||||
#endif // LL_USE_TCMALLOC
|
||||
|
||||
LLAllocatorHeapProfile const & LLAllocator::getProfile()
|
||||
{
|
||||
mProf.mLines.clear();
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ static LLTrace::ThreadRecorder* sMasterThreadRecorder = NULL;
|
|||
//static
|
||||
void LLCommon::initClass()
|
||||
{
|
||||
LLMemory::initClass();
|
||||
if (!sAprInitialized)
|
||||
{
|
||||
ll_init_apr();
|
||||
|
|
@ -70,5 +69,4 @@ void LLCommon::cleanupClass()
|
|||
ll_cleanup_apr();
|
||||
sAprInitialized = FALSE;
|
||||
}
|
||||
SUBSYSTEM_CLEANUP(LLMemory);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -155,7 +155,11 @@ LLCoros::LLCoros():
|
|||
// Previously we used
|
||||
// boost::context::guarded_stack_allocator::default_stacksize();
|
||||
// empirically this is 64KB on Windows and Linux. Try quadrupling.
|
||||
#if ADDRESS_SIZE == 64
|
||||
mStackSize(512*1024)
|
||||
#else
|
||||
mStackSize(256*1024)
|
||||
#endif
|
||||
{
|
||||
// Register our cleanup() method for "mainloop" ticks
|
||||
LLEventPumps::instance().obtain("mainloop").listen(
|
||||
|
|
|
|||
|
|
@ -124,8 +124,8 @@ public:
|
|||
virtual std::string describe(bool full=true) const;
|
||||
|
||||
protected:
|
||||
typedef std::vector< std::pair<int, int> > EdgeList;
|
||||
typedef std::vector<int> VertexList;
|
||||
typedef std::vector< std::pair<std::size_t, std::size_t> > EdgeList;
|
||||
typedef std::vector<std::size_t> VertexList;
|
||||
VertexList topo_sort(int vertices, const EdgeList& edges) const;
|
||||
|
||||
/**
|
||||
|
|
@ -508,7 +508,7 @@ public:
|
|||
// been explicitly added. Rely on std::map rejecting a second attempt
|
||||
// to insert the same key. Use the map's size() as the vertex number
|
||||
// to get a distinct value for each successful insertion.
|
||||
typedef std::map<KEY, int> VertexMap;
|
||||
typedef std::map<KEY, std::size_t> VertexMap;
|
||||
VertexMap vmap;
|
||||
// Nest each of these loops because !@#$%? MSVC warns us that its
|
||||
// former broken behavior has finally been fixed -- and our builds
|
||||
|
|
|
|||
|
|
@ -47,13 +47,13 @@
|
|||
// namespace) that a global 'nil' macro breaks badly.
|
||||
#if defined(nil)
|
||||
// Capture the value of the macro 'nil', hoping int is an appropriate type.
|
||||
static const int nil_(nil);
|
||||
static const auto nil_(nil);
|
||||
// Now forget the macro.
|
||||
#undef nil
|
||||
// Finally, reintroduce 'nil' as a properly-scoped alias for the previously-
|
||||
// defined const 'nil_'. Make it static since otherwise it produces duplicate-
|
||||
// symbol link errors later.
|
||||
static const int& nil(nil_);
|
||||
static const auto& nil(nil_);
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
|
|
|||
|
|
@ -282,7 +282,8 @@ const std::string LLEventPump::ANONYMOUS = std::string();
|
|||
|
||||
LLEventPump::LLEventPump(const std::string& name, bool tweak):
|
||||
// Register every new instance with LLEventPumps
|
||||
mName(LLEventPumps::instance().registerNew(*this, name, tweak)),
|
||||
mRegistry(LLEventPumps::instance().getHandle()),
|
||||
mName(mRegistry.get()->registerNew(*this, name, tweak)),
|
||||
mSignal(new LLStandardSignal()),
|
||||
mEnabled(true)
|
||||
{}
|
||||
|
|
@ -293,8 +294,13 @@ LLEventPump::LLEventPump(const std::string& name, bool tweak):
|
|||
|
||||
LLEventPump::~LLEventPump()
|
||||
{
|
||||
// Unregister this doomed instance from LLEventPumps
|
||||
LLEventPumps::instance().unregister(*this);
|
||||
// Unregister this doomed instance from LLEventPumps -- but only if
|
||||
// LLEventPumps is still around!
|
||||
LLEventPumps* registry = mRegistry.get();
|
||||
if (registry)
|
||||
{
|
||||
registry->unregister(*this);
|
||||
}
|
||||
}
|
||||
|
||||
// static data member
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@
|
|||
#include "lldependencies.h"
|
||||
#include "llstl.h"
|
||||
#include "llexception.h"
|
||||
#include "llhandle.h"
|
||||
|
||||
/*==========================================================================*|
|
||||
// override this to allow binding free functions with more parameters
|
||||
|
|
@ -227,7 +228,15 @@ class LLEventPump;
|
|||
* LLEventPumps is a Singleton manager through which one typically accesses
|
||||
* this subsystem.
|
||||
*/
|
||||
class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps>
|
||||
// LLEventPumps isa LLHandleProvider only for (hopefully rare) long-lived
|
||||
// class objects that must refer to this class late in their lifespan, say in
|
||||
// the destructor. Specifically, the case that matters is a possible reference
|
||||
// after LLEventPumps::deleteSingleton(). (Lingering LLEventPump instances are
|
||||
// capable of this.) In that case, instead of calling LLEventPumps::instance()
|
||||
// again -- resurrecting the deleted LLSingleton -- store an
|
||||
// LLHandle<LLEventPumps> and test it before use.
|
||||
class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps>,
|
||||
public LLHandleProvider<LLEventPumps>
|
||||
{
|
||||
LLSINGLETON(LLEventPumps);
|
||||
public:
|
||||
|
|
@ -590,6 +599,9 @@ private:
|
|||
return this->listen_impl(name, listener, after, before);
|
||||
}
|
||||
|
||||
// must precede mName; see LLEventPump::LLEventPump()
|
||||
LLHandle<LLEventPumps> mRegistry;
|
||||
|
||||
std::string mName;
|
||||
|
||||
protected:
|
||||
|
|
@ -817,14 +829,14 @@ public:
|
|||
mConnection(new LLBoundListener)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/// Copy constructor. Copy shared_ptrs to original instance data.
|
||||
LLListenerWrapperBase(const LLListenerWrapperBase& that):
|
||||
mName(that.mName),
|
||||
mConnection(that.mConnection)
|
||||
{
|
||||
}
|
||||
virtual ~LLListenerWrapperBase() {}
|
||||
virtual ~LLListenerWrapperBase() {}
|
||||
|
||||
/// Ask LLEventPump::listen() for the listener name
|
||||
virtual void accept_name(const std::string& name) const
|
||||
|
|
|
|||
|
|
@ -89,43 +89,15 @@ public:
|
|||
#if LL_FASTTIMER_USE_RDTSC
|
||||
static U32 getCPUClockCount32()
|
||||
{
|
||||
U32 ret_val;
|
||||
#if !defined(ND_BUILD64BIT_ARCH)
|
||||
__asm
|
||||
{
|
||||
_emit 0x0f
|
||||
_emit 0x31
|
||||
shr eax,8
|
||||
shl edx,24
|
||||
or eax, edx
|
||||
mov dword ptr [ret_val], eax
|
||||
}
|
||||
#else
|
||||
unsigned __int64 val = __rdtsc();
|
||||
val = val >> 8;
|
||||
ret_val = static_cast<U32>( val );
|
||||
#endif
|
||||
return ret_val;
|
||||
return static_cast<U32>(val);
|
||||
}
|
||||
|
||||
// return full timer value, *not* shifted by 8 bits
|
||||
static U64 getCPUClockCount64()
|
||||
{
|
||||
U64 ret_val;
|
||||
#if !defined(ND_BUILD64BIT_ARCH)
|
||||
__asm
|
||||
{
|
||||
_emit 0x0f
|
||||
_emit 0x31
|
||||
mov eax,eax
|
||||
mov edx,edx
|
||||
mov dword ptr [ret_val+4], edx
|
||||
mov dword ptr [ret_val], eax
|
||||
}
|
||||
#else
|
||||
ret_val = static_cast<U64>( __rdtsc() );
|
||||
#endif
|
||||
return ret_val;
|
||||
return static_cast<U64>( __rdtsc() );
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
@ -188,32 +160,16 @@ public:
|
|||
// Mac+Linux+Solaris FAST x86 implementation of CPU clock
|
||||
static U32 getCPUClockCount32()
|
||||
{
|
||||
// <FS:ND> Proper RDTSC timings for Linux/Mac
|
||||
|
||||
// U64 x;
|
||||
// __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
|
||||
// return (U32)(x >> 8);
|
||||
|
||||
U32 low(0),high(0);
|
||||
__asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) );
|
||||
return (low>>8) | (high<<24);
|
||||
|
||||
// </FS:ND>
|
||||
}
|
||||
|
||||
static U64 getCPUClockCount64()
|
||||
{
|
||||
// <FS:ND> Proper RDTSC timings for Linux/Mac
|
||||
|
||||
// U64 x;
|
||||
// __asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
|
||||
// return x;
|
||||
|
||||
U32 low(0),high(0);
|
||||
__asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) );
|
||||
return (U64)low | ( ((U64)high) << 32);
|
||||
|
||||
// </FS:ND>
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -182,7 +182,14 @@ int LLFile::mkdir(const std::string& dirname, int perms)
|
|||
int rc = ::mkdir(dirname.c_str(), (mode_t)perms);
|
||||
#endif
|
||||
// We often use mkdir() to ensure the existence of a directory that might
|
||||
// already exist. Don't spam the log if it does.
|
||||
// already exist. There is no known case in which we want to call out as
|
||||
// an error the requested directory already existing.
|
||||
if (rc < 0 && errno == EEXIST)
|
||||
{
|
||||
// this is not the error you want, move along
|
||||
return 0;
|
||||
}
|
||||
// anything else might be a problem
|
||||
return warnif("mkdir", dirname, rc, EEXIST);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,10 +45,7 @@ typedef FILE LLFILE;
|
|||
typedef struct _stat llstat;
|
||||
#else
|
||||
typedef struct stat llstat;
|
||||
//<FS:TS> This file only exists on Linux
|
||||
# if LL_LINUX
|
||||
# include <bits/postypes.h>
|
||||
# endif
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifndef S_ISREG
|
||||
|
|
@ -72,6 +69,7 @@ public:
|
|||
|
||||
// perms is a permissions mask like 0777 or 0700. In most cases it will
|
||||
// be overridden by the user's umask. It is ignored on Windows.
|
||||
// mkdir() considers "directory already exists" to be SUCCESS.
|
||||
static int mkdir(const std::string& filename, int perms = 0700);
|
||||
|
||||
static int rmdir(const std::string& filename);
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#define LLHANDLE_H
|
||||
|
||||
#include "llpointer.h"
|
||||
#include "llrefcount.h"
|
||||
#include "llexception.h"
|
||||
#include <stdexcept>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,56 @@
|
|||
#endif
|
||||
// </FS:CR>
|
||||
|
||||
// As of 2017-05-06, as far as nat knows, only clang supports __has_feature().
|
||||
// Unfortunately VS2013's preprocessor shortcut logic doesn't prevent it from
|
||||
// producing (fatal) warnings for defined(__clang__) && __has_feature(...).
|
||||
// Have to work around that.
|
||||
#if ! defined(__clang__)
|
||||
#define __has_feature(x) 0
|
||||
#endif // __clang__
|
||||
|
||||
#if defined(LL_TEST_llinstancetracker) && __has_feature(cxx_noexcept)
|
||||
// ~LLInstanceTracker() performs llassert_always() validation. That's fine in
|
||||
// production code, since the llassert_always() is implemented as an LL_ERRS
|
||||
// message, which will crash-with-message. In our integration test executable,
|
||||
// though, this llassert_always() throws an exception instead so we can test
|
||||
// error conditions and continue running the test. However -- as of C++11,
|
||||
// destructors are implicitly noexcept(true). Unless we mark
|
||||
// ~LLInstanceTracker() noexcept(false), the test executable crashes even on
|
||||
// the ATTEMPT to throw.
|
||||
#define LLINSTANCETRACKER_DTOR_NOEXCEPT noexcept(false)
|
||||
#else
|
||||
// If we're building for production, or in fact building *any other* test, or
|
||||
// we're using a compiler that doesn't support __has_feature(), or we're not
|
||||
// compiling with a C++ version that supports noexcept -- don't specify it.
|
||||
#define LLINSTANCETRACKER_DTOR_NOEXCEPT
|
||||
#endif
|
||||
|
||||
// As of 2017-05-06, as far as nat knows, only clang supports __has_feature().
|
||||
// Unfortunately VS2013's preprocessor shortcut logic doesn't prevent it from
|
||||
// producing (fatal) warnings for defined(__clang__) && __has_feature(...).
|
||||
// Have to work around that.
|
||||
#if ! defined(__clang__)
|
||||
#define __has_feature(x) 0
|
||||
#endif // __clang__
|
||||
|
||||
#if defined(LL_TEST_llinstancetracker) && __has_feature(cxx_noexcept)
|
||||
// ~LLInstanceTracker() performs llassert_always() validation. That's fine in
|
||||
// production code, since the llassert_always() is implemented as an LL_ERRS
|
||||
// message, which will crash-with-message. In our integration test executable,
|
||||
// though, this llassert_always() throws an exception instead so we can test
|
||||
// error conditions and continue running the test. However -- as of C++11,
|
||||
// destructors are implicitly noexcept(true). Unless we mark
|
||||
// ~LLInstanceTracker() noexcept(false), the test executable crashes even on
|
||||
// the ATTEMPT to throw.
|
||||
#define LLINSTANCETRACKER_DTOR_NOEXCEPT noexcept(false)
|
||||
#else
|
||||
// If we're building for production, or in fact building *any other* test, or
|
||||
// we're using a compiler that doesn't support __has_feature(), or we're not
|
||||
// compiling with a C++ version that supports noexcept -- don't specify it.
|
||||
#define LLINSTANCETRACKER_DTOR_NOEXCEPT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Base class manages "class-static" data that must actually have singleton
|
||||
* semantics: one instance per process, rather than one instance per module as
|
||||
|
|
@ -232,7 +282,7 @@ protected:
|
|||
getStatic();
|
||||
add_(key);
|
||||
}
|
||||
virtual ~LLInstanceTracker()
|
||||
virtual ~LLInstanceTracker() LLINSTANCETRACKER_DTOR_NOEXCEPT
|
||||
{
|
||||
// it's unsafe to delete instances of this type while all instances are being iterated over.
|
||||
|
||||
|
|
@ -242,7 +292,7 @@ protected:
|
|||
#endif
|
||||
// </FS:ND>
|
||||
|
||||
remove_();
|
||||
remove_();
|
||||
}
|
||||
virtual void setKey(KEY key) { remove_(); add_(key); }
|
||||
virtual const KEY& getKey() const { return mInstanceKey; }
|
||||
|
|
@ -387,7 +437,7 @@ protected:
|
|||
getStatic();
|
||||
getSet_().insert(static_cast<T*>(this));
|
||||
}
|
||||
virtual ~LLInstanceTracker()
|
||||
virtual ~LLInstanceTracker() LLINSTANCETRACKER_DTOR_NOEXCEPT
|
||||
{
|
||||
// it's unsafe to delete instances of this type while all instances are being iterated over.
|
||||
|
||||
|
|
|
|||
|
|
@ -12,12 +12,10 @@
|
|||
*
|
||||
* also relevant:
|
||||
*
|
||||
* Template parameter deduction for constructors
|
||||
* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0091r0.html
|
||||
*
|
||||
* https://github.com/viboes/std-make
|
||||
*
|
||||
* but obviously we're not there yet.
|
||||
* Template argument deduction for class templates
|
||||
* http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0091r3.html
|
||||
* was apparently adopted in June 2016? Unclear when compilers will
|
||||
* portably support this, but there is hope.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2015&license=viewerlgpl$
|
||||
* Copyright (c) 2015, Linden Research, Inc.
|
||||
|
|
|
|||
|
|
@ -44,11 +44,10 @@
|
|||
#include "llsys.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lltrace.h"
|
||||
|
||||
#include "llerror.h"
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//static
|
||||
char* LLMemory::reserveMem = 0;
|
||||
U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX);
|
||||
U32Kilobytes LLMemory::sMaxPhysicalMemInKB(0);
|
||||
static LLTrace::SampleStatHandle<F64Megabytes> sAllocatedMem("allocated_mem", "active memory in use by application");
|
||||
|
|
@ -79,29 +78,6 @@ void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
|
|||
#endif
|
||||
}
|
||||
|
||||
//static
|
||||
void LLMemory::initClass()
|
||||
{
|
||||
if (!reserveMem)
|
||||
{
|
||||
reserveMem = new char[16*1024]; // reserve 16K for out of memory error handling
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLMemory::cleanupClass()
|
||||
{
|
||||
delete [] reserveMem;
|
||||
reserveMem = NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLMemory::freeReserve()
|
||||
{
|
||||
delete [] reserveMem;
|
||||
reserveMem = NULL;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure)
|
||||
{
|
||||
|
|
@ -112,19 +88,18 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_f
|
|||
//static
|
||||
void LLMemory::updateMemoryInfo()
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
HANDLE self = GetCurrentProcess();
|
||||
#if LL_WINDOWS
|
||||
PROCESS_MEMORY_COUNTERS counters;
|
||||
|
||||
if (!GetProcessMemoryInfo(self, &counters, sizeof(counters)))
|
||||
|
||||
if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
|
||||
{
|
||||
LL_WARNS() << "GetProcessMemoryInfo failed" << LL_ENDL;
|
||||
return ;
|
||||
}
|
||||
|
||||
sAllocatedMemInKB = (U32Bytes)(counters.WorkingSetSize) ;
|
||||
sAllocatedMemInKB = U64Bytes(counters.WorkingSetSize) ;
|
||||
sample(sAllocatedMem, sAllocatedMemInKB);
|
||||
sAllocatedPageSizeInKB = (U32Bytes)(counters.PagefileUsage) ;
|
||||
sAllocatedPageSizeInKB = U64Bytes(counters.PagefileUsage) ;
|
||||
sample(sVirtualMem, sAllocatedPageSizeInKB);
|
||||
|
||||
U32Kilobytes avail_phys, avail_virtual;
|
||||
|
|
@ -141,9 +116,9 @@ void LLMemory::updateMemoryInfo()
|
|||
}
|
||||
#else
|
||||
//not valid for other systems for now.
|
||||
sAllocatedMemInKB = (U32Bytes)LLMemory::getCurrentRSS();
|
||||
sMaxPhysicalMemInKB = (U32Bytes)U32_MAX ;
|
||||
sAvailPhysicalMemInKB = (U32Bytes)U32_MAX ;
|
||||
sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS());
|
||||
sMaxPhysicalMemInKB = U64Bytes(U32_MAX);
|
||||
sAvailPhysicalMemInKB = U64Bytes(U32_MAX);
|
||||
#endif
|
||||
|
||||
return ;
|
||||
|
|
@ -170,7 +145,7 @@ void* LLMemory::tryToAlloc(void* address, U32 size)
|
|||
return address ;
|
||||
#else
|
||||
return (void*)0x01 ; //skip checking
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
//static
|
||||
|
|
@ -184,7 +159,7 @@ void LLMemory::logMemoryInfo(BOOL update)
|
|||
|
||||
LL_INFOS() << "Current allocated physical memory(KB): " << sAllocatedMemInKB << LL_ENDL ;
|
||||
LL_INFOS() << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << LL_ENDL ;
|
||||
LL_INFOS() << "Current availabe physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;
|
||||
LL_INFOS() << "Current available physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;
|
||||
LL_INFOS() << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << LL_ENDL ;
|
||||
|
||||
LL_INFOS() << "--- private pool information -- " << LL_ENDL ;
|
||||
|
|
@ -264,12 +239,12 @@ U32Kilobytes LLMemory::getAllocatedMemKB()
|
|||
|
||||
#if defined(LL_WINDOWS)
|
||||
|
||||
//static
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
{
|
||||
HANDLE self = GetCurrentProcess();
|
||||
PROCESS_MEMORY_COUNTERS counters;
|
||||
|
||||
if (!GetProcessMemoryInfo(self, &counters, sizeof(counters)))
|
||||
|
||||
if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
|
||||
{
|
||||
LL_WARNS() << "GetProcessMemoryInfo failed" << LL_ENDL;
|
||||
return 0;
|
||||
|
|
@ -278,35 +253,8 @@ U64 LLMemory::getCurrentRSS()
|
|||
return counters.WorkingSetSize;
|
||||
}
|
||||
|
||||
//static
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
PROCESS_MEMORY_COUNTERS pmc ;
|
||||
U32 ret = 0 ;
|
||||
|
||||
if (GetProcessMemoryInfo( GetCurrentProcess(), &pmc, sizeof(pmc)) )
|
||||
{
|
||||
ret = pmc.WorkingSetSize ;
|
||||
}
|
||||
|
||||
return ret ;
|
||||
}
|
||||
|
||||
#elif defined(LL_DARWIN)
|
||||
|
||||
/*
|
||||
The API used here is not capable of dealing with 64-bit memory sizes, but is available before 10.4.
|
||||
|
||||
Once we start requiring 10.4, we can use the updated API, which looks like this:
|
||||
|
||||
task_basic_info_64_data_t basicInfo;
|
||||
mach_msg_type_number_t basicInfoCount = TASK_BASIC_INFO_64_COUNT;
|
||||
if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
|
||||
|
||||
Of course, this doesn't gain us anything unless we start building the viewer as a 64-bit executable, since that's the only way
|
||||
for our memory allocation to exceed 2^32.
|
||||
*/
|
||||
|
||||
// if (sysctl(ctl, 2, &page_size, &size, NULL, 0) == -1)
|
||||
// {
|
||||
// LL_WARNS() << "Couldn't get page size" << LL_ENDL;
|
||||
|
|
@ -319,16 +267,15 @@ U32 LLMemory::getWorkingSetSize()
|
|||
U64 LLMemory::getCurrentRSS()
|
||||
{
|
||||
U64 residentSize = 0;
|
||||
task_basic_info_data_t basicInfo;
|
||||
mach_msg_type_number_t basicInfoCount = TASK_BASIC_INFO_COUNT;
|
||||
if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
|
||||
mach_task_basic_info_data_t basicInfo;
|
||||
mach_msg_type_number_t basicInfoCount = MACH_TASK_BASIC_INFO_COUNT;
|
||||
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
|
||||
{
|
||||
residentSize = basicInfo.resident_size;
|
||||
|
||||
// If we ever wanted it, the process virtual size is also available as:
|
||||
// virtualSize = basicInfo.virtual_size;
|
||||
|
||||
// LL_INFOS() << "resident size is " << residentSize << LL_ENDL;
|
||||
// residentSize = basicInfo.resident_size;
|
||||
// Although this method is defined to return the "resident set size,"
|
||||
// in fact what callers want from it is the total virtual memory
|
||||
// consumed by the application.
|
||||
residentSize = basicInfo.virtual_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -338,11 +285,6 @@ U64 LLMemory::getCurrentRSS()
|
|||
return residentSize;
|
||||
}
|
||||
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#elif defined(LL_LINUX)
|
||||
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
|
|
@ -354,7 +296,7 @@ U64 LLMemory::getCurrentRSS()
|
|||
if (fp == NULL)
|
||||
{
|
||||
LL_WARNS() << "couldn't open " << statPath << LL_ENDL;
|
||||
goto bail;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Eee-yew! See Documentation/filesystems/proc.txt in your
|
||||
|
|
@ -373,15 +315,9 @@ U64 LLMemory::getCurrentRSS()
|
|||
|
||||
fclose(fp);
|
||||
|
||||
bail:
|
||||
return rss;
|
||||
}
|
||||
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#elif LL_SOLARIS
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
|
@ -411,11 +347,6 @@ U64 LLMemory::getCurrentRSS()
|
|||
return((U64)proc_psinfo.pr_rssize * 1024);
|
||||
}
|
||||
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
U64 LLMemory::getCurrentRSS()
|
||||
|
|
@ -423,11 +354,6 @@ U64 LLMemory::getCurrentRSS()
|
|||
return 0;
|
||||
}
|
||||
|
||||
U32 LLMemory::getWorkingSetSize()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
|
@ -592,12 +518,7 @@ char* LLPrivateMemoryPool::LLMemoryBlock::allocate()
|
|||
void LLPrivateMemoryPool::LLMemoryBlock::freeMem(void* addr)
|
||||
{
|
||||
//bit index
|
||||
// U32 idx = ((U32)addr - (U32)mBuffer - mDummySize) / mSlotSize ;
|
||||
// <FS:ND> 64 bit fix
|
||||
unsigned char *p1 = reinterpret_cast<unsigned char*>(addr);
|
||||
unsigned char *p2 = reinterpret_cast<unsigned char*>(mBuffer);
|
||||
U32 idx = ( p1 - p2 - mDummySize) / mSlotSize ;
|
||||
// </FS:ND>
|
||||
uintptr_t idx = ((uintptr_t)addr - (uintptr_t)mBuffer - mDummySize) / mSlotSize ;
|
||||
|
||||
U32* bits = &mUsageBits ;
|
||||
if(idx >= 32)
|
||||
|
|
@ -779,7 +700,7 @@ char* LLPrivateMemoryPool::LLMemoryChunk::allocate(U32 size)
|
|||
|
||||
void LLPrivateMemoryPool::LLMemoryChunk::freeMem(void* addr)
|
||||
{
|
||||
U32 blk_idx = getPageIndex(/*<ND/> 64 bit fix (U32)*/addr) ;
|
||||
U32 blk_idx = getPageIndex((uintptr_t)addr) ;
|
||||
LLMemoryBlock* blk = (LLMemoryBlock*)(mMetaBuffer + blk_idx * sizeof(LLMemoryBlock)) ;
|
||||
blk = blk->mSelf ;
|
||||
|
||||
|
|
@ -804,13 +725,7 @@ bool LLPrivateMemoryPool::LLMemoryChunk::empty()
|
|||
|
||||
bool LLPrivateMemoryPool::LLMemoryChunk::containsAddress(const char* addr) const
|
||||
{
|
||||
//return (U32)mBuffer <= (U32)addr && (U32)mBuffer + mBufferSize > (U32)addr ;
|
||||
// <FS:ND> 64 bit fix
|
||||
unsigned char const *pBuffer = reinterpret_cast<unsigned char const*>( mBuffer );
|
||||
unsigned char const *pAddr = reinterpret_cast<unsigned char const*>( addr );
|
||||
|
||||
return pBuffer <= pAddr && pBuffer + mBufferSize > pAddr ;
|
||||
// </FS:ND>
|
||||
return (uintptr_t)mBuffer <= (uintptr_t)addr && (uintptr_t)mBuffer + mBufferSize > (uintptr_t)addr ;
|
||||
}
|
||||
|
||||
//debug use
|
||||
|
|
@ -843,13 +758,13 @@ void LLPrivateMemoryPool::LLMemoryChunk::dump()
|
|||
for(U32 i = 1 ; i < blk_list.size(); i++)
|
||||
{
|
||||
total_size += blk_list[i]->getBufferSize() ;
|
||||
if((U32)blk_list[i]->getBuffer() < (U32)blk_list[i-1]->getBuffer() + blk_list[i-1]->getBufferSize())
|
||||
if((uintptr_t)blk_list[i]->getBuffer() < (uintptr_t)blk_list[i-1]->getBuffer() + blk_list[i-1]->getBufferSize())
|
||||
{
|
||||
LL_ERRS() << "buffer corrupted." << LL_ENDL ;
|
||||
}
|
||||
}
|
||||
|
||||
llassert_always(total_size + mMinBlockSize >= mBufferSize - ((U32)mDataBuffer - (U32)mBuffer)) ;
|
||||
llassert_always(total_size + mMinBlockSize >= mBufferSize - ((uintptr_t)mDataBuffer - (uintptr_t)mBuffer)) ;
|
||||
|
||||
U32 blk_num = (mBufferSize - (mDataBuffer - mBuffer)) / mMinBlockSize ;
|
||||
for(U32 i = 0 ; i < blk_num ; )
|
||||
|
|
@ -872,7 +787,7 @@ void LLPrivateMemoryPool::LLMemoryChunk::dump()
|
|||
#endif
|
||||
#if 0
|
||||
LL_INFOS() << "---------------------------" << LL_ENDL ;
|
||||
LL_INFOS() << "Chunk buffer: " << (U32)getBuffer() << " size: " << getBufferSize() << LL_ENDL ;
|
||||
LL_INFOS() << "Chunk buffer: " << (uintptr_t)getBuffer() << " size: " << getBufferSize() << LL_ENDL ;
|
||||
|
||||
LL_INFOS() << "available blocks ... " << LL_ENDL ;
|
||||
for(S32 i = 0 ; i < mBlockLevels ; i++)
|
||||
|
|
@ -880,7 +795,7 @@ void LLPrivateMemoryPool::LLMemoryChunk::dump()
|
|||
LLMemoryBlock* blk = mAvailBlockList[i] ;
|
||||
while(blk)
|
||||
{
|
||||
LL_INFOS() << "blk buffer " << (U32)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ;
|
||||
LL_INFOS() << "blk buffer " << (uintptr_t)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ;
|
||||
blk = blk->mNext ;
|
||||
}
|
||||
}
|
||||
|
|
@ -891,7 +806,7 @@ void LLPrivateMemoryPool::LLMemoryChunk::dump()
|
|||
LLMemoryBlock* blk = mFreeSpaceList[i] ;
|
||||
while(blk)
|
||||
{
|
||||
LL_INFOS() << "blk buffer " << (U32)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ;
|
||||
LL_INFOS() << "blk buffer " << (uintptr_t)blk->getBuffer() << " size: " << blk->getBufferSize() << LL_ENDL ;
|
||||
blk = blk->mNext ;
|
||||
}
|
||||
}
|
||||
|
|
@ -1167,16 +1082,9 @@ void LLPrivateMemoryPool::LLMemoryChunk::addToAvailBlockList(LLMemoryBlock* blk)
|
|||
return ;
|
||||
}
|
||||
|
||||
//U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(U32 addr)
|
||||
U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(void * addr) // <ND/> 64 bit fix
|
||||
U32 LLPrivateMemoryPool::LLMemoryChunk::getPageIndex(uintptr_t addr)
|
||||
{
|
||||
// return (addr - (U32)mDataBuffer) / mMinBlockSize ;
|
||||
// <FS:ND> 64 bit fix
|
||||
unsigned char *pAddr = reinterpret_cast< unsigned char* >( addr );
|
||||
unsigned char *pBuffer = reinterpret_cast< unsigned char* >( mDataBuffer );
|
||||
|
||||
return (pAddr - pBuffer) / mMinBlockSize ;
|
||||
// </FS:ND>
|
||||
return (addr - (uintptr_t)mDataBuffer) / mMinBlockSize ;
|
||||
}
|
||||
|
||||
//for mAvailBlockList
|
||||
|
|
@ -1514,13 +1422,7 @@ void LLPrivateMemoryPool::removeChunk(LLMemoryChunk* chunk)
|
|||
|
||||
U16 LLPrivateMemoryPool::findHashKey(const char* addr)
|
||||
{
|
||||
// return (((U32)addr) / CHUNK_SIZE) % mHashFactor ;
|
||||
// <FS:ND> 64 bit fix
|
||||
unsigned char const *pAddr = reinterpret_cast< unsigned char const *>( addr );
|
||||
U64 nAddr = reinterpret_cast<U64>(pAddr);
|
||||
|
||||
return ( nAddr / CHUNK_SIZE) % mHashFactor ;
|
||||
// </FS:ND>
|
||||
return (((uintptr_t)addr) / CHUNK_SIZE) % mHashFactor ;
|
||||
}
|
||||
|
||||
LLPrivateMemoryPool::LLMemoryChunk* LLPrivateMemoryPool::findChunk(const char* addr)
|
||||
|
|
@ -1745,7 +1647,7 @@ LLPrivateMemoryPoolManager::~LLPrivateMemoryPoolManager()
|
|||
S32 k = 0 ;
|
||||
for(mem_allocation_info_t::iterator iter = sMemAllocationTracker.begin() ; iter != sMemAllocationTracker.end() ; ++iter)
|
||||
{
|
||||
LL_INFOS() << k++ << ", " << (U32)iter->first << " : " << iter->second << LL_ENDL ;
|
||||
LL_INFOS() << k++ << ", " << (uintptr_t)iter->first << " : " << iter->second << LL_ENDL ;
|
||||
}
|
||||
sMemAllocationTracker.clear() ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ template <typename T> T* LL_NEXT_ALIGNED_ADDRESS_64(T* address)
|
|||
//------------------------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
#if !LL_USE_TCMALLOC
|
||||
inline void* ll_aligned_malloc_16(size_t size) // returned hunk MUST be freed with ll_aligned_free_16().
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
|
|
@ -187,13 +186,6 @@ inline void* ll_aligned_realloc_16(void* ptr, size_t size, size_t old_size) // r
|
|||
#endif
|
||||
}
|
||||
|
||||
#else // USE_TCMALLOC
|
||||
// ll_aligned_foo_16 are not needed with tcmalloc
|
||||
#define ll_aligned_malloc_16 malloc
|
||||
#define ll_aligned_realloc_16(a,b,c) realloc(a,b)
|
||||
#define ll_aligned_free_16 free
|
||||
#endif // USE_TCMALLOC
|
||||
|
||||
inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
|
||||
{
|
||||
#if defined(LL_WINDOWS)
|
||||
|
|
@ -354,13 +346,9 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __
|
|||
class LL_COMMON_API LLMemory
|
||||
{
|
||||
public:
|
||||
static void initClass();
|
||||
static void cleanupClass();
|
||||
static void freeReserve();
|
||||
// Return the resident set size of the current process, in bytes.
|
||||
// Return value is zero if not known.
|
||||
static U64 getCurrentRSS();
|
||||
static U32 getWorkingSetSize();
|
||||
static void* tryToAlloc(void* address, U32 size);
|
||||
static void initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure);
|
||||
static void updateMemoryInfo() ;
|
||||
|
|
@ -371,7 +359,6 @@ public:
|
|||
static U32Kilobytes getMaxMemKB() ;
|
||||
static U32Kilobytes getAllocatedMemKB() ;
|
||||
private:
|
||||
static char* reserveMem;
|
||||
static U32Kilobytes sAvailPhysicalMemInKB ;
|
||||
static U32Kilobytes sMaxPhysicalMemInKB ;
|
||||
static U32Kilobytes sAllocatedMemInKB;
|
||||
|
|
@ -435,9 +422,7 @@ public:
|
|||
{
|
||||
bool operator()(const LLMemoryBlock* const& lhs, const LLMemoryBlock* const& rhs)
|
||||
{
|
||||
//return (U32)lhs->getBuffer() < (U32)rhs->getBuffer();
|
||||
//<ND/> 64 bit fix
|
||||
return reinterpret_cast<unsigned char*>(lhs->getBuffer()) < reinterpret_cast<unsigned char*>(rhs->getBuffer());
|
||||
return (uintptr_t)lhs->getBuffer() < (uintptr_t)rhs->getBuffer();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
@ -468,8 +453,7 @@ public:
|
|||
void dump() ;
|
||||
|
||||
private:
|
||||
// U32 getPageIndex(U32 addr) ;
|
||||
U32 getPageIndex(void* addr) ; // <ND/> 64 bit fix
|
||||
U32 getPageIndex(uintptr_t addr) ;
|
||||
U32 getBlockLevel(U32 size) ;
|
||||
U16 getPageLevel(U32 size) ;
|
||||
LLMemoryBlock* addBlock(U32 blk_idx) ;
|
||||
|
|
|
|||
|
|
@ -148,6 +148,12 @@
|
|||
#pragma warning( 3 : 4266 ) // 'function' : no override available for virtual member function from base 'type'; function is hidden
|
||||
#pragma warning (disable : 4180) // qualifier applied to function type has no meaning; ignored
|
||||
//#pragma warning( disable : 4284 ) // silly MS warning deep inside their <map> include file
|
||||
|
||||
#if ADDRESS_SIZE == 64
|
||||
// That one is all over the place for x64 builds.
|
||||
#pragma warning( disable : 4267 ) // 'var' : conversion from 'size_t' to 'type', possible loss of data)
|
||||
#endif
|
||||
|
||||
#pragma warning( disable : 4503 ) // 'decorated name length exceeded, name was truncated'. Does not seem to affect compilation.
|
||||
#pragma warning( disable : 4800 ) // 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
|
||||
#pragma warning( disable : 4996 ) // warning: deprecated
|
||||
|
|
@ -196,13 +202,9 @@
|
|||
# define LL_COMMON_API
|
||||
#endif // LL_COMMON_LINK_SHARED
|
||||
|
||||
#if LL_WINDOWS
|
||||
#define LL_TYPEOF(exp) decltype(exp)
|
||||
#elif LL_LINUX
|
||||
#define LL_TYPEOF(exp) typeof(exp)
|
||||
#elif LL_DARWIN
|
||||
#define LL_TYPEOF(exp) decltype(exp)
|
||||
#endif
|
||||
// With C++11, decltype() is standard. We no longer need a platform-dependent
|
||||
// macro to get the type of an expression.
|
||||
#define LL_TYPEOF(expr) decltype(expr)
|
||||
|
||||
#define LL_TO_STRING_HELPER(x) #x
|
||||
#define LL_TO_STRING(x) LL_TO_STRING_HELPER(x)
|
||||
|
|
|
|||
|
|
@ -517,6 +517,10 @@ LLProcessPtr LLProcess::create(const LLSDOrParams& params)
|
|||
|
||||
LLProcess::LLProcess(const LLSDOrParams& params):
|
||||
mAutokill(params.autokill),
|
||||
// Because 'autokill' originally meant both 'autokill' and 'attached', to
|
||||
// preserve existing semantics, we promise that mAttached defaults to the
|
||||
// same setting as mAutokill.
|
||||
mAttached(params.attached.isProvided()? params.attached : params.autokill),
|
||||
mPipes(NSLOTS)
|
||||
{
|
||||
// Hmm, when you construct a ptr_vector with a size, it merely reserves
|
||||
|
|
@ -625,9 +629,9 @@ LLProcess::LLProcess(const LLSDOrParams& params):
|
|||
// std handles and the like, and that's a bit more detachment than we
|
||||
// want. autokill=false just means not to implicitly kill the child when
|
||||
// the parent terminates!
|
||||
// chkapr(apr_procattr_detach_set(procattr, params.autokill? 0 : 1));
|
||||
// chkapr(apr_procattr_detach_set(procattr, mAutokill? 0 : 1));
|
||||
|
||||
if (params.autokill)
|
||||
if (mAutokill)
|
||||
{
|
||||
#if ! defined(APR_HAS_PROCATTR_AUTOKILL_SET)
|
||||
// Our special preprocessor symbol isn't even defined -- wrong APR
|
||||
|
|
@ -696,7 +700,7 @@ LLProcess::LLProcess(const LLSDOrParams& params):
|
|||
// take steps to terminate the child. This is all suspenders-and-belt: in
|
||||
// theory our destructor should kill an autokill child, but in practice
|
||||
// that doesn't always work (e.g. VWR-21538).
|
||||
if (params.autokill)
|
||||
if (mAutokill)
|
||||
{
|
||||
/*==========================================================================*|
|
||||
// NO: There may be an APR bug, not sure -- but at least on Mac, when
|
||||
|
|
@ -799,7 +803,7 @@ LLProcess::~LLProcess()
|
|||
sProcessListener.dropPoll(*this);
|
||||
}
|
||||
|
||||
if (mAutokill)
|
||||
if (mAttached)
|
||||
{
|
||||
kill("destructor");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ public:
|
|||
args("args"),
|
||||
cwd("cwd"),
|
||||
autokill("autokill", true),
|
||||
attached("attached", true),
|
||||
files("files"),
|
||||
postend("postend"),
|
||||
desc("desc")
|
||||
|
|
@ -183,9 +184,31 @@ public:
|
|||
Multiple<std::string> args;
|
||||
/// current working directory, if need it changed
|
||||
Optional<std::string> cwd;
|
||||
/// implicitly kill process on destruction of LLProcess object
|
||||
/// (default true)
|
||||
/// implicitly kill child process on termination of parent, whether
|
||||
/// voluntary or crash (default true)
|
||||
Optional<bool> autokill;
|
||||
/// implicitly kill process on destruction of LLProcess object
|
||||
/// (default same as autokill)
|
||||
///
|
||||
/// Originally, 'autokill' conflated two concepts: kill child process on
|
||||
/// - destruction of its LLProcess object, and
|
||||
/// - termination of parent process, voluntary or otherwise.
|
||||
///
|
||||
/// It's useful to tease these apart. Some child processes are sent a
|
||||
/// "clean up and terminate" message before the associated LLProcess
|
||||
/// object is destroyed. A child process launched with attached=false
|
||||
/// has an extra time window from the destruction of its LLProcess
|
||||
/// until parent-process termination in which to perform its own
|
||||
/// orderly shutdown, yet autokill=true still guarantees that we won't
|
||||
/// accumulate orphan instances of such processes indefinitely. With
|
||||
/// attached=true, if a child process cannot clean up between the
|
||||
/// shutdown message and LLProcess destruction (presumably very soon
|
||||
/// thereafter), it's forcibly killed anyway -- which can lead to
|
||||
/// distressing user-visible crash indications.
|
||||
///
|
||||
/// (The usefulness of attached=true with autokill=false is less
|
||||
/// clear, but we don't prohibit that combination.)
|
||||
Optional<bool> attached;
|
||||
/**
|
||||
* Up to three FileParam items: for child stdin, stdout, stderr.
|
||||
* Passing two FileParam entries means default treatment for stderr,
|
||||
|
|
@ -549,7 +572,7 @@ private:
|
|||
std::string mDesc;
|
||||
std::string mPostend;
|
||||
apr_proc_t mProcess;
|
||||
bool mAutokill;
|
||||
bool mAutokill, mAttached;
|
||||
Status mStatus;
|
||||
// explicitly want this ptr_vector to be able to store NULLs
|
||||
typedef boost::ptr_vector< boost::nullable<BasePipe> > PipeVector;
|
||||
|
|
|
|||
|
|
@ -26,9 +26,11 @@
|
|||
|
||||
#include "linden_common.h"
|
||||
#include "llprocessor.h"
|
||||
|
||||
#include "llstring.h"
|
||||
#include "stringize.h"
|
||||
#include "llerror.h"
|
||||
|
||||
#include <iomanip>
|
||||
//#include <memory>
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
|
@ -47,11 +49,6 @@
|
|||
# define LL_X86 1
|
||||
#elif LL_MSVC && _M_IX86
|
||||
# define LL_X86 1
|
||||
#elif LL_CLANG && ( defined(__amd64__) || defined(__x86_64__) )
|
||||
# define LL_X86_64 1
|
||||
# define LL_X86 1
|
||||
#elif LL_CLANG && ( defined(__i386__) )
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) )
|
||||
# define LL_X86_64 1
|
||||
# define LL_X86 1
|
||||
|
|
@ -193,7 +190,7 @@ namespace
|
|||
case 0xF: return "Intel Pentium 4";
|
||||
case 0x10: return "Intel Itanium 2 (IA-64)";
|
||||
}
|
||||
return "Unknown";
|
||||
return STRINGIZE("Intel <unknown 0x" << std::hex << composed_family << ">");
|
||||
}
|
||||
|
||||
std::string amd_CPUFamilyName(int composed_family)
|
||||
|
|
@ -206,27 +203,28 @@ namespace
|
|||
case 0xF: return "AMD K8";
|
||||
case 0x10: return "AMD K8L";
|
||||
}
|
||||
return "Unknown";
|
||||
return STRINGIZE("AMD <unknown 0x" << std::hex << composed_family << ">");
|
||||
}
|
||||
|
||||
std::string compute_CPUFamilyName(const char* cpu_vendor, int family, int ext_family)
|
||||
{
|
||||
const char* intel_string = "GenuineIntel";
|
||||
const char* amd_string = "AuthenticAMD";
|
||||
if(!strncmp(cpu_vendor, intel_string, strlen(intel_string)))
|
||||
if (LLStringUtil::startsWith(cpu_vendor, intel_string))
|
||||
{
|
||||
U32 composed_family = family + ext_family;
|
||||
return intel_CPUFamilyName(composed_family);
|
||||
}
|
||||
else if(!strncmp(cpu_vendor, amd_string, strlen(amd_string)))
|
||||
else if (LLStringUtil::startsWith(cpu_vendor, amd_string))
|
||||
{
|
||||
U32 composed_family = (family == 0xF)
|
||||
? family + ext_family
|
||||
: family;
|
||||
return amd_CPUFamilyName(composed_family);
|
||||
}
|
||||
return "Unknown";
|
||||
return STRINGIZE("Unrecognized CPU vendor <" << cpu_vendor << ">");
|
||||
}
|
||||
|
||||
} // end unnamed namespace
|
||||
|
||||
// The base class for implementations.
|
||||
|
|
@ -262,8 +260,8 @@ public:
|
|||
return hasExtension("Altivec");
|
||||
}
|
||||
|
||||
std::string getCPUFamilyName() const { return getInfo(eFamilyName, "Unknown").asString(); }
|
||||
std::string getCPUBrandName() const { return getInfo(eBrandName, "Unknown").asString(); }
|
||||
std::string getCPUFamilyName() const { return getInfo(eFamilyName, "Unset family").asString(); }
|
||||
std::string getCPUBrandName() const { return getInfo(eBrandName, "Unset brand").asString(); }
|
||||
|
||||
// This is virtual to support a different linux format.
|
||||
// *NOTE:Mani - I didn't want to screw up server use of this data...
|
||||
|
|
@ -275,7 +273,7 @@ public:
|
|||
out << "//////////////////////////" << std::endl;
|
||||
out << "Processor Name: " << getCPUBrandName() << std::endl;
|
||||
out << "Frequency: " << getCPUFrequency() << " MHz" << std::endl;
|
||||
out << "Vendor: " << getInfo(eVendor, "Unknown").asString() << std::endl;
|
||||
out << "Vendor: " << getInfo(eVendor, "Unset vendor").asString() << std::endl;
|
||||
out << "Family: " << getCPUFamilyName() << " (" << getInfo(eFamily, 0) << ")" << std::endl;
|
||||
out << "Extended family: " << getInfo(eExtendedFamily, 0) << std::endl;
|
||||
out << "Model: " << getInfo(eModel, 0) << std::endl;
|
||||
|
|
@ -402,7 +400,6 @@ static F64 calculate_cpu_frequency(U32 measure_msecs)
|
|||
HANDLE hThread = GetCurrentThread();
|
||||
unsigned long dwCurPriorityClass = GetPriorityClass(hProcess);
|
||||
int iCurThreadPriority = GetThreadPriority(hThread);
|
||||
// unsigned long dwProcessMask, dwSystemMask, dwNewMask = 1;
|
||||
DWORD_PTR dwProcessMask, dwSystemMask, dwNewMask = 1;
|
||||
GetProcessAffinityMask(hProcess, &dwProcessMask, &dwSystemMask);
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,30 @@
|
|||
#define LLSAFEHANDLE_H
|
||||
|
||||
#include "llerror.h" // *TODO: consider eliminating this
|
||||
#include "llsingleton.h"
|
||||
|
||||
/*==========================================================================*|
|
||||
____ ___ _ _ ___ _____ _ _ ____ _____ _
|
||||
| _ \ / _ \ | \ | |/ _ \_ _| | | | / ___|| ____| |
|
||||
| | | | | | | | \| | | | || | | | | \___ \| _| | |
|
||||
| |_| | |_| | | |\ | |_| || | | |_| |___) | |___|_|
|
||||
|____/ \___/ |_| \_|\___/ |_| \___/|____/|_____(_)
|
||||
|
||||
This handle class is deprecated. Unfortunately it is already in widespread use
|
||||
to reference the LLObjectSelection and LLParcelSelection classes, but do not
|
||||
apply LLSafeHandle to other classes, or declare new instances.
|
||||
|
||||
Instead, use LLPointer or other smart pointer types with appropriate checks
|
||||
for NULL. If you're certain the reference cannot (or must not) be NULL,
|
||||
consider storing a C++ reference instead -- or use (e.g.) LLCheckedHandle.
|
||||
|
||||
When an LLSafeHandle<T> containing NULL is dereferenced, it resolves to a
|
||||
canonical "null" T instance. This raises issues about the lifespan of the
|
||||
"null" instance. In addition to encouraging sloppy coding practices, it
|
||||
potentially masks bugs when code that performs some mutating operation
|
||||
inadvertently applies it to the "null" instance. That result might or might
|
||||
not ever affect subsequent computations.
|
||||
|*==========================================================================*/
|
||||
|
||||
// Expands LLPointer to return a pointer to a special instance of class Type instead of NULL.
|
||||
// This is useful in instances where operations on NULL pointers are semantically safe and/or
|
||||
|
|
@ -112,10 +136,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
typedef Type* (*NullFunc)();
|
||||
static const NullFunc sNullFunc;
|
||||
|
||||
protected:
|
||||
void ref()
|
||||
{
|
||||
|
|
@ -150,9 +170,25 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
// Define an LLSingleton whose sole purpose is to hold a "null instance"
|
||||
// of the subject Type: the canonical instance to dereference if this
|
||||
// LLSafeHandle actually holds a null pointer. We use LLSingleton
|
||||
// specifically so that the "null instance" can be cleaned up at a well-
|
||||
// defined time, specifically LLSingletonBase::deleteAll().
|
||||
// Of course, as with any LLSingleton, the "null instance" is only
|
||||
// instantiated on demand -- in this case, if you actually try to
|
||||
// dereference an LLSafeHandle containing null.
|
||||
class NullInstanceHolder: public LLSingleton<NullInstanceHolder>
|
||||
{
|
||||
LLSINGLETON_EMPTY_CTOR(NullInstanceHolder);
|
||||
~NullInstanceHolder() {}
|
||||
public:
|
||||
Type mNullInstance;
|
||||
};
|
||||
|
||||
static Type* nonNull(Type* ptr)
|
||||
{
|
||||
return ptr == NULL ? sNullFunc() : ptr;
|
||||
return ptr? ptr : &NullInstanceHolder::instance().mNullInstance;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "stdtypes.h"
|
||||
|
||||
#include "llsd.h"
|
||||
#include "value.h"
|
||||
#include "json/value.h"
|
||||
|
||||
/// Convert a parsed JSON structure into LLSD maintaining member names and
|
||||
/// array indexes.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,120 @@
|
|||
/**
|
||||
* @file llstatsaccumulator.h
|
||||
* @brief Class for accumulating statistics.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_STATS_ACCUMULATOR_H
|
||||
#define LL_STATS_ACCUMULATOR_H
|
||||
#include "llsd.h"
|
||||
|
||||
class LLStatsAccumulator
|
||||
{
|
||||
public:
|
||||
inline LLStatsAccumulator()
|
||||
{
|
||||
reset();
|
||||
}
|
||||
|
||||
inline void push(F32 val)
|
||||
{
|
||||
if (mCountOfNextUpdatesToIgnore > 0)
|
||||
{
|
||||
mCountOfNextUpdatesToIgnore--;
|
||||
return;
|
||||
}
|
||||
|
||||
mCount++;
|
||||
mSum += val;
|
||||
mSumOfSquares += val * val;
|
||||
if (mCount == 1 || val > mMaxValue)
|
||||
{
|
||||
mMaxValue = val;
|
||||
}
|
||||
if (mCount == 1 || val < mMinValue)
|
||||
{
|
||||
mMinValue = val;
|
||||
}
|
||||
}
|
||||
|
||||
inline F32 getSum() const
|
||||
{
|
||||
return mSum;
|
||||
}
|
||||
|
||||
inline F32 getMean() const
|
||||
{
|
||||
return (mCount == 0) ? 0.f : ((F32)mSum) / mCount;
|
||||
}
|
||||
|
||||
inline F32 getMinValue() const
|
||||
{
|
||||
return mMinValue;
|
||||
}
|
||||
|
||||
inline F32 getMaxValue() const
|
||||
{
|
||||
return mMaxValue;
|
||||
}
|
||||
|
||||
inline F32 getStdDev() const
|
||||
{
|
||||
const F32 mean = getMean();
|
||||
return (mCount < 2) ? 0.f : sqrtf(llmax(0.f, mSumOfSquares / mCount - (mean * mean)));
|
||||
}
|
||||
|
||||
inline U32 getCount() const
|
||||
{
|
||||
return mCount;
|
||||
}
|
||||
|
||||
inline void reset()
|
||||
{
|
||||
mCount = 0;
|
||||
mSum = mSumOfSquares = 0.f;
|
||||
mMinValue = 0.0f;
|
||||
mMaxValue = 0.0f;
|
||||
mCountOfNextUpdatesToIgnore = 0;
|
||||
}
|
||||
|
||||
inline LLSD asLLSD() const
|
||||
{
|
||||
LLSD data;
|
||||
data["mean"] = getMean();
|
||||
data["std_dev"] = getStdDev();
|
||||
data["count"] = (S32)mCount;
|
||||
data["min"] = getMinValue();
|
||||
data["max"] = getMaxValue();
|
||||
return data;
|
||||
}
|
||||
|
||||
private:
|
||||
S32 mCount;
|
||||
F32 mSum;
|
||||
F32 mSumOfSquares;
|
||||
F32 mMinValue;
|
||||
F32 mMaxValue;
|
||||
U32 mCountOfNextUpdatesToIgnore;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -768,22 +768,6 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
|
|||
#endif
|
||||
}
|
||||
|
||||
U32Bytes LLMemoryInfo::getPhysicalMemoryClamped() const
|
||||
{
|
||||
// Return the total physical memory in bytes, but clamp it
|
||||
// to no more than U32_MAX
|
||||
|
||||
U32Kilobytes phys_kb = getPhysicalMemoryKB();
|
||||
if (phys_kb >= U32Gigabytes(4))
|
||||
{
|
||||
return U32Bytes(U32_MAX);
|
||||
}
|
||||
else
|
||||
{
|
||||
return phys_kb;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb)
|
||||
{
|
||||
|
|
@ -1011,10 +995,10 @@ LLSD LLMemoryInfo::loadStatsMap( bool aProcessMemoryOnly )
|
|||
//
|
||||
|
||||
{
|
||||
vm_statistics_data_t vmstat;
|
||||
mach_msg_type_number_t vmstatCount = HOST_VM_INFO_COUNT;
|
||||
vm_statistics64_data_t vmstat;
|
||||
mach_msg_type_number_t vmstatCount = HOST_VM_INFO64_COUNT;
|
||||
|
||||
if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t) &vmstat, &vmstatCount) != KERN_SUCCESS)
|
||||
if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) &vmstat, &vmstatCount) != KERN_SUCCESS)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect memory information" << LL_ENDL;
|
||||
}
|
||||
|
|
@ -1072,20 +1056,20 @@ LLSD LLMemoryInfo::loadStatsMap( bool aProcessMemoryOnly )
|
|||
//
|
||||
|
||||
{
|
||||
task_basic_info_64_data_t taskinfo;
|
||||
unsigned taskinfoSize = sizeof(taskinfo);
|
||||
|
||||
if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t) &taskinfo, &taskinfoSize) != KERN_SUCCESS)
|
||||
mach_task_basic_info_data_t taskinfo;
|
||||
mach_msg_type_number_t task_count = MACH_TASK_BASIC_INFO_COUNT;
|
||||
if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t) &taskinfo, &task_count) != KERN_SUCCESS)
|
||||
{
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect task information" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.add("Basic suspend count", taskinfo.suspend_count);
|
||||
stats.add("Basic virtual memory KB", taskinfo.virtual_size / 1024);
|
||||
stats.add("Basic resident memory KB", taskinfo.resident_size / 1024);
|
||||
stats.add("Basic new thread policy", taskinfo.policy);
|
||||
}
|
||||
LL_WARNS("LLMemoryInfo") << "Unable to collect task information" << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
stats.add("Basic virtual memory KB", taskinfo.virtual_size / 1024);
|
||||
stats.add("Basic resident memory KB", taskinfo.resident_size / 1024);
|
||||
stats.add("Basic max resident memory KB", taskinfo.resident_size_max / 1024);
|
||||
stats.add("Basic new thread policy", taskinfo.policy);
|
||||
stats.add("Basic suspend count", taskinfo.suspend_count);
|
||||
}
|
||||
}
|
||||
|
||||
#elif LL_SOLARIS
|
||||
|
|
|
|||
|
|
@ -114,11 +114,6 @@ public:
|
|||
void stream(std::ostream& s) const; ///< output text info to s
|
||||
|
||||
U32Kilobytes getPhysicalMemoryKB() const;
|
||||
|
||||
/*! Memory size in bytes, if total memory is >= 4GB then U32_MAX will
|
||||
** be returned.
|
||||
*/
|
||||
U32Bytes getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes
|
||||
|
||||
//get the available memory infomation in KiloBytes.
|
||||
static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "lltimer.h"
|
||||
#include "lltrace.h"
|
||||
#include "lltracethreadrecorder.h"
|
||||
#include "llexception.h"
|
||||
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
#include <sched.h>
|
||||
|
|
@ -46,31 +47,28 @@ const DWORD MS_VC_EXCEPTION=0x406D1388;
|
|||
#pragma pack(push,8)
|
||||
typedef struct tagTHREADNAME_INFO
|
||||
{
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to name (in user addr space).
|
||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
DWORD dwType; // Must be 0x1000.
|
||||
LPCSTR szName; // Pointer to name (in user addr space).
|
||||
DWORD dwThreadID; // Thread ID (-1=caller thread).
|
||||
DWORD dwFlags; // Reserved for future use, must be zero.
|
||||
} THREADNAME_INFO;
|
||||
#pragma pack(pop)
|
||||
|
||||
void set_thread_name( DWORD dwThreadID, const char* threadName)
|
||||
{
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = threadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
THREADNAME_INFO info;
|
||||
info.dwType = 0x1000;
|
||||
info.szName = threadName;
|
||||
info.dwThreadID = dwThreadID;
|
||||
info.dwFlags = 0;
|
||||
|
||||
__try
|
||||
{
|
||||
// <FS:ND> Proper arguments for RaiseException
|
||||
// ::RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (DWORD*)&info );
|
||||
::RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info );
|
||||
// </FS:ND>
|
||||
}
|
||||
__except(EXCEPTION_CONTINUE_EXECUTION)
|
||||
{
|
||||
}
|
||||
__try
|
||||
{
|
||||
::RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(DWORD), (ULONG_PTR*)&info );
|
||||
}
|
||||
__except(EXCEPTION_CONTINUE_EXECUTION)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -102,17 +100,17 @@ U32 LLThread::sIDIter = 0;
|
|||
|
||||
LL_COMMON_API void assert_main_thread()
|
||||
{
|
||||
static U32 s_thread_id = LLThread::currentID();
|
||||
if (LLThread::currentID() != s_thread_id)
|
||||
{
|
||||
LL_WARNS() << "Illegal execution from thread id " << (S32) LLThread::currentID()
|
||||
<< " outside main thread " << (S32) s_thread_id << LL_ENDL;
|
||||
}
|
||||
static U32 s_thread_id = LLThread::currentID();
|
||||
if (LLThread::currentID() != s_thread_id)
|
||||
{
|
||||
LL_WARNS() << "Illegal execution from thread id " << (S32) LLThread::currentID()
|
||||
<< " outside main thread " << (S32) s_thread_id << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLThread::registerThreadID()
|
||||
{
|
||||
sThreadID = ++sIDIter;
|
||||
sThreadID = ++sIDIter;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -120,157 +118,203 @@ void LLThread::registerThreadID()
|
|||
//
|
||||
void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap)
|
||||
{
|
||||
LLThread *threadp = (LLThread *)datap;
|
||||
LLThread *threadp = (LLThread *)datap;
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
set_thread_name(-1, threadp->mName.c_str());
|
||||
set_thread_name(-1, threadp->mName.c_str());
|
||||
#endif
|
||||
|
||||
// for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread
|
||||
threadp->mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder());
|
||||
// for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread
|
||||
threadp->mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder());
|
||||
|
||||
sThreadID = threadp->mID;
|
||||
sThreadID = threadp->mID;
|
||||
|
||||
// Run the user supplied function
|
||||
threadp->run();
|
||||
try
|
||||
{
|
||||
// Run the user supplied function
|
||||
do
|
||||
{
|
||||
try
|
||||
{
|
||||
threadp->run();
|
||||
}
|
||||
catch (const LLContinueError &e)
|
||||
{
|
||||
LL_WARNS("THREAD") << "ContinueException on thread '" << threadp->mName <<
|
||||
"' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL;
|
||||
//output possible call stacks to log file.
|
||||
LLError::LLCallStacks::print();
|
||||
|
||||
//LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
|
||||
|
||||
delete threadp->mRecorder;
|
||||
threadp->mRecorder = NULL;
|
||||
|
||||
// We're done with the run function, this thread is done executing now.
|
||||
//NB: we are using this flag to sync across threads...we really need memory barriers here
|
||||
threadp->mStatus = STOPPED;
|
||||
LOG_UNHANDLED_EXCEPTION("LLThread");
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
return NULL;
|
||||
} while (true);
|
||||
|
||||
//LL_INFOS() << "LLThread::staticRun() Exiting: " << threadp->mName << LL_ENDL;
|
||||
|
||||
// We're done with the run function, this thread is done executing now.
|
||||
//NB: we are using this flag to sync across threads...we really need memory barriers here
|
||||
threadp->mStatus = STOPPED;
|
||||
}
|
||||
catch (std::bad_alloc)
|
||||
{
|
||||
threadp->mStatus = CRASHED;
|
||||
LLMemory::logMemoryInfo(TRUE);
|
||||
|
||||
//output possible call stacks to log file.
|
||||
LLError::LLCallStacks::print();
|
||||
|
||||
LL_ERRS("THREAD") << "Bad memory allocation in LLThread::staticRun() named '" << threadp->mName << "'!" << LL_ENDL;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
threadp->mStatus = CRASHED;
|
||||
CRASH_ON_UNHANDLED_EXCEPTION("LLThread");
|
||||
}
|
||||
|
||||
delete threadp->mRecorder;
|
||||
threadp->mRecorder = NULL;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLThread::LLThread(const std::string& name, apr_pool_t *poolp) :
|
||||
mPaused(FALSE),
|
||||
mName(name),
|
||||
mAPRThreadp(NULL),
|
||||
mStatus(STOPPED),
|
||||
mRecorder(NULL)
|
||||
mPaused(FALSE),
|
||||
mName(name),
|
||||
mAPRThreadp(NULL),
|
||||
mStatus(STOPPED),
|
||||
mRecorder(NULL)
|
||||
{
|
||||
|
||||
mID = ++sIDIter;
|
||||
mID = ++sIDIter;
|
||||
|
||||
// Thread creation probably CAN be paranoid about APR being initialized, if necessary
|
||||
if (poolp)
|
||||
{
|
||||
mIsLocalPool = FALSE;
|
||||
mAPRPoolp = poolp;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsLocalPool = TRUE;
|
||||
apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
|
||||
}
|
||||
mRunCondition = new LLCondition(mAPRPoolp);
|
||||
mDataLock = new LLMutex(mAPRPoolp);
|
||||
mLocalAPRFilePoolp = NULL ;
|
||||
// Thread creation probably CAN be paranoid about APR being initialized, if necessary
|
||||
if (poolp)
|
||||
{
|
||||
mIsLocalPool = FALSE;
|
||||
mAPRPoolp = poolp;
|
||||
}
|
||||
else
|
||||
{
|
||||
mIsLocalPool = TRUE;
|
||||
apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
|
||||
}
|
||||
mRunCondition = new LLCondition(mAPRPoolp);
|
||||
mDataLock = new LLMutex(mAPRPoolp);
|
||||
mLocalAPRFilePoolp = NULL ;
|
||||
}
|
||||
|
||||
|
||||
LLThread::~LLThread()
|
||||
{
|
||||
shutdown();
|
||||
shutdown();
|
||||
|
||||
if(mLocalAPRFilePoolp)
|
||||
{
|
||||
delete mLocalAPRFilePoolp ;
|
||||
mLocalAPRFilePoolp = NULL ;
|
||||
}
|
||||
if (isCrashed())
|
||||
{
|
||||
LL_WARNS("THREAD") << "Destroying crashed thread named '" << mName << "'" << LL_ENDL;
|
||||
}
|
||||
|
||||
if(mLocalAPRFilePoolp)
|
||||
{
|
||||
delete mLocalAPRFilePoolp ;
|
||||
mLocalAPRFilePoolp = NULL ;
|
||||
}
|
||||
}
|
||||
|
||||
void LLThread::shutdown()
|
||||
{
|
||||
// Warning! If you somehow call the thread destructor from itself,
|
||||
// the thread will die in an unclean fashion!
|
||||
if (mAPRThreadp)
|
||||
{
|
||||
if (!isStopped())
|
||||
{
|
||||
// The thread isn't already stopped
|
||||
// First, set the flag that indicates that we're ready to die
|
||||
setQuitting();
|
||||
if (isCrashed())
|
||||
{
|
||||
LL_WARNS("THREAD") << "Shutting down crashed thread named '" << mName << "'" << LL_ENDL;
|
||||
}
|
||||
|
||||
//LL_INFOS() << "LLThread::~LLThread() Killing thread " << mName << " Status: " << mStatus << LL_ENDL;
|
||||
// Now wait a bit for the thread to exit
|
||||
// It's unclear whether I should even bother doing this - this destructor
|
||||
// should never get called unless we're already stopped, really...
|
||||
S32 counter = 0;
|
||||
const S32 MAX_WAIT = 600;
|
||||
while (counter < MAX_WAIT)
|
||||
{
|
||||
if (isStopped())
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Sleep for a tenth of a second
|
||||
ms_sleep(100);
|
||||
yield();
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
// Warning! If you somehow call the thread destructor from itself,
|
||||
// the thread will die in an unclean fashion!
|
||||
if (mAPRThreadp)
|
||||
{
|
||||
if (!isStopped())
|
||||
{
|
||||
// The thread isn't already stopped
|
||||
// First, set the flag that indicates that we're ready to die
|
||||
setQuitting();
|
||||
|
||||
if (!isStopped())
|
||||
{
|
||||
// This thread just wouldn't stop, even though we gave it time
|
||||
//LL_WARNS() << "LLThread::~LLThread() exiting thread before clean exit!" << LL_ENDL;
|
||||
// Put a stake in its heart.
|
||||
delete mRecorder;
|
||||
//LL_INFOS() << "LLThread::~LLThread() Killing thread " << mName << " Status: " << mStatus << LL_ENDL;
|
||||
// Now wait a bit for the thread to exit
|
||||
// It's unclear whether I should even bother doing this - this destructor
|
||||
// should never get called unless we're already stopped, really...
|
||||
S32 counter = 0;
|
||||
const S32 MAX_WAIT = 600;
|
||||
while (counter < MAX_WAIT)
|
||||
{
|
||||
if (isStopped())
|
||||
{
|
||||
break;
|
||||
}
|
||||
// Sleep for a tenth of a second
|
||||
ms_sleep(100);
|
||||
yield();
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
apr_thread_exit(mAPRThreadp, -1);
|
||||
return;
|
||||
}
|
||||
mAPRThreadp = NULL;
|
||||
}
|
||||
if (!isStopped())
|
||||
{
|
||||
// This thread just wouldn't stop, even though we gave it time
|
||||
//LL_WARNS() << "LLThread::~LLThread() exiting thread before clean exit!" << LL_ENDL;
|
||||
// Put a stake in its heart.
|
||||
delete mRecorder;
|
||||
|
||||
delete mRunCondition;
|
||||
mRunCondition = NULL;
|
||||
apr_thread_exit(mAPRThreadp, -1);
|
||||
return;
|
||||
}
|
||||
mAPRThreadp = NULL;
|
||||
}
|
||||
|
||||
delete mDataLock;
|
||||
mDataLock = NULL;
|
||||
|
||||
if (mIsLocalPool && mAPRPoolp)
|
||||
{
|
||||
apr_pool_destroy(mAPRPoolp);
|
||||
mAPRPoolp = 0;
|
||||
}
|
||||
delete mRunCondition;
|
||||
mRunCondition = NULL;
|
||||
|
||||
if (mRecorder)
|
||||
{
|
||||
// missed chance to properly shut down recorder (needs to be done in thread context)
|
||||
// probably due to abnormal thread termination
|
||||
// so just leak it and remove it from parent
|
||||
LLTrace::get_master_thread_recorder()->removeChildRecorder(mRecorder);
|
||||
}
|
||||
delete mDataLock;
|
||||
mDataLock = NULL;
|
||||
|
||||
if (mIsLocalPool && mAPRPoolp)
|
||||
{
|
||||
apr_pool_destroy(mAPRPoolp);
|
||||
mAPRPoolp = 0;
|
||||
}
|
||||
|
||||
if (mRecorder)
|
||||
{
|
||||
// missed chance to properly shut down recorder (needs to be done in thread context)
|
||||
// probably due to abnormal thread termination
|
||||
// so just leak it and remove it from parent
|
||||
LLTrace::get_master_thread_recorder()->removeChildRecorder(mRecorder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLThread::start()
|
||||
{
|
||||
llassert(isStopped());
|
||||
|
||||
// Set thread state to running
|
||||
mStatus = RUNNING;
|
||||
llassert(isStopped());
|
||||
|
||||
// Set thread state to running
|
||||
mStatus = RUNNING;
|
||||
|
||||
apr_status_t status =
|
||||
apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
|
||||
|
||||
if(status == APR_SUCCESS)
|
||||
{
|
||||
// We won't bother joining
|
||||
apr_thread_detach(mAPRThreadp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mStatus = STOPPED;
|
||||
LL_WARNS() << "failed to start thread " << mName << LL_ENDL;
|
||||
ll_apr_warn_status(status);
|
||||
}
|
||||
apr_status_t status =
|
||||
apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
|
||||
|
||||
if(status == APR_SUCCESS)
|
||||
{
|
||||
// We won't bother joining
|
||||
apr_thread_detach(mAPRThreadp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mStatus = STOPPED;
|
||||
LL_WARNS() << "failed to start thread " << mName << LL_ENDL;
|
||||
ll_apr_warn_status(status);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -281,28 +325,28 @@ void LLThread::start()
|
|||
// The thread will pause when (and if) it calls checkPause()
|
||||
void LLThread::pause()
|
||||
{
|
||||
if (!mPaused)
|
||||
{
|
||||
// this will cause the thread to stop execution as soon as checkPause() is called
|
||||
mPaused = 1; // Does not need to be atomic since this is only set/unset from the main thread
|
||||
}
|
||||
if (!mPaused)
|
||||
{
|
||||
// this will cause the thread to stop execution as soon as checkPause() is called
|
||||
mPaused = 1; // Does not need to be atomic since this is only set/unset from the main thread
|
||||
}
|
||||
}
|
||||
|
||||
void LLThread::unpause()
|
||||
{
|
||||
if (mPaused)
|
||||
{
|
||||
mPaused = 0;
|
||||
}
|
||||
if (mPaused)
|
||||
{
|
||||
mPaused = 0;
|
||||
}
|
||||
|
||||
wake(); // wake up the thread if necessary
|
||||
wake(); // wake up the thread if necessary
|
||||
}
|
||||
|
||||
// virtual predicate function -- returns true if the thread should wake up, false if it should sleep.
|
||||
bool LLThread::runCondition(void)
|
||||
{
|
||||
// by default, always run. Handling of pause/unpause is done regardless of this function's result.
|
||||
return true;
|
||||
// by default, always run. Handling of pause/unpause is done regardless of this function's result.
|
||||
return true;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -310,65 +354,65 @@ bool LLThread::runCondition(void)
|
|||
// Stop thread execution if requested until unpaused.
|
||||
void LLThread::checkPause()
|
||||
{
|
||||
mDataLock->lock();
|
||||
mDataLock->lock();
|
||||
|
||||
// This is in a while loop because the pthread API allows for spurious wakeups.
|
||||
while(shouldSleep())
|
||||
{
|
||||
mDataLock->unlock();
|
||||
mRunCondition->wait(); // unlocks mRunCondition
|
||||
mDataLock->lock();
|
||||
// mRunCondition is locked when the thread wakes up
|
||||
}
|
||||
|
||||
mDataLock->unlock();
|
||||
// This is in a while loop because the pthread API allows for spurious wakeups.
|
||||
while(shouldSleep())
|
||||
{
|
||||
mDataLock->unlock();
|
||||
mRunCondition->wait(); // unlocks mRunCondition
|
||||
mDataLock->lock();
|
||||
// mRunCondition is locked when the thread wakes up
|
||||
}
|
||||
|
||||
mDataLock->unlock();
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
void LLThread::setQuitting()
|
||||
{
|
||||
mDataLock->lock();
|
||||
if (mStatus == RUNNING)
|
||||
{
|
||||
mStatus = QUITTING;
|
||||
}
|
||||
mDataLock->unlock();
|
||||
wake();
|
||||
mDataLock->lock();
|
||||
if (mStatus == RUNNING)
|
||||
{
|
||||
mStatus = QUITTING;
|
||||
}
|
||||
mDataLock->unlock();
|
||||
wake();
|
||||
}
|
||||
|
||||
// static
|
||||
U32 LLThread::currentID()
|
||||
{
|
||||
return sThreadID;
|
||||
return sThreadID;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLThread::yield()
|
||||
{
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
sched_yield(); // annoyingly, apr_thread_yield is a noop on linux...
|
||||
sched_yield(); // annoyingly, apr_thread_yield is a noop on linux...
|
||||
#else
|
||||
apr_thread_yield();
|
||||
apr_thread_yield();
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLThread::wake()
|
||||
{
|
||||
mDataLock->lock();
|
||||
if(!shouldSleep())
|
||||
{
|
||||
mRunCondition->signal();
|
||||
}
|
||||
mDataLock->unlock();
|
||||
mDataLock->lock();
|
||||
if(!shouldSleep())
|
||||
{
|
||||
mRunCondition->signal();
|
||||
}
|
||||
mDataLock->unlock();
|
||||
}
|
||||
|
||||
void LLThread::wakeLocked()
|
||||
{
|
||||
if(!shouldSleep())
|
||||
{
|
||||
mRunCondition->signal();
|
||||
}
|
||||
if(!shouldSleep())
|
||||
{
|
||||
mRunCondition->signal();
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
@ -381,38 +425,38 @@ LLMutex* LLThreadSafeRefCount::sMutex = 0;
|
|||
//static
|
||||
void LLThreadSafeRefCount::initThreadSafeRefCount()
|
||||
{
|
||||
if (!sMutex)
|
||||
{
|
||||
sMutex = new LLMutex(0);
|
||||
}
|
||||
if (!sMutex)
|
||||
{
|
||||
sMutex = new LLMutex(0);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLThreadSafeRefCount::cleanupThreadSafeRefCount()
|
||||
{
|
||||
delete sMutex;
|
||||
sMutex = NULL;
|
||||
delete sMutex;
|
||||
sMutex = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
LLThreadSafeRefCount::LLThreadSafeRefCount() :
|
||||
mRef(0)
|
||||
mRef(0)
|
||||
{
|
||||
}
|
||||
|
||||
LLThreadSafeRefCount::LLThreadSafeRefCount(const LLThreadSafeRefCount& src)
|
||||
{
|
||||
mRef = 0;
|
||||
mRef = 0;
|
||||
}
|
||||
|
||||
LLThreadSafeRefCount::~LLThreadSafeRefCount()
|
||||
{
|
||||
if (mRef != 0)
|
||||
{
|
||||
if (mRef != 0)
|
||||
{
|
||||
LL_ERRS() << "deleting referenced object mRef = " << mRef << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -38,118 +38,120 @@ LL_COMMON_API void assert_main_thread();
|
|||
|
||||
namespace LLTrace
|
||||
{
|
||||
class ThreadRecorder;
|
||||
class ThreadRecorder;
|
||||
}
|
||||
|
||||
class LL_COMMON_API LLThread
|
||||
{
|
||||
private:
|
||||
friend class LLMutex;
|
||||
static U32 sIDIter;
|
||||
friend class LLMutex;
|
||||
static U32 sIDIter;
|
||||
|
||||
public:
|
||||
typedef enum e_thread_status
|
||||
{
|
||||
STOPPED = 0, // The thread is not running. Not started, or has exited its run function
|
||||
RUNNING = 1, // The thread is currently running
|
||||
QUITTING= 2 // Someone wants this thread to quit
|
||||
} EThreadStatus;
|
||||
typedef enum e_thread_status
|
||||
{
|
||||
STOPPED = 0, // The thread is not running. Not started, or has exited its run function
|
||||
RUNNING = 1, // The thread is currently running
|
||||
QUITTING= 2, // Someone wants this thread to quit
|
||||
CRASHED = -1 // An uncaught exception was thrown by the thread
|
||||
} EThreadStatus;
|
||||
|
||||
LLThread(const std::string& name, apr_pool_t *poolp = NULL);
|
||||
virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
|
||||
virtual void shutdown(); // stops the thread
|
||||
|
||||
bool isQuitting() const { return (QUITTING == mStatus); }
|
||||
bool isStopped() const { return (STOPPED == mStatus); }
|
||||
|
||||
static U32 currentID(); // Return ID of current thread
|
||||
static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure.
|
||||
|
||||
LLThread(const std::string& name, apr_pool_t *poolp = NULL);
|
||||
virtual ~LLThread(); // Warning! You almost NEVER want to destroy a thread unless it's in the STOPPED state.
|
||||
virtual void shutdown(); // stops the thread
|
||||
|
||||
bool isQuitting() const { return (QUITTING == mStatus); }
|
||||
bool isStopped() const { return (STOPPED == mStatus) || (CRASHED == mStatus); }
|
||||
bool isCrashed() const { return (CRASHED == mStatus); }
|
||||
|
||||
static U32 currentID(); // Return ID of current thread
|
||||
static void yield(); // Static because it can be called by the main thread, which doesn't have an LLThread data structure.
|
||||
|
||||
public:
|
||||
// PAUSE / RESUME functionality. See source code for important usage notes.
|
||||
// Called from MAIN THREAD.
|
||||
void pause();
|
||||
void unpause();
|
||||
bool isPaused() { return isStopped() || mPaused == TRUE; }
|
||||
|
||||
// Cause the thread to wake up and check its condition
|
||||
void wake();
|
||||
// PAUSE / RESUME functionality. See source code for important usage notes.
|
||||
// Called from MAIN THREAD.
|
||||
void pause();
|
||||
void unpause();
|
||||
bool isPaused() { return isStopped() || mPaused == TRUE; }
|
||||
|
||||
// Cause the thread to wake up and check its condition
|
||||
void wake();
|
||||
|
||||
// Same as above, but to be used when the condition is already locked.
|
||||
void wakeLocked();
|
||||
// Same as above, but to be used when the condition is already locked.
|
||||
void wakeLocked();
|
||||
|
||||
// Called from run() (CHILD THREAD). Pause the thread if requested until unpaused.
|
||||
void checkPause();
|
||||
// Called from run() (CHILD THREAD). Pause the thread if requested until unpaused.
|
||||
void checkPause();
|
||||
|
||||
// this kicks off the apr thread
|
||||
void start(void);
|
||||
// this kicks off the apr thread
|
||||
void start(void);
|
||||
|
||||
apr_pool_t *getAPRPool() { return mAPRPoolp; }
|
||||
LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
|
||||
apr_pool_t *getAPRPool() { return mAPRPoolp; }
|
||||
LLVolatileAPRPool* getLocalAPRFilePool() { return mLocalAPRFilePoolp ; }
|
||||
|
||||
U32 getID() const { return mID; }
|
||||
U32 getID() const { return mID; }
|
||||
|
||||
// Called by threads *not* created via LLThread to register some
|
||||
// internal state used by LLMutex. You must call this once early
|
||||
// in the running thread to prevent collisions with the main thread.
|
||||
static void registerThreadID();
|
||||
|
||||
// Called by threads *not* created via LLThread to register some
|
||||
// internal state used by LLMutex. You must call this once early
|
||||
// in the running thread to prevent collisions with the main thread.
|
||||
static void registerThreadID();
|
||||
|
||||
private:
|
||||
BOOL mPaused;
|
||||
|
||||
// static function passed to APR thread creation routine
|
||||
static void *APR_THREAD_FUNC staticRun(struct apr_thread_t *apr_threadp, void *datap);
|
||||
BOOL mPaused;
|
||||
|
||||
// static function passed to APR thread creation routine
|
||||
static void *APR_THREAD_FUNC staticRun(struct apr_thread_t *apr_threadp, void *datap);
|
||||
|
||||
protected:
|
||||
std::string mName;
|
||||
class LLCondition* mRunCondition;
|
||||
LLMutex* mDataLock;
|
||||
std::string mName;
|
||||
class LLCondition* mRunCondition;
|
||||
LLMutex* mDataLock;
|
||||
|
||||
apr_thread_t *mAPRThreadp;
|
||||
apr_pool_t *mAPRPoolp;
|
||||
BOOL mIsLocalPool;
|
||||
EThreadStatus mStatus;
|
||||
U32 mID;
|
||||
LLTrace::ThreadRecorder* mRecorder;
|
||||
apr_thread_t *mAPRThreadp;
|
||||
apr_pool_t *mAPRPoolp;
|
||||
BOOL mIsLocalPool;
|
||||
EThreadStatus mStatus;
|
||||
U32 mID;
|
||||
LLTrace::ThreadRecorder* mRecorder;
|
||||
|
||||
//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
|
||||
//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
|
||||
// otherwise it will cause severe memory leaking!!! --bao
|
||||
LLVolatileAPRPool *mLocalAPRFilePoolp ;
|
||||
//a local apr_pool for APRFile operations in this thread. If it exists, LLAPRFile::sAPRFilePoolp should not be used.
|
||||
//Note: this pool is used by APRFile ONLY, do NOT use it for any other purposes.
|
||||
// otherwise it will cause severe memory leaking!!! --bao
|
||||
LLVolatileAPRPool *mLocalAPRFilePoolp ;
|
||||
|
||||
void setQuitting();
|
||||
|
||||
// virtual function overridden by subclass -- this will be called when the thread runs
|
||||
virtual void run(void) = 0;
|
||||
|
||||
// virtual predicate function -- returns true if the thread should wake up, false if it should sleep.
|
||||
virtual bool runCondition(void);
|
||||
void setQuitting();
|
||||
|
||||
// virtual function overridden by subclass -- this will be called when the thread runs
|
||||
virtual void run(void) = 0;
|
||||
|
||||
// virtual predicate function -- returns true if the thread should wake up, false if it should sleep.
|
||||
virtual bool runCondition(void);
|
||||
|
||||
// Lock/Unlock Run Condition -- use around modification of any variable used in runCondition()
|
||||
inline void lockData();
|
||||
inline void unlockData();
|
||||
|
||||
// This is the predicate that decides whether the thread should sleep.
|
||||
// It should only be called with mDataLock locked, since the virtual runCondition() function may need to access
|
||||
// data structures that are thread-unsafe.
|
||||
bool shouldSleep(void) { return (mStatus == RUNNING) && (isPaused() || (!runCondition())); }
|
||||
// Lock/Unlock Run Condition -- use around modification of any variable used in runCondition()
|
||||
inline void lockData();
|
||||
inline void unlockData();
|
||||
|
||||
// This is the predicate that decides whether the thread should sleep.
|
||||
// It should only be called with mDataLock locked, since the virtual runCondition() function may need to access
|
||||
// data structures that are thread-unsafe.
|
||||
bool shouldSleep(void) { return (mStatus == RUNNING) && (isPaused() || (!runCondition())); }
|
||||
|
||||
// To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following:
|
||||
// mDataLock->lock();
|
||||
// if(!shouldSleep())
|
||||
// mRunCondition->signal();
|
||||
// mDataLock->unlock();
|
||||
// To avoid spurious signals (and the associated context switches) when the condition may or may not have changed, you can do the following:
|
||||
// mDataLock->lock();
|
||||
// if(!shouldSleep())
|
||||
// mRunCondition->signal();
|
||||
// mDataLock->unlock();
|
||||
};
|
||||
|
||||
|
||||
void LLThread::lockData()
|
||||
{
|
||||
mDataLock->lock();
|
||||
mDataLock->lock();
|
||||
}
|
||||
|
||||
void LLThread::unlockData()
|
||||
{
|
||||
mDataLock->unlock();
|
||||
mDataLock->unlock();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -160,9 +162,9 @@ void LLThread::unlockData()
|
|||
class LL_COMMON_API LLResponder : public LLThreadSafeRefCount
|
||||
{
|
||||
protected:
|
||||
virtual ~LLResponder();
|
||||
virtual ~LLResponder();
|
||||
public:
|
||||
virtual void completed(bool success) = 0;
|
||||
virtual void completed(bool success) = 0;
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class StatBase
|
|||
{
|
||||
public:
|
||||
StatBase(const char* name, const char* description);
|
||||
virtual ~StatBase() {};
|
||||
virtual ~StatBase() LLINSTANCETRACKER_DTOR_NOEXCEPT {}
|
||||
virtual const char* getUnitLabel() const;
|
||||
|
||||
const std::string& getName() const { return mName; }
|
||||
|
|
|
|||
|
|
@ -788,6 +788,69 @@ namespace tut
|
|||
|
||||
template<> template<>
|
||||
void object::test<10>()
|
||||
{
|
||||
set_test_name("attached=false");
|
||||
// almost just like autokill=false, except set autokill=true with
|
||||
// attached=false.
|
||||
NamedTempFile from("from", "not started");
|
||||
NamedTempFile to("to", "");
|
||||
LLProcess::handle phandle(0);
|
||||
{
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
"from __future__ import with_statement\n"
|
||||
"import sys, time\n"
|
||||
"with open(sys.argv[1], 'w') as f:\n"
|
||||
" f.write('ok')\n"
|
||||
"# wait for 'go' from test program\n"
|
||||
"for i in xrange(60):\n"
|
||||
" time.sleep(1)\n"
|
||||
" with open(sys.argv[2]) as f:\n"
|
||||
" go = f.read()\n"
|
||||
" if go == 'go':\n"
|
||||
" break\n"
|
||||
"else:\n"
|
||||
" with open(sys.argv[1], 'w') as f:\n"
|
||||
" f.write('never saw go')\n"
|
||||
" sys.exit(1)\n"
|
||||
"# okay, saw 'go', write 'ack'\n"
|
||||
"with open(sys.argv[1], 'w') as f:\n"
|
||||
" f.write('ack')\n");
|
||||
py.mParams.args.add(from.getName());
|
||||
py.mParams.args.add(to.getName());
|
||||
py.mParams.autokill = true;
|
||||
py.mParams.attached = false;
|
||||
py.launch();
|
||||
// Capture handle for later
|
||||
phandle = py.mPy->getProcessHandle();
|
||||
// Wait for the script to wake up and do its first write
|
||||
int i = 0, timeout = 60;
|
||||
for ( ; i < timeout; ++i)
|
||||
{
|
||||
yield();
|
||||
if (readfile(from.getName(), "from autokill script") == "ok")
|
||||
break;
|
||||
}
|
||||
// If we broke this loop because of the counter, something's wrong
|
||||
ensure("script never started", i < timeout);
|
||||
// Now destroy the LLProcess, which should NOT kill the child!
|
||||
}
|
||||
// If the destructor killed the child anyway, give it time to die
|
||||
yield(2);
|
||||
// How do we know it's not terminated? By making it respond to
|
||||
// a specific stimulus in a specific way.
|
||||
{
|
||||
std::ofstream outf(to.getName().c_str());
|
||||
outf << "go";
|
||||
} // flush and close.
|
||||
// now wait for the script to terminate... one way or another.
|
||||
waitfor(phandle, "autokill script");
|
||||
// If the LLProcess destructor implicitly called kill(), the
|
||||
// script could not have written 'ack' as we expect.
|
||||
ensure_equals(get_test_name() + " script output", readfile(from.getName()), "ack");
|
||||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<11>()
|
||||
{
|
||||
set_test_name("'bogus' test");
|
||||
CaptureLog recorder;
|
||||
|
|
@ -801,7 +864,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<11>()
|
||||
void object::test<12>()
|
||||
{
|
||||
set_test_name("'file' test");
|
||||
// Replace this test with one or more real 'file' tests when we
|
||||
|
|
@ -815,7 +878,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<12>()
|
||||
void object::test<13>()
|
||||
{
|
||||
set_test_name("'tpipe' test");
|
||||
// Replace this test with one or more real 'tpipe' tests when we
|
||||
|
|
@ -832,7 +895,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<13>()
|
||||
void object::test<14>()
|
||||
{
|
||||
set_test_name("'npipe' test");
|
||||
// Replace this test with one or more real 'npipe' tests when we
|
||||
|
|
@ -850,7 +913,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<14>()
|
||||
void object::test<15>()
|
||||
{
|
||||
set_test_name("internal pipe name warning");
|
||||
CaptureLog recorder;
|
||||
|
|
@ -914,7 +977,7 @@ namespace tut
|
|||
} while (0)
|
||||
|
||||
template<> template<>
|
||||
void object::test<15>()
|
||||
void object::test<16>()
|
||||
{
|
||||
set_test_name("get*Pipe() validation");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
|
|
@ -934,7 +997,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<16>()
|
||||
void object::test<17>()
|
||||
{
|
||||
set_test_name("talk to stdin/stdout");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
|
|
@ -992,7 +1055,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<17>()
|
||||
void object::test<18>()
|
||||
{
|
||||
set_test_name("listen for ReadPipe events");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
|
|
@ -1052,7 +1115,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<18>()
|
||||
void object::test<19>()
|
||||
{
|
||||
set_test_name("ReadPipe \"eof\" event");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
|
|
@ -1078,7 +1141,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<19>()
|
||||
void object::test<20>()
|
||||
{
|
||||
set_test_name("setLimit()");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
|
|
@ -1107,7 +1170,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<20>()
|
||||
void object::test<21>()
|
||||
{
|
||||
set_test_name("peek() ReadPipe data");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
|
|
@ -1160,7 +1223,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<21>()
|
||||
void object::test<22>()
|
||||
{
|
||||
set_test_name("bad postend");
|
||||
std::string pumpname("postend");
|
||||
|
|
@ -1185,7 +1248,7 @@ namespace tut
|
|||
}
|
||||
|
||||
template<> template<>
|
||||
void object::test<22>()
|
||||
void object::test<23>()
|
||||
{
|
||||
set_test_name("good postend");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
|
|
@ -1241,7 +1304,7 @@ namespace tut
|
|||
};
|
||||
|
||||
template<> template<>
|
||||
void object::test<23>()
|
||||
void object::test<24>()
|
||||
{
|
||||
set_test_name("all data visible at postend");
|
||||
PythonProcessLauncher py(get_test_name(),
|
||||
|
|
|
|||
|
|
@ -1553,7 +1553,7 @@ namespace tut
|
|||
params.executable = PYTHON;
|
||||
params.args.add(scriptfile.getName());
|
||||
LLProcessPtr py(LLProcess::create(params));
|
||||
ensure(STRINGIZE("Couldn't launch " << desc << " script"), py);
|
||||
ensure(STRINGIZE("Couldn't launch " << desc << " script"), bool(py));
|
||||
// Implementing timeout would mean messing with alarm() and
|
||||
// catching SIGALRM... later maybe...
|
||||
int status(0);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ include(00-Common)
|
|||
|
||||
include(CURL)
|
||||
include(OpenSSL)
|
||||
include(NGHTTP2)
|
||||
include(ZLIB)
|
||||
include(LLCoreHttp)
|
||||
include(LLAddBuildTest)
|
||||
|
|
@ -34,6 +35,7 @@ set(llcorehttp_SOURCE_FILES
|
|||
httpoptions.cpp
|
||||
httprequest.cpp
|
||||
httpresponse.cpp
|
||||
httpstats.cpp
|
||||
_httplibcurl.cpp
|
||||
_httpopcancel.cpp
|
||||
_httpoperation.cpp
|
||||
|
|
@ -61,6 +63,7 @@ set(llcorehttp_HEADER_FILES
|
|||
httpoptions.h
|
||||
httprequest.h
|
||||
httpresponse.h
|
||||
httpstats.h
|
||||
_httpinternal.h
|
||||
_httplibcurl.h
|
||||
_httpopcancel.h
|
||||
|
|
@ -96,6 +99,7 @@ target_link_libraries(
|
|||
${CURL_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CRYPTO_LIBRARIES}
|
||||
${NGHTTP2_LIBRARIES}
|
||||
${BOOST_THREAD_LIBRARY}
|
||||
${BOOST_SYSTEM_LIBRARY}
|
||||
)
|
||||
|
|
@ -134,6 +138,7 @@ if (LL_TESTS)
|
|||
${CURL_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CRYPTO_LIBRARIES}
|
||||
${NGHTTP2_LIBRARIES}
|
||||
${BOOST_THREAD_LIBRARY}
|
||||
${BOOST_SYSTEM_LIBRARY}
|
||||
)
|
||||
|
|
@ -152,7 +157,7 @@ if (LL_TESTS)
|
|||
if (DARWIN)
|
||||
# Path inside the app bundle where we'll need to copy libraries
|
||||
set(LL_TEST_DESTINATION_DIR
|
||||
${CMAKE_SOURCE_DIR}/../build-darwin-i386/sharedlibs/Resources
|
||||
${CMAKE_BINARY_DIR}/sharedlibs/Resources
|
||||
)
|
||||
|
||||
# Create the Contents/Resources directory
|
||||
|
|
@ -168,21 +173,23 @@ if (DARWIN)
|
|||
|
||||
# Copy the required libraries to the package app
|
||||
add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib ${LL_TEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libapr-1.0.dylib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib ${LL_TEST_DESTINATION_DIR}
|
||||
DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libapr-1.0.dylib
|
||||
)
|
||||
add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib ${LL_TEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libaprutil-1.0.dylib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib ${LL_TEST_DESTINATION_DIR}
|
||||
DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libaprutil-1.0.dylib
|
||||
)
|
||||
add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib ${LL_TEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexception_handler.dylib
|
||||
)
|
||||
add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib ${LL_TEST_DESTINATION_DIR}
|
||||
DEPENDS ${CMAKE_SOURCE_DIR}/../build-darwin-i386/packages/lib/release/libexpat.1.5.2.dylib
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib ${LL_TEST_DESTINATION_DIR}
|
||||
DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/libexception_handler.dylib
|
||||
)
|
||||
foreach(expat ${EXPAT_COPY})
|
||||
add_custom_command(TARGET INTEGRATION_TEST_llcorehttp PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat} ${LL_TEST_DESTINATION_DIR}
|
||||
DEPENDS ${AUTOBUILD_INSTALL_DIR}/lib/release/${expat}
|
||||
)
|
||||
endforeach(expat)
|
||||
|
||||
endif (DARWIN)
|
||||
|
||||
|
|
@ -202,6 +209,7 @@ endif (DARWIN)
|
|||
${CURL_LIBRARIES}
|
||||
${OPENSSL_LIBRARIES}
|
||||
${CRYPTO_LIBRARIES}
|
||||
${NGHTTP2_LIBRARIES}
|
||||
${BOOST_THREAD_LIBRARY}
|
||||
${BOOST_SYSTEM_LIBRARY}
|
||||
)
|
||||
|
|
@ -218,7 +226,7 @@ endif (DARWIN)
|
|||
# The following come from LLAddBuildTest.cmake's INTEGRATION_TEST_xxxx target.
|
||||
set_target_properties(http_texture_load
|
||||
PROPERTIES
|
||||
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE ${TCMALLOC_LINK_FLAGS}"
|
||||
LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE"
|
||||
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
|
||||
LINK_FLAGS_RELEASE ""
|
||||
)
|
||||
|
|
|
|||
|
|
@ -40,6 +40,15 @@ namespace
|
|||
void check_curl_multi_code(CURLMcode code);
|
||||
void check_curl_multi_code(CURLMcode code, int curl_setopt_option);
|
||||
|
||||
// This is a template because different 'option' values require different
|
||||
// types for 'ARG'. Just pass them through unchanged (by value).
|
||||
template <typename ARG>
|
||||
void check_curl_multi_setopt(CURLM* handle, CURLMoption option, ARG argument)
|
||||
{
|
||||
CURLMcode code = curl_multi_setopt(handle, option, argument);
|
||||
check_curl_multi_code(code, option);
|
||||
}
|
||||
|
||||
static const char * const LOG_CORE("CoreHttp");
|
||||
|
||||
} // end anonymous namespace
|
||||
|
|
@ -518,46 +527,38 @@ void HttpLibcurl::policyUpdated(int policy_class)
|
|||
|
||||
HttpPolicyClass & options(policy.getClassOptions(policy_class));
|
||||
CURLM * multi_handle(mMultiHandles[policy_class]);
|
||||
CURLMcode code;
|
||||
|
||||
// Enable policy if stalled
|
||||
policy.stallPolicy(policy_class, false);
|
||||
mDirtyPolicy[policy_class] = false;
|
||||
|
||||
|
||||
if (options.mPipelining > 1)
|
||||
{
|
||||
// We'll try to do pipelining on this multihandle
|
||||
code = curl_multi_setopt(multi_handle,
|
||||
check_curl_multi_setopt(multi_handle,
|
||||
CURLMOPT_PIPELINING,
|
||||
1L);
|
||||
check_curl_multi_code(code, CURLMOPT_PIPELINING);
|
||||
code = curl_multi_setopt(multi_handle,
|
||||
check_curl_multi_setopt(multi_handle,
|
||||
CURLMOPT_MAX_PIPELINE_LENGTH,
|
||||
long(options.mPipelining));
|
||||
check_curl_multi_code(code, CURLMOPT_MAX_PIPELINE_LENGTH);
|
||||
code = curl_multi_setopt(multi_handle,
|
||||
check_curl_multi_setopt(multi_handle,
|
||||
CURLMOPT_MAX_HOST_CONNECTIONS,
|
||||
long(options.mPerHostConnectionLimit));
|
||||
check_curl_multi_code(code, CURLMOPT_MAX_HOST_CONNECTIONS);
|
||||
code = curl_multi_setopt(multi_handle,
|
||||
check_curl_multi_setopt(multi_handle,
|
||||
CURLMOPT_MAX_TOTAL_CONNECTIONS,
|
||||
long(options.mConnectionLimit));
|
||||
check_curl_multi_code(code, CURLMOPT_MAX_TOTAL_CONNECTIONS);
|
||||
}
|
||||
else
|
||||
{
|
||||
code = curl_multi_setopt(multi_handle,
|
||||
check_curl_multi_setopt(multi_handle,
|
||||
CURLMOPT_PIPELINING,
|
||||
0L);
|
||||
check_curl_multi_code(code, CURLMOPT_PIPELINING);
|
||||
code = curl_multi_setopt(multi_handle,
|
||||
check_curl_multi_setopt(multi_handle,
|
||||
CURLMOPT_MAX_HOST_CONNECTIONS,
|
||||
0L);
|
||||
check_curl_multi_code(code, CURLMOPT_MAX_HOST_CONNECTIONS);
|
||||
code = curl_multi_setopt(multi_handle,
|
||||
check_curl_multi_setopt(multi_handle,
|
||||
CURLMOPT_MAX_TOTAL_CONNECTIONS,
|
||||
long(options.mConnectionLimit));
|
||||
check_curl_multi_code(code, CURLMOPT_MAX_TOTAL_CONNECTIONS);
|
||||
}
|
||||
}
|
||||
else if (! mDirtyPolicy[policy_class])
|
||||
|
|
|
|||
|
|
@ -47,6 +47,8 @@
|
|||
#include "llhttpconstants.h"
|
||||
#include "llproxy.h"
|
||||
|
||||
#include "httpstats.h"
|
||||
|
||||
// *DEBUG: "[curl:bugs] #1420" problem and testing.
|
||||
//
|
||||
// A pipelining problem, https://sourceforge.net/p/curl/bugs/1420/,
|
||||
|
|
@ -106,6 +108,15 @@ void os_strlower(char * str);
|
|||
// Error testing and reporting for libcurl status codes
|
||||
void check_curl_easy_code(CURLcode code, int curl_setopt_option);
|
||||
|
||||
// This is a template because different 'option' values require different
|
||||
// types for 'ARG'. Just pass them through unchanged (by value).
|
||||
template <typename ARG>
|
||||
void check_curl_easy_setopt(CURL* handle, CURLoption option, ARG argument)
|
||||
{
|
||||
CURLcode code = curl_easy_setopt(handle, option, argument);
|
||||
check_curl_easy_code(code, option);
|
||||
}
|
||||
|
||||
static const char * const LOG_CORE("CoreHttp");
|
||||
|
||||
} // end anonymous namespace
|
||||
|
|
@ -247,6 +258,8 @@ void HttpOpRequest::visitNotifier(HttpRequest * request)
|
|||
response->setHeaders(mReplyHeaders);
|
||||
response->setRequestURL(mReqURL);
|
||||
|
||||
response->setRequestMethod(methodToString(mReqMethod));
|
||||
|
||||
if (mReplyOffset || mReplyLength)
|
||||
{
|
||||
// Got an explicit offset/length in response
|
||||
|
|
@ -452,8 +465,6 @@ void HttpOpRequest::setupCommon(HttpRequest::policy_t policy_id,
|
|||
// *TODO: Move this to _httplibcurl where it belongs.
|
||||
HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
||||
{
|
||||
CURLcode code;
|
||||
|
||||
// Scrub transport and result data for retried op case
|
||||
mCurlActive = false;
|
||||
mCurlHandle = NULL;
|
||||
|
|
@ -492,45 +503,28 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
return HttpStatus(HttpStatus::LLCORE, HE_BAD_ALLOC);
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
check_curl_easy_code(code, CURLOPT_IPRESOLVE);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
|
||||
check_curl_easy_code(code, CURLOPT_NOSIGNAL);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1);
|
||||
check_curl_easy_code(code, CURLOPT_NOPROGRESS);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str());
|
||||
check_curl_easy_code(code, CURLOPT_URL);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, getHandle());
|
||||
check_curl_easy_code(code, CURLOPT_PRIVATE);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
|
||||
check_curl_easy_code(code, CURLOPT_ENCODING);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_NOSIGNAL, 1);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_NOPROGRESS, 1);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_URL, mReqURL.c_str());
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_PRIVATE, getHandle());
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
|
||||
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
|
||||
check_curl_easy_code(code, CURLOPT_AUTOREFERER);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
|
||||
check_curl_easy_code(code, CURLOPT_MAXREDIRS);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
|
||||
check_curl_easy_code(code, CURLOPT_WRITEFUNCTION);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, getHandle());
|
||||
check_curl_easy_code(code, CURLOPT_WRITEDATA);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
|
||||
check_curl_easy_code(code, CURLOPT_READFUNCTION);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, getHandle());
|
||||
check_curl_easy_code(code, CURLOPT_READDATA);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKFUNCTION, seekCallback);
|
||||
check_curl_easy_code(code, CURLOPT_SEEKFUNCTION);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, getHandle());
|
||||
check_curl_easy_code(code, CURLOPT_SEEKDATA);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_AUTOREFERER, 1);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_MAXREDIRS, HTTP_REDIRECTS_DEFAULT);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_WRITEDATA, getHandle());
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_READFUNCTION, readCallback);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_READDATA, getHandle());
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_SEEKFUNCTION, seekCallback);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_SEEKDATA, getHandle());
|
||||
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, "");
|
||||
check_curl_easy_code(code, CURLOPT_COOKIEFILE);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_COOKIEFILE, "");
|
||||
|
||||
if (gpolicy.mSslCtxCallback)
|
||||
{
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback);
|
||||
check_curl_easy_code(code, CURLOPT_SSL_CTX_FUNCTION);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, getHandle());
|
||||
check_curl_easy_code(code, CURLOPT_SSL_CTX_DATA);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_FUNCTION, curlSslCtxCallback);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_CTX_DATA, getHandle());
|
||||
mCallbackSSLVerify = gpolicy.mSslCtxCallback;
|
||||
}
|
||||
|
||||
|
|
@ -550,24 +544,18 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
nobody = mReqOptions->getHeadersOnly() ? 1L : 0L;
|
||||
last_modified = mReqOptions->getLastModified(); // <FS:Ansariel> GetIfModified request
|
||||
}
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
|
||||
check_curl_easy_code(code, CURLOPT_FOLLOWLOCATION);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_FOLLOWLOCATION, follow_redirect);
|
||||
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, sslPeerV);
|
||||
check_curl_easy_code(code, CURLOPT_SSL_VERIFYPEER);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV);
|
||||
check_curl_easy_code(code, CURLOPT_SSL_VERIFYHOST);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYPEER, sslPeerV);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_SSL_VERIFYHOST, sslHostV);
|
||||
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);
|
||||
check_curl_easy_code(code, CURLOPT_NOBODY);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_NOBODY, nobody);
|
||||
|
||||
// <FS:Ansariel> GetIfModified request
|
||||
if (last_modified > 0)
|
||||
{
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
||||
check_curl_easy_code(code, CURLOPT_TIMECONDITION);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE, last_modified);
|
||||
check_curl_easy_code(code, CURLOPT_TIMEVALUE);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMECONDITION, CURL_TIMECOND_IFMODSINCE);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEVALUE, last_modified);
|
||||
}
|
||||
// </FS:Ansariel>
|
||||
|
||||
|
|
@ -577,8 +565,7 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
// about 700 or so requests and starts issuing TCP RSTs to
|
||||
// new connections. Reuse the DNS lookups for even a few
|
||||
// seconds and no RSTs.
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);
|
||||
check_curl_easy_code(code, CURLOPT_DNS_CACHE_TIMEOUT);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout);
|
||||
|
||||
if (gpolicy.mUseLLProxy)
|
||||
{
|
||||
|
|
@ -601,81 +588,66 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
{
|
||||
// *TODO: This is fine for now but get fuller socks5/
|
||||
// authentication thing going later....
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, gpolicy.mHttpProxy.c_str());
|
||||
check_curl_easy_code(code, CURLOPT_PROXY);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
check_curl_easy_code(code, CURLOPT_PROXYTYPE);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_PROXY, gpolicy.mHttpProxy.c_str());
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
}
|
||||
if (gpolicy.mCAPath.size())
|
||||
{
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, gpolicy.mCAPath.c_str());
|
||||
check_curl_easy_code(code, CURLOPT_CAPATH);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_CAPATH, gpolicy.mCAPath.c_str());
|
||||
}
|
||||
if (gpolicy.mCAFile.size())
|
||||
{
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, gpolicy.mCAFile.c_str());
|
||||
check_curl_easy_code(code, CURLOPT_CAINFO);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_CAINFO, gpolicy.mCAFile.c_str());
|
||||
}
|
||||
|
||||
switch (mReqMethod)
|
||||
{
|
||||
case HOR_GET:
|
||||
if (nobody == 0)
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
|
||||
check_curl_easy_code(code, CURLOPT_HTTPGET);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTPGET, 1);
|
||||
break;
|
||||
|
||||
case HOR_POST:
|
||||
{
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1);
|
||||
check_curl_easy_code(code, CURLOPT_POST);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
|
||||
check_curl_easy_code(code, CURLOPT_ENCODING);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_POST, 1);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_ENCODING, "");
|
||||
long data_size(0);
|
||||
if (mReqBody)
|
||||
{
|
||||
data_size = mReqBody->size();
|
||||
}
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL));
|
||||
check_curl_easy_code(code, CURLOPT_POSTFIELDS);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
|
||||
check_curl_easy_code(code, CURLOPT_POSTFIELDSIZE);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDS, static_cast<void *>(NULL));
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_POSTFIELDSIZE, data_size);
|
||||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
|
||||
}
|
||||
break;
|
||||
|
||||
case HOR_PATCH:
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "PATCH");
|
||||
// fall through. The rest is the same as PUT
|
||||
case HOR_PUT:
|
||||
{
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
|
||||
check_curl_easy_code(code, CURLOPT_UPLOAD);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_UPLOAD, 1);
|
||||
long data_size(0);
|
||||
if (mReqBody)
|
||||
{
|
||||
data_size = mReqBody->size();
|
||||
}
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
|
||||
check_curl_easy_code(code, CURLOPT_INFILESIZE);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_INFILESIZE, data_size);
|
||||
mCurlHeaders = curl_slist_append(mCurlHeaders, "Expect:");
|
||||
}
|
||||
break;
|
||||
|
||||
case HOR_DELETE:
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
break;
|
||||
|
||||
case HOR_COPY:
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "COPY");
|
||||
check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "COPY");
|
||||
break;
|
||||
|
||||
case HOR_MOVE:
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "MOVE");
|
||||
check_curl_easy_code(code, CURLOPT_CUSTOMREQUEST);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_CUSTOMREQUEST, "MOVE");
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
@ -693,12 +665,9 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
// Tracing
|
||||
if (mTracing >= HTTP_TRACE_CURL_HEADERS)
|
||||
{
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1);
|
||||
check_curl_easy_code(code, CURLOPT_VERBOSE);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this);
|
||||
check_curl_easy_code(code, CURLOPT_DEBUGDATA);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback);
|
||||
check_curl_easy_code(code, CURLOPT_DEBUGFUNCTION);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_VERBOSE, 1);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGDATA, this);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_DEBUGFUNCTION, debugCallback);
|
||||
}
|
||||
|
||||
// There's a CURLOPT for this now...
|
||||
|
|
@ -775,6 +744,13 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
//
|
||||
// xfer_timeout *= cpolicy.mPipelining;
|
||||
xfer_timeout *= 2L;
|
||||
|
||||
// Also try requesting HTTP/2.
|
||||
/******************************/
|
||||
// but for test purposes, only if overriding VIEWERASSET
|
||||
if (getenv("VIEWERASSET"))
|
||||
/******************************/
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
}
|
||||
// *DEBUG: Enable following override for timeout handling and "[curl:bugs] #1420" tests
|
||||
//if (cpolicy.mPipelining)
|
||||
|
|
@ -782,10 +758,8 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
// xfer_timeout = 1L;
|
||||
// timeout = 1L;
|
||||
//}
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, xfer_timeout);
|
||||
check_curl_easy_code(code, CURLOPT_TIMEOUT);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout);
|
||||
check_curl_easy_code(code, CURLOPT_CONNECTTIMEOUT);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_TIMEOUT, xfer_timeout);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_CONNECTTIMEOUT, timeout);
|
||||
|
||||
// Request headers
|
||||
if (mReqHeaders)
|
||||
|
|
@ -793,15 +767,12 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service)
|
|||
// Caller's headers last to override
|
||||
mCurlHeaders = append_headers_to_slist(mReqHeaders, mCurlHeaders);
|
||||
}
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders);
|
||||
check_curl_easy_code(code, CURLOPT_HTTPHEADER);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_HTTPHEADER, mCurlHeaders);
|
||||
|
||||
if (mProcFlags & (PF_SCAN_RANGE_HEADER | PF_SAVE_HEADERS | PF_USE_RETRY_AFTER))
|
||||
{
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback);
|
||||
check_curl_easy_code(code, CURLOPT_HEADERFUNCTION);
|
||||
code = curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this);
|
||||
check_curl_easy_code(code, CURLOPT_HEADERDATA);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_HEADERFUNCTION, headerCallback);
|
||||
check_curl_easy_setopt(mCurlHandle, CURLOPT_HEADERDATA, this);
|
||||
}
|
||||
|
||||
if (status)
|
||||
|
|
@ -822,6 +793,7 @@ size_t HttpOpRequest::writeCallback(void * data, size_t size, size_t nmemb, void
|
|||
}
|
||||
const size_t req_size(size * nmemb);
|
||||
const size_t write_size(op->mReplyBody->append(static_cast<char *>(data), req_size));
|
||||
HTTPStats::instance().recordDataDown(write_size);
|
||||
return write_size;
|
||||
}
|
||||
|
||||
|
|
@ -850,7 +822,8 @@ size_t HttpOpRequest::readCallback(void * data, size_t size, size_t nmemb, void
|
|||
|
||||
const size_t do_size((std::min)(req_size, body_size - op->mCurlBodyPos));
|
||||
const size_t read_size(op->mReqBody->read(op->mCurlBodyPos, static_cast<char *>(data), do_size));
|
||||
op->mCurlBodyPos += read_size;
|
||||
HTTPStats::instance().recordDataUp(read_size);
|
||||
op->mCurlBodyPos += read_size;
|
||||
return read_size;
|
||||
}
|
||||
|
||||
|
|
@ -1162,6 +1135,25 @@ int HttpOpRequest::debugCallback(CURL * handle, curl_infotype info, char * buffe
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::string HttpOpRequest::methodToString(const HttpOpRequest::EMethod &e)
|
||||
{
|
||||
if (e == HOR_COPY)
|
||||
return "COPY";
|
||||
else if (e == HOR_DELETE)
|
||||
return "DELETE";
|
||||
else if (e == HOR_GET)
|
||||
return "GET";
|
||||
else if (e == HOR_MOVE)
|
||||
return "MOVE";
|
||||
else if (e == HOR_PATCH)
|
||||
return "PATCH";
|
||||
else if (e == HOR_POST)
|
||||
return "POST";
|
||||
else if (e == HOR_PUT)
|
||||
return "PUT";
|
||||
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
} // end namespace LLCore
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,8 @@ public:
|
|||
HOR_COPY,
|
||||
HOR_MOVE
|
||||
};
|
||||
|
||||
static std::string methodToString(const EMethod &);
|
||||
|
||||
virtual void stageFromRequest(HttpService *);
|
||||
virtual void stageFromReady(HttpService *);
|
||||
virtual void stageFromActive(HttpService *);
|
||||
|
|
@ -237,6 +238,7 @@ public:
|
|||
}; // end class HttpOpRequest
|
||||
|
||||
|
||||
|
||||
/// HttpOpRequestCompare isn't an operation but a uniform comparison
|
||||
/// functor for STL containers that order by priority. Mainly
|
||||
/// used for the ready queue container but defined here.
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "_httppolicyclass.h"
|
||||
|
||||
#include "lltimer.h"
|
||||
#include "httpstats.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
|
@ -444,6 +445,8 @@ bool HttpPolicy::stageAfterCompletion(const HttpOpRequest::ptr_t &op)
|
|||
}
|
||||
|
||||
op->stageFromActive(mService);
|
||||
|
||||
HTTPStats::instance().recordResultCode(op->mStatus.getType());
|
||||
return false; // not active
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@
|
|||
|
||||
#include "lltimer.h"
|
||||
#include "llthread.h"
|
||||
|
||||
#include "llexception.h"
|
||||
#include "llmemory.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
|
@ -293,22 +294,42 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
|
|||
ELoopSpeed loop(REQUEST_SLEEP);
|
||||
while (! mExitRequested)
|
||||
{
|
||||
loop = processRequestQueue(loop);
|
||||
try
|
||||
{
|
||||
loop = processRequestQueue(loop);
|
||||
|
||||
// Process ready queue issuing new requests as needed
|
||||
ELoopSpeed new_loop = mPolicy->processReadyQueue();
|
||||
loop = (std::min)(loop, new_loop);
|
||||
// Process ready queue issuing new requests as needed
|
||||
ELoopSpeed new_loop = mPolicy->processReadyQueue();
|
||||
loop = (std::min)(loop, new_loop);
|
||||
|
||||
// Give libcurl some cycles
|
||||
new_loop = mTransport->processTransport();
|
||||
loop = (std::min)(loop, new_loop);
|
||||
// Give libcurl some cycles
|
||||
new_loop = mTransport->processTransport();
|
||||
loop = (std::min)(loop, new_loop);
|
||||
|
||||
// Determine whether to spin, sleep briefly or sleep for next request
|
||||
if (REQUEST_SLEEP != loop)
|
||||
{
|
||||
ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS);
|
||||
}
|
||||
}
|
||||
// Determine whether to spin, sleep briefly or sleep for next request
|
||||
if (REQUEST_SLEEP != loop)
|
||||
{
|
||||
ms_sleep(HTTP_SERVICE_LOOP_SLEEP_NORMAL_MS);
|
||||
}
|
||||
}
|
||||
catch (const LLContinueError&)
|
||||
{
|
||||
LOG_UNHANDLED_EXCEPTION("");
|
||||
}
|
||||
catch (std::bad_alloc)
|
||||
{
|
||||
LLMemory::logMemoryInfo(TRUE);
|
||||
|
||||
//output possible call stacks to log file.
|
||||
LLError::LLCallStacks::print();
|
||||
|
||||
LL_ERRS() << "Bad memory allocation in HttpService::threadRun()!" << LL_ENDL;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
CRASH_ON_UNHANDLED_EXCEPTION("");
|
||||
}
|
||||
}
|
||||
|
||||
shutdown();
|
||||
sState = STOPPED;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
*/
|
||||
|
||||
#include "bufferarray.h"
|
||||
#include "llexception.h"
|
||||
#include "llmemory.h"
|
||||
|
||||
|
||||
// BufferArray is a list of chunks, each a BufferArray::Block, of contiguous
|
||||
|
|
@ -140,8 +142,22 @@ size_t BufferArray::append(const void * src, size_t len)
|
|||
{
|
||||
mBlocks.reserve(mBlocks.size() + 5);
|
||||
}
|
||||
Block * block = Block::alloc(BLOCK_ALLOC_SIZE);
|
||||
memcpy(block->mData, c_src, copy_len);
|
||||
Block * block;
|
||||
try
|
||||
{
|
||||
block = Block::alloc(BLOCK_ALLOC_SIZE);
|
||||
}
|
||||
catch (std::bad_alloc)
|
||||
{
|
||||
LLMemory::logMemoryInfo(TRUE);
|
||||
|
||||
//output possible call stacks to log file.
|
||||
LLError::LLCallStacks::print();
|
||||
|
||||
LL_WARNS() << "Bad memory allocation in thrown by Block::alloc in read!" << LL_ENDL;
|
||||
break;
|
||||
}
|
||||
memcpy(block->mData, c_src, copy_len);
|
||||
block->mUsed = copy_len;
|
||||
llassert_always(block->mUsed <= block->mAlloced);
|
||||
mBlocks.push_back(block);
|
||||
|
|
@ -149,7 +165,7 @@ size_t BufferArray::append(const void * src, size_t len)
|
|||
c_src += copy_len;
|
||||
len -= copy_len;
|
||||
}
|
||||
return ret;
|
||||
return ret - len;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -50,14 +50,12 @@ HttpStatus::type_enum_t EXT_CURL_EASY;
|
|||
HttpStatus::type_enum_t EXT_CURL_MULTI;
|
||||
HttpStatus::type_enum_t LLCORE;
|
||||
|
||||
HttpStatus::operator unsigned long() const
|
||||
HttpStatus::operator U32() const
|
||||
{
|
||||
// <FS:ND> 64 bit compatibility
|
||||
// static const int shift(sizeof(unsigned long) * 4);
|
||||
static const int shift(sizeof(4 * 4));
|
||||
// </FS:ND>
|
||||
// Effectively, concatenate mType (high) with mStatus (low).
|
||||
static const int shift(sizeof(mDetails->mStatus) * 8);
|
||||
|
||||
unsigned long result(((unsigned long)mDetails->mType) << shift | (unsigned long)(int)mDetails->mStatus);
|
||||
U32 result(U32(mDetails->mType) << shift | U32((int)mDetails->mStatus));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +65,7 @@ std::string HttpStatus::toHex() const
|
|||
std::ostringstream result;
|
||||
result.width(8);
|
||||
result.fill('0');
|
||||
result << std::hex << operator unsigned long() << std::dec;
|
||||
result << std::hex << operator U32();
|
||||
return result.str();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -383,10 +383,10 @@ struct HttpStatus
|
|||
/// creates an ambiguous second path to integer conversion
|
||||
/// which tends to find programming errors such as formatting
|
||||
/// the status to a stream (operator<<).
|
||||
operator unsigned long() const;
|
||||
unsigned long toULong() const
|
||||
operator U32() const;
|
||||
U32 toULong() const
|
||||
{
|
||||
return operator unsigned long();
|
||||
return operator U32();
|
||||
}
|
||||
|
||||
/// And to convert to a hex string.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#include "_httpopsetget.h"
|
||||
|
||||
#include "lltimer.h"
|
||||
|
||||
#include "httpstats.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
|
@ -62,6 +62,8 @@ HttpRequest::HttpRequest()
|
|||
mRequestQueue->addRef();
|
||||
|
||||
mReplyQueue.reset( new HttpReplyQueue() );
|
||||
|
||||
HTTPStats::instance().recordHTTPRequest();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -680,7 +680,7 @@ private:
|
|||
/// @}
|
||||
// End Global State
|
||||
// ====================================
|
||||
|
||||
|
||||
}; // end class HttpRequest
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -204,6 +204,15 @@ public:
|
|||
return mRequestUrl;
|
||||
}
|
||||
|
||||
void setRequestMethod(const std::string &method)
|
||||
{
|
||||
mRequestMethod = method;
|
||||
}
|
||||
|
||||
const std::string &getRequestMethod() const
|
||||
{
|
||||
return mRequestMethod;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Response data here
|
||||
|
|
@ -217,6 +226,7 @@ protected:
|
|||
unsigned int mRetries;
|
||||
unsigned int m503Retries;
|
||||
std::string mRequestUrl;
|
||||
std::string mRequestMethod;
|
||||
|
||||
TransferStats::ptr_t mStats;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* @file llviewerstats.cpp
|
||||
* @brief LLViewerStats class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#include "httpstats.h"
|
||||
#include "llerror.h"
|
||||
|
||||
namespace LLCore
|
||||
{
|
||||
HTTPStats::HTTPStats()
|
||||
{
|
||||
resetStats();
|
||||
}
|
||||
|
||||
|
||||
HTTPStats::~HTTPStats()
|
||||
{
|
||||
}
|
||||
|
||||
void HTTPStats::resetStats()
|
||||
{
|
||||
mResutCodes.clear();
|
||||
mDataDown.reset();
|
||||
mDataUp.reset();
|
||||
mRequests = 0;
|
||||
}
|
||||
|
||||
|
||||
void HTTPStats::recordResultCode(S32 code)
|
||||
{
|
||||
std::map<S32, S32>::iterator it;
|
||||
|
||||
it = mResutCodes.find(code);
|
||||
|
||||
if (it == mResutCodes.end())
|
||||
mResutCodes[code] = 1;
|
||||
else
|
||||
(*it).second = (*it).second + 1;
|
||||
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string byte_count_converter(F32 bytes)
|
||||
{
|
||||
static const char unit_suffix[] = { 'B', 'K', 'M', 'G' };
|
||||
|
||||
F32 value = bytes;
|
||||
int suffix = 0;
|
||||
|
||||
while ((value > 1024.0) && (suffix < 3))
|
||||
{
|
||||
value /= 1024.0;
|
||||
++suffix;
|
||||
}
|
||||
|
||||
std::stringstream out;
|
||||
|
||||
out << std::setprecision(4) << value << unit_suffix[suffix];
|
||||
|
||||
return out.str();
|
||||
}
|
||||
}
|
||||
|
||||
void HTTPStats::dumpStats()
|
||||
{
|
||||
std::stringstream out;
|
||||
|
||||
out << "HTTP DATA SUMMARY" << std::endl;
|
||||
out << "HTTP Transfer counts:" << std::endl;
|
||||
out << "Data Sent: " << byte_count_converter(mDataUp.getSum()) << " (" << mDataUp.getSum() << ")" << std::endl;
|
||||
out << "Data Recv: " << byte_count_converter(mDataDown.getSum()) << " (" << mDataDown.getSum() << ")" << std::endl;
|
||||
out << "Total requests: " << mRequests << "(request objects created)" << std::endl;
|
||||
out << std::endl;
|
||||
out << "Result Codes:" << std::endl << "--- -----" << std::endl;
|
||||
|
||||
for (std::map<S32, S32>::iterator it = mResutCodes.begin(); it != mResutCodes.end(); ++it)
|
||||
{
|
||||
out << (*it).first << " " << (*it).second << std::endl;
|
||||
}
|
||||
|
||||
LL_WARNS("HTTP Core") << out.str() << LL_ENDL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* @file llviewerim_peningtats.h
|
||||
* @brief LLViewerStats class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, 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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLVIEWERSTATS_H
|
||||
#define LL_LLVIEWERSTATS_H
|
||||
|
||||
#include "lltracerecording.h"
|
||||
#include "lltrace.h"
|
||||
#include "llstatsaccumulator.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llsd.h"
|
||||
|
||||
namespace LLCore
|
||||
{
|
||||
class HTTPStats : public LLSingleton<HTTPStats>
|
||||
{
|
||||
LLSINGLETON(HTTPStats);
|
||||
virtual ~HTTPStats();
|
||||
|
||||
public:
|
||||
void resetStats();
|
||||
|
||||
typedef LLStatsAccumulator StatsAccumulator;
|
||||
|
||||
void recordDataDown(size_t bytes)
|
||||
{
|
||||
mDataDown.push(bytes);
|
||||
}
|
||||
|
||||
void recordDataUp(size_t bytes)
|
||||
{
|
||||
mDataUp.push(bytes);
|
||||
}
|
||||
|
||||
void recordHTTPRequest() { ++mRequests; }
|
||||
|
||||
void recordResultCode(S32 code);
|
||||
|
||||
void dumpStats();
|
||||
private:
|
||||
StatsAccumulator mDataDown;
|
||||
StatsAccumulator mDataUp;
|
||||
|
||||
S32 mRequests;
|
||||
|
||||
std::map<S32, S32> mResutCodes;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
#endif // LL_LLVIEWERSTATS_H
|
||||
|
|
@ -215,7 +215,8 @@ void HttpRequestTestObjectType::test<1>()
|
|||
HttpRequest::destroyService();
|
||||
|
||||
// make sure we didn't leak any memory
|
||||
ensure("Memory returned", mMemTotal == GetMemTotal());
|
||||
// nat 2017-08-15 don't: requires total stasis in every other subsystem
|
||||
// ensure("Memory returned", mMemTotal == GetMemTotal());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
@ -835,7 +836,7 @@ void HttpRequestTestObjectType::test<8>()
|
|||
|
||||
ensure("Two handler calls on the way out", 2 == mHandlerCalls);
|
||||
|
||||
#if defined(WIN32)
|
||||
#if 0 // defined(WIN32)
|
||||
// Can only do this memory test on Windows. On other platforms,
|
||||
// the LL logging system holds on to memory and produces what looks
|
||||
// like memory leaks...
|
||||
|
|
@ -946,7 +947,7 @@ void HttpRequestTestObjectType::test<9>()
|
|||
|
||||
ensure("Two handler calls on the way out", 2 == mHandlerCalls);
|
||||
|
||||
#if defined(WIN32)
|
||||
#if 0 // defined(WIN32)
|
||||
// Can only do this memory test on Windows. On other platforms,
|
||||
// the LL logging system holds on to memory and produces what looks
|
||||
// like memory leaks...
|
||||
|
|
@ -1182,7 +1183,7 @@ void HttpRequestTestObjectType::test<11>()
|
|||
|
||||
ensure("Two handler calls on the way out", 2 == mHandlerCalls);
|
||||
|
||||
#if defined(WIN32)
|
||||
#if 0 // defined(WIN32)
|
||||
// Can only do this memory test on Windows. On other platforms,
|
||||
// the LL logging system holds on to memory and produces what looks
|
||||
// like memory leaks...
|
||||
|
|
@ -1428,7 +1429,7 @@ void HttpRequestTestObjectType::test<13>()
|
|||
|
||||
ensure("Two handler calls on the way out", 2 == mHandlerCalls);
|
||||
|
||||
#if defined(WIN32)
|
||||
#if 0 // defined(WIN32)
|
||||
// Can only do this memory test on Windows. On other platforms,
|
||||
// the LL logging system holds on to memory and produces what looks
|
||||
// like memory leaks...
|
||||
|
|
@ -1662,7 +1663,7 @@ void HttpRequestTestObjectType::test<15>()
|
|||
|
||||
ensure("Two handler calls on the way out", 2 == mHandlerCalls);
|
||||
|
||||
#if defined(WIN32)
|
||||
#if 0 // defined(WIN32)
|
||||
// Can only do this memory test on Windows. On other platforms,
|
||||
// the LL logging system holds on to memory and produces what looks
|
||||
// like memory leaks...
|
||||
|
|
@ -3089,6 +3090,10 @@ void HttpRequestTestObjectType::test<23>()
|
|||
|
||||
set_test_name("HttpRequest GET 503s with 'Retry-After'");
|
||||
|
||||
#if LL_WINDOWS && ADDRESS_SIZE == 64
|
||||
skip("llcorehttp 503-with-retry test hangs on Windows 64");
|
||||
#endif
|
||||
|
||||
// This tests mainly that the code doesn't fall over if
|
||||
// various well- and mis-formed Retry-After headers are
|
||||
// sent along with the response. Direct inspection of
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ void HttpStatusTestObjectType::test<7>()
|
|||
HttpStatus status(404);
|
||||
std::string msg = status.toHex();
|
||||
// std::cout << "Result: " << msg << std::endl;
|
||||
ensure(msg == "01940001");
|
||||
ensure_equals(msg, "01940001");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -686,8 +686,8 @@ bool LLCrashLogger::init()
|
|||
LLCore::LLHttp::initialize();
|
||||
|
||||
// We assume that all the logs we're looking for reside on the current drive
|
||||
#ifdef ND_BUILD64BIT_ARCH
|
||||
gDirUtilp->initAppDirs("Firestorm_x64");
|
||||
#if ADDRESS_SIZE == 64
|
||||
gDirUtilp->initAppDirs( "Firestorm_x64" );
|
||||
#else
|
||||
gDirUtilp->initAppDirs("Firestorm");
|
||||
#endif
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue