mirror of
https://github.com/FirestormViewer/phoenix-firestorm.git
synced 2026-08-14 08:53:53 +00:00
Merge branch develop into project/fonts-update
# Conflicts: # indra/llrender/llfontfreetype.cpp
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
# Replace tabs with spaces
|
||||
1b68f71348ecf3983b76b40d7940da8377f049b7
|
||||
33418a77b716e122da9778869cdbabe97c83ff37
|
||||
6b974724826a038b0db794460b322eb4921da735
|
||||
# Trim trailing whitespace
|
||||
a0b3021bdcf76859054fda8e30abb3ed47749e83
|
||||
8444cd9562a6a7b755fcb075864e205122354192
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
* text eol=lf
|
||||
|
||||
# VSTool (normalization disabled)
|
||||
indra/tools/vstool/* -text
|
||||
|
||||
# Images
|
||||
*.bmp binary
|
||||
*.BMP binary
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: monthly
|
||||
+63
-35
@@ -1,81 +1,109 @@
|
||||
llappearance:
|
||||
- indra/llappearance/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llappearance/**
|
||||
|
||||
llaudio:
|
||||
- indra/llaudio/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llaudio/**
|
||||
|
||||
llcharacter:
|
||||
- indra/llcharacter/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llcharacter/**
|
||||
|
||||
llcommon:
|
||||
- indra/llcommon/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llcommon/**
|
||||
|
||||
llcorehttp:
|
||||
- indra/llcorehttp/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llcorehttp/**
|
||||
|
||||
llcrashlogger:
|
||||
- indra/llcrashlogger/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llcrashlogger/**
|
||||
|
||||
llfilesystem:
|
||||
- indra/llfilesystem/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llfilesystem/**
|
||||
|
||||
llimage:
|
||||
- indra/llimage/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llimage/**
|
||||
|
||||
llimagej2coj:
|
||||
- indra/llimagej2coj/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llimagej2coj/**
|
||||
|
||||
llinventory:
|
||||
- indra/llinventory/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llinventory/**
|
||||
|
||||
llkdu:
|
||||
- indra/llkdu/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llkdu/**
|
||||
|
||||
llmath:
|
||||
- indra/llmath/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llmath/**
|
||||
|
||||
llmeshoptimizer:
|
||||
- indra/llmeshoptimizer/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llmeshoptimizer/**
|
||||
|
||||
llmessage:
|
||||
- indra/llmessage/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llmessage/**
|
||||
|
||||
llplugin:
|
||||
- indra/llplugin/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llplugin/**
|
||||
|
||||
llprimitive:
|
||||
- indra/llprimitive/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llprimitive/**
|
||||
|
||||
llrender:
|
||||
- indra/llrender/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llrender/**
|
||||
|
||||
llui:
|
||||
- indra/llui/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llui/**
|
||||
|
||||
llwindow:
|
||||
- indra/llwindow/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llwindow/**
|
||||
|
||||
llxml:
|
||||
- indra/llxml/**/*
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: indra/llxml/**
|
||||
|
||||
cmake:
|
||||
- '**/*.cmake'
|
||||
- '**/*/cmake/*'
|
||||
- '**/CMakeLists.txt'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- '**/*.cmake'
|
||||
- '**/*/cmake/*'
|
||||
- '**/CMakeLists.txt'
|
||||
|
||||
python:
|
||||
- '**/*.py'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: '**/*.py'
|
||||
|
||||
c/cpp:
|
||||
- '**/*.c'
|
||||
- '**/*.cpp'
|
||||
- '**/*.cxx'
|
||||
- '**/*.h'
|
||||
- '**/*.hpp'
|
||||
- '**/*.hxx'
|
||||
- '**/*.i'
|
||||
- '**/*.inl'
|
||||
- '**/*.y'
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- '**/*.c'
|
||||
- '**/*.cpp'
|
||||
- '**/*.cxx'
|
||||
- '**/*.h'
|
||||
- '**/*.hpp'
|
||||
- '**/*.hxx'
|
||||
- '**/*.i'
|
||||
- '**/*.inl'
|
||||
- '**/*.y'
|
||||
|
||||
'team:viewer':
|
||||
- '*'
|
||||
objc:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- '**/*.m'
|
||||
- '**/*.mm'
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
## Description
|
||||
|
||||
<!--
|
||||
Describe what this PR changes or adds. Include any relevant context or motivation.
|
||||
-->
|
||||
|
||||
## Related Issues
|
||||
|
||||
- [ ] **Please link to a relevant GitHub issue for additional context.**
|
||||
- **Bug Fix:** Link to an issue that includes reproduction steps and testing guidance.
|
||||
- **Feature/Enhancement:** Link to an issue with a write-up, rationale, and requirements.
|
||||
|
||||
Issue Link: <!-- e.g., closes #123 or relates to #456 -->
|
||||
|
||||
---
|
||||
|
||||
## Checklist
|
||||
|
||||
Please ensure the following before requesting review:
|
||||
|
||||
- [ ] I have provided a clear title and detailed description for this pull request.
|
||||
- [ ] If useful, I have included media such as screenshots and video to show off my changes.
|
||||
- [ ] The PR is linked to a relevant issue with sufficient context.
|
||||
- [ ] I have tested the changes locally and verified they work as intended.
|
||||
- [ ] All new and existing tests pass.
|
||||
- [ ] Code follows the project's style guidelines.
|
||||
- [ ] Documentation has been updated if needed.
|
||||
- [ ] Any dependent changes have been merged and published in downstream modules
|
||||
- [ ] I have reviewed the [contributing guidelines](https://github.com/secondlife/viewer/blob/develop/CONTRIBUTING.md).
|
||||
|
||||
---
|
||||
|
||||
## Additional Notes
|
||||
|
||||
<!--
|
||||
Add any other information, screenshots, or suggestions for reviewers here.
|
||||
-->
|
||||
@@ -0,0 +1 @@
|
||||
qatest.yaml -text eol=crlf
|
||||
@@ -1,6 +1,7 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches: ["main", "release/*", "project/*"]
|
||||
@@ -42,8 +43,8 @@ jobs:
|
||||
needs: setup
|
||||
strategy:
|
||||
matrix:
|
||||
runner: [windows-large, macos-15-xlarge]
|
||||
configuration: ${{ fromJSON(needs.setup.outputs.configurations) }}
|
||||
runner: ${{ fromJson((github.ref_type == 'tag' && startsWith(github.ref, 'refs/tags/Second_Life')) && '["windows-large","macos-15-xlarge"]' || '["windows-2022","macos-15-xlarge"]') }}
|
||||
configuration: ${{ fromJson(needs.setup.outputs.configurations) }}
|
||||
runs-on: ${{ matrix.runner }}
|
||||
outputs:
|
||||
viewer_channel: ${{ steps.build.outputs.viewer_channel }}
|
||||
@@ -64,7 +65,7 @@ jobs:
|
||||
# autobuild-package.xml.
|
||||
AUTOBUILD_VCS_INFO: "true"
|
||||
AUTOBUILD_VSVER: "170"
|
||||
DEVELOPER_DIR: "/Applications/Xcode_16.1.app/Contents/Developer"
|
||||
DEVELOPER_DIR: "/Applications/Xcode_16.4.app/Contents/Developer"
|
||||
# Ensure that Linden viewer builds engage Bugsplat.
|
||||
BUGSPLAT_DB: ${{ needs.setup.outputs.bugsplat_db }}
|
||||
build_coverity: false
|
||||
@@ -85,24 +86,23 @@ jobs:
|
||||
variants: ${{ matrix.configuration }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||||
|
||||
- name: Setup python
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Checkout build variables
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: secondlife/build-variables
|
||||
ref: master
|
||||
path: .build-variables
|
||||
|
||||
- name: Checkout master-message-template
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: secondlife/master-message-template
|
||||
path: .master-message-template
|
||||
@@ -218,8 +218,10 @@ jobs:
|
||||
prefix=${ba[0]}
|
||||
if [ "$prefix" == "project" ]; then
|
||||
IFS='_' read -ra prj <<< "${ba[1]}"
|
||||
prj_str="${prj[*]}"
|
||||
# uppercase first letter of each word
|
||||
export viewer_channel="Second Life Project ${prj[*]^}"
|
||||
capitalized=$(echo "$prj_str" | awk '{for (i=1; i<=NF; i++) $i = toupper(substr($i,1,1)) substr($i,2); print}')
|
||||
export viewer_channel="Second Life Project $capitalized"
|
||||
elif [[ "$prefix" == "release" || "$prefix" == "main" ]];
|
||||
then
|
||||
export viewer_channel="Second Life Release"
|
||||
@@ -304,11 +306,11 @@ jobs:
|
||||
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
|
||||
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
|
||||
needs: build
|
||||
runs-on: windows-large
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Sign and package Windows viewer
|
||||
if: env.AZURE_KEY_VAULT_URI && env.AZURE_CERT_NAME && env.AZURE_CLIENT_ID && env.AZURE_CLIENT_SECRET && env.AZURE_TENANT_ID
|
||||
uses: secondlife/viewer-build-util/sign-pkg-windows@v2
|
||||
uses: secondlife/viewer-build-util/sign-pkg-windows@v2.0.4
|
||||
with:
|
||||
vault_uri: "${{ env.AZURE_KEY_VAULT_URI }}"
|
||||
cert_name: "${{ env.AZURE_CERT_NAME }}"
|
||||
@@ -360,8 +362,9 @@ jobs:
|
||||
|
||||
post-windows-symbols:
|
||||
env:
|
||||
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
|
||||
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
|
||||
BUGSPLAT_DATABASE: "${{ secrets.BUGSPLAT_DATABASE }}"
|
||||
SYMBOL_UPLOAD_CLIENT_ID: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_ID }}"
|
||||
SYMBOL_UPLOAD_CLIENT_SECRET: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_SECRET }}"
|
||||
needs: build
|
||||
if: needs.build.outputs.configuration == 'Release'
|
||||
runs-on: ubuntu-latest
|
||||
@@ -372,51 +375,56 @@ jobs:
|
||||
name: Windows-app
|
||||
path: _artifacts
|
||||
- name: Download Windows Symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: Windows-symbols
|
||||
- name: Extract viewer pdb
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
shell: bash
|
||||
run: |
|
||||
tar -xJf "${{ needs.build.outputs.viewer_channel }}.sym.tar.xz" -C _artifacts
|
||||
- name: Post Windows symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: secondlife-3p/symbol-upload@v10
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
uses: BugSplat-Git/symbol-upload@095d163ae9ceb006d286a731dcd35cf6a1b458c8
|
||||
with:
|
||||
username: ${{ env.BUGSPLAT_USER }}
|
||||
password: ${{ env.BUGSPLAT_PASS }}
|
||||
database: "SecondLife_Viewer_2018"
|
||||
clientId: "${{ env.SYMBOL_UPLOAD_CLIENT_ID }}"
|
||||
clientSecret: "${{ env.SYMBOL_UPLOAD_CLIENT_SECRET }}"
|
||||
database: "${{ env.BUGSPLAT_DATABASE }}"
|
||||
application: ${{ needs.build.outputs.viewer_channel }}
|
||||
version: ${{ needs.build.outputs.viewer_version }}
|
||||
directory: _artifacts
|
||||
files: "**/{SecondLifeViewer.exe,llwebrtc.dll,*.pdb}"
|
||||
node-version: "22"
|
||||
dumpSyms: false
|
||||
|
||||
post-mac-symbols:
|
||||
env:
|
||||
BUGSPLAT_USER: ${{ secrets.BUGSPLAT_USER }}
|
||||
BUGSPLAT_PASS: ${{ secrets.BUGSPLAT_PASS }}
|
||||
BUGSPLAT_DATABASE: "${{ secrets.BUGSPLAT_DATABASE }}"
|
||||
SYMBOL_UPLOAD_CLIENT_ID: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_ID }}"
|
||||
SYMBOL_UPLOAD_CLIENT_SECRET: "${{ secrets.BUGSPLAT_SYMBOL_UPLOAD_CLIENT_SECRET }}"
|
||||
needs: build
|
||||
if: needs.build.outputs.configuration == 'Release'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download Mac Symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: macOS-symbols
|
||||
- name: Post Mac symbols
|
||||
if: env.BUGSPLAT_USER && env.BUGSPLAT_PASS
|
||||
uses: secondlife-3p/symbol-upload@v10
|
||||
if: env.BUGSPLAT_DATABASE && env.SYMBOL_UPLOAD_CLIENT_ID
|
||||
uses: BugSplat-Git/symbol-upload@095d163ae9ceb006d286a731dcd35cf6a1b458c8
|
||||
with:
|
||||
username: ${{ env.BUGSPLAT_USER }}
|
||||
password: ${{ env.BUGSPLAT_PASS }}
|
||||
database: "SecondLife_Viewer_2018"
|
||||
clientId: "${{ env.SYMBOL_UPLOAD_CLIENT_ID }}"
|
||||
clientSecret: "${{ env.SYMBOL_UPLOAD_CLIENT_SECRET }}"
|
||||
database: "${{ env.BUGSPLAT_DATABASE }}"
|
||||
application: ${{ needs.build.outputs.viewer_channel }}
|
||||
version: ${{ needs.build.outputs.viewer_version }} (${{ needs.build.outputs.viewer_version }})
|
||||
directory: .
|
||||
files: "**/*.xcarchive.zip"
|
||||
node-version: "22"
|
||||
dumpSyms: false
|
||||
|
||||
release:
|
||||
needs: [setup, build, sign-and-package-windows, sign-and-package-mac]
|
||||
@@ -455,7 +463,6 @@ jobs:
|
||||
prerelease: true
|
||||
generate_release_notes: true
|
||||
target_commitish: ${{ github.sha }}
|
||||
previous_tag: release
|
||||
append_body: true
|
||||
fail_on_unmatched_files: true
|
||||
files: |
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
name: Check PR
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-description:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check PR description
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const description = context.payload.pull_request.body || '';
|
||||
if (description.trim().length < 20) {
|
||||
core.setFailed("❌ PR description is too short. Please provide at least 20 characters.");
|
||||
}
|
||||
@@ -23,4 +23,4 @@ jobs:
|
||||
path-to-signatures: signatures.json
|
||||
remote-organization-name: secondlife
|
||||
remote-repository-name: cla-signatures
|
||||
allowlist: callum@mbp.localdomain,rye@lindenlab.com
|
||||
allowlist: callum@mbp.localdomain,rye@lindenlab.com,rye,bot*
|
||||
|
||||
@@ -9,7 +9,7 @@ jobs:
|
||||
pull-requests: write
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/labeler@v4
|
||||
- uses: actions/labeler@v6
|
||||
with:
|
||||
configuration-path: .github/labeler.yaml
|
||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
@@ -11,8 +11,8 @@ jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v4
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: 3.x
|
||||
- uses: pre-commit/action@v3.0.0
|
||||
- uses: pre-commit/action@v3.0.1
|
||||
|
||||
@@ -0,0 +1,610 @@
|
||||
name: Run QA Test # Runs automated tests on self-hosted QA machines
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: ["Build"]
|
||||
types:
|
||||
- completed
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build_id:
|
||||
description: 'Build workflow run ID (e.g. For github.com/secondlife/viewer/actions/runs/1234567890 the ID is 1234567890)'
|
||||
required: true
|
||||
default: '14806728332'
|
||||
|
||||
jobs:
|
||||
debug-workflow:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Debug Workflow Variables
|
||||
run: |
|
||||
echo "Workflow Conclusion: ${{ github.event.workflow_run.conclusion }}"
|
||||
echo "Workflow Head Branch: ${{ github.event.workflow_run.head_branch }}"
|
||||
echo "Workflow Run ID: ${{ github.event.workflow_run.id }}"
|
||||
echo "Head Commit Message: ${{ github.event.workflow_run.head_commit.message }}"
|
||||
echo "GitHub Ref: ${{ github.ref }}"
|
||||
echo "GitHub Ref Name: ${{ github.ref_name }}"
|
||||
echo "GitHub Event Name: ${{ github.event_name }}"
|
||||
echo "GitHub Workflow Name: ${{ github.workflow }}"
|
||||
|
||||
install-viewer-and-run-tests:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ matrix.runner }}
|
||||
cancel-in-progress: false # Prevents cancellation of in-progress jobs
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- os: windows
|
||||
runner: qa-windows-atlas
|
||||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: windows
|
||||
runner: qa-windows-asus-dan
|
||||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: windows
|
||||
runner: qa-windows-kurt
|
||||
artifact: Windows-installer
|
||||
install-path: 'C:\viewer-automation-main'
|
||||
- os: mac
|
||||
runner: qa-mac-dan
|
||||
artifact: macOS-installer
|
||||
install-path: '$HOME/Documents/viewer-automation'
|
||||
- os: mac
|
||||
runner: qa-mac-atlas
|
||||
artifact: macOS-installer
|
||||
install-path: '$HOME/Documents/viewer-automation'
|
||||
- os: mac
|
||||
runner: qa-mac-caleb
|
||||
artifact: macOS-installer
|
||||
install-path: '$HOME/Documents/viewer-automation'
|
||||
fail-fast: false
|
||||
|
||||
runs-on: [self-hosted, "${{ matrix.runner }}"]
|
||||
# Run test only on successful builds of Second_Life_X branches or on manual dispatch
|
||||
if: >
|
||||
(github.event_name == 'workflow_run' &&
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
startsWith(github.event.workflow_run.head_branch, 'Second_Life')) ||
|
||||
github.event_name == 'workflow_dispatch'
|
||||
|
||||
steps:
|
||||
# Windows-specific steps
|
||||
- name: Set Build ID
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
|
||||
echo "BUILD_ID=${{ github.event.inputs.build_id }}" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.inputs.build_id }}/artifacts" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
} else {
|
||||
echo "BUILD_ID=${{ github.event.workflow_run.id }}" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.workflow_run.id }}/artifacts" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
}
|
||||
|
||||
- name: Temporarily Allow PowerShell Scripts (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Set-ExecutionPolicy RemoteSigned -Scope Process -Force
|
||||
|
||||
- name: Verify viewer-automation-main Exists (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
if (-Not (Test-Path -Path '${{ matrix.install-path }}')) {
|
||||
Write-Host '❌ Error: viewer-automation folder not found on runner!'
|
||||
exit 1
|
||||
}
|
||||
Write-Host '✅ viewer-automation folder is provided.'
|
||||
|
||||
- name: Verify viewer-automation-main is Up-To-Date (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cd ${{ matrix.install-path }}
|
||||
Write-Host "Checking for repository updates..."
|
||||
|
||||
# Check if .git directory exists
|
||||
if (Test-Path -Path ".git") {
|
||||
try {
|
||||
# Save local changes instead of discarding them
|
||||
git stash push -m "Automated stash before update $(Get-Date)"
|
||||
Write-Host "Local changes saved (if any)"
|
||||
|
||||
# Update the repository
|
||||
git pull
|
||||
Write-Host "✅ Repository updated successfully"
|
||||
|
||||
# Try to restore local changes if any were stashed
|
||||
$stashList = git stash list
|
||||
if ($stashList -match "Automated stash before update") {
|
||||
try {
|
||||
git stash pop
|
||||
Write-Host "✅ Local changes restored successfully"
|
||||
} catch {
|
||||
Write-Host "⚠️ Conflict when restoring local changes"
|
||||
# Save the conflicted state in a new branch for later review
|
||||
$branchName = "conflict-recovery-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
|
||||
git checkout -b $branchName
|
||||
Write-Host "✅ Created branch '$branchName' with conflicted state"
|
||||
|
||||
# For test execution, revert to a clean state
|
||||
git reset --hard HEAD
|
||||
Write-Host "✅ Reset to clean state for test execution"
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
Write-Host "⚠️ Could not update repository: $_"
|
||||
Write-Host "Continuing with existing files..."
|
||||
}
|
||||
} else {
|
||||
Write-Host "⚠️ Not a Git repository, using existing files"
|
||||
}
|
||||
|
||||
- name: Verify Python Installation (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
try {
|
||||
$pythonVersion = (python --version)
|
||||
Write-Host "✅ Python found: $pythonVersion"
|
||||
} catch {
|
||||
Write-Host "❌ Error: Python not found in PATH. Please install Python on this runner."
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Setup Python Virtual Environment (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
|
||||
cd ${{ matrix.install-path }}
|
||||
|
||||
if (-Not (Test-Path -Path ".venv")) {
|
||||
Write-Host "Creating virtual environment..."
|
||||
python -m venv .venv
|
||||
} else {
|
||||
Write-Host "Using existing virtual environment"
|
||||
}
|
||||
|
||||
# Direct environment activation to avoid script execution issues
|
||||
$env:VIRTUAL_ENV = "$PWD\.venv"
|
||||
$env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH"
|
||||
|
||||
# Install dependencies
|
||||
if (Test-Path -Path "requirements.txt") {
|
||||
Write-Host "Installing dependencies from requirements.txt..."
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Install Playwright browsers - add this line
|
||||
Write-Host "Installing Playwright browsers..."
|
||||
python -m playwright install
|
||||
} else {
|
||||
pip install outleap requests behave playwright
|
||||
# Install Playwright browsers - add this line
|
||||
Write-Host "Installing Playwright browsers..."
|
||||
python -m playwright install
|
||||
}
|
||||
|
||||
- name: Fetch & Download Installer Artifact (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$BUILD_ID = "${{ env.BUILD_ID }}"
|
||||
$ARTIFACTS_URL = "${{ env.ARTIFACTS_URL }}"
|
||||
|
||||
# Fetch the correct artifact URL
|
||||
$response = Invoke-RestMethod -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}" } -Uri $ARTIFACTS_URL
|
||||
$ARTIFACT_NAME = ($response.artifacts | Where-Object { $_.name -eq "${{ matrix.artifact }}" }).archive_download_url
|
||||
|
||||
if (-Not $ARTIFACT_NAME) {
|
||||
Write-Host "❌ Error: ${{ matrix.artifact }} artifact not found!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✅ Artifact found: $ARTIFACT_NAME"
|
||||
|
||||
# Secure download path
|
||||
$DownloadPath = "$env:TEMP\secondlife-build-$BUILD_ID"
|
||||
New-Item -ItemType Directory -Path $DownloadPath -Force | Out-Null
|
||||
$InstallerPath = "$DownloadPath\installer.zip"
|
||||
|
||||
# Download the ZIP
|
||||
Invoke-WebRequest -Uri $ARTIFACT_NAME -Headers @{Authorization="token ${{ secrets.GITHUB_TOKEN }}"} -OutFile $InstallerPath
|
||||
|
||||
# Ensure download succeeded
|
||||
if (-Not (Test-Path $InstallerPath)) {
|
||||
Write-Host "❌ Error: Failed to download ${{ matrix.artifact }}.zip"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Set the path for other steps
|
||||
echo "DOWNLOAD_PATH=$DownloadPath" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Extract Installer & Locate Executable (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$BUILD_ID = "${{ env.BUILD_ID }}"
|
||||
$ExtractPath = "${{ env.DOWNLOAD_PATH }}"
|
||||
$InstallerZip = "$ExtractPath\installer.zip"
|
||||
|
||||
# Print paths for debugging
|
||||
Write-Host "Extract Path: $ExtractPath"
|
||||
Write-Host "Installer ZIP Path: $InstallerZip"
|
||||
|
||||
# Verify ZIP exists before extracting
|
||||
if (-Not (Test-Path $InstallerZip)) {
|
||||
Write-Host "❌ Error: ZIP file not found at $InstallerZip!"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✅ ZIP file exists and is valid. Extracting..."
|
||||
|
||||
Expand-Archive -Path $InstallerZip -DestinationPath $ExtractPath -Force
|
||||
|
||||
# Find installer executable
|
||||
$INSTALLER_PATH = (Get-ChildItem -Path $ExtractPath -Filter '*.exe' -Recurse | Select-Object -First 1).FullName
|
||||
|
||||
if (-Not $INSTALLER_PATH -or $INSTALLER_PATH -eq "") {
|
||||
Write-Host "❌ Error: No installer executable found in the extracted files!"
|
||||
Write-Host "📂 Extracted Files:"
|
||||
Get-ChildItem -Path $ExtractPath -Recurse | Format-Table -AutoSize
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "✅ Installer found: $INSTALLER_PATH"
|
||||
echo "INSTALLER_PATH=$INSTALLER_PATH" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||
|
||||
- name: Install Second Life (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
# Windows - Use Task Scheduler to bypass UAC
|
||||
$action = New-ScheduledTaskAction -Execute "${{ env.INSTALLER_PATH }}" -Argument "/S"
|
||||
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest
|
||||
$task = New-ScheduledTask -Action $action -Principal $principal
|
||||
Register-ScheduledTask -TaskName "SilentSLInstaller" -InputObject $task -Force
|
||||
Start-ScheduledTask -TaskName "SilentSLInstaller"
|
||||
|
||||
- name: Wait for Installation to Complete (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Host "Waiting for the Second Life installer to finish..."
|
||||
do {
|
||||
Start-Sleep -Seconds 5
|
||||
$installerProcess = Get-Process | Where-Object { $_.Path -eq "${{ env.INSTALLER_PATH }}" }
|
||||
} while ($installerProcess)
|
||||
|
||||
Write-Host "✅ Installation completed!"
|
||||
|
||||
- name: Cleanup After Installation (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
# Cleanup Task Scheduler Entry
|
||||
Unregister-ScheduledTask -TaskName "SilentSLInstaller" -Confirm:$false
|
||||
Write-Host "✅ Task Scheduler entry removed."
|
||||
|
||||
# Delete Installer ZIP
|
||||
$DeletePath = "${{ env.DOWNLOAD_PATH }}\installer.zip"
|
||||
|
||||
Write-Host "Checking if installer ZIP exists: $DeletePath"
|
||||
|
||||
# Ensure the ZIP file exists before trying to delete it
|
||||
if (Test-Path $DeletePath) {
|
||||
Remove-Item -Path $DeletePath -Force
|
||||
Write-Host "✅ Successfully deleted: $DeletePath"
|
||||
} else {
|
||||
Write-Host "⚠️ Warning: ZIP file does not exist, skipping deletion."
|
||||
}
|
||||
|
||||
- name: Run QA Test Script (Windows)
|
||||
if: matrix.os == 'windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
Write-Host "Running QA Test script on Windows runner: ${{ matrix.runner }}..."
|
||||
cd ${{ matrix.install-path }}
|
||||
|
||||
# Activate virtual environment
|
||||
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force
|
||||
$env:VIRTUAL_ENV = "$PWD\.venv"
|
||||
$env:PATH = "$env:VIRTUAL_ENV\Scripts;$env:PATH"
|
||||
|
||||
# Set runner name as environment variable
|
||||
$env:RUNNER_NAME = "${{ matrix.runner }}"
|
||||
|
||||
# Run the test script
|
||||
python runTests.py
|
||||
|
||||
# Mac-specific steps
|
||||
- name: Set Build ID (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||
echo "BUILD_ID=${{ github.event.inputs.build_id }}" >> $GITHUB_ENV
|
||||
echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.inputs.build_id }}/artifacts" >> $GITHUB_ENV
|
||||
else
|
||||
echo "BUILD_ID=${{ github.event.workflow_run.id }}" >> $GITHUB_ENV
|
||||
echo "ARTIFACTS_URL=https://api.github.com/repos/secondlife/viewer/actions/runs/${{ github.event.workflow_run.id }}/artifacts" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Verify viewer-automation-main Exists (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ! -d "${{ matrix.install-path }}" ]; then
|
||||
echo "❌ Error: viewer-automation folder not found on runner!"
|
||||
exit 1
|
||||
fi
|
||||
echo "✅ viewer-automation is provided."
|
||||
|
||||
- name: Verify viewer-automation-main is Up-To-Date (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
continue-on-error: true
|
||||
run: |
|
||||
cd ${{ matrix.install-path }}
|
||||
echo "Checking for repository updates..."
|
||||
|
||||
# Check if .git directory exists
|
||||
if [ -d ".git" ]; then
|
||||
# Save local changes instead of discarding them
|
||||
git stash push -m "Automated stash before update $(date)"
|
||||
echo "Local changes saved (if any)"
|
||||
|
||||
# Update the repository
|
||||
git pull || echo "⚠️ Could not update repository"
|
||||
echo "✅ Repository updated (or attempted update)"
|
||||
|
||||
# Try to restore local changes if any were stashed
|
||||
if git stash list | grep -q "Automated stash before update"; then
|
||||
# Try to pop the stash, but be prepared for conflicts
|
||||
if ! git stash pop; then
|
||||
echo "⚠️ Conflict when restoring local changes"
|
||||
# Save the conflicted state in a new branch for later review
|
||||
branch_name="conflict-recovery-$(date +%Y%m%d-%H%M%S)"
|
||||
git checkout -b "$branch_name"
|
||||
echo "✅ Created branch '$branch_name' with conflicted state"
|
||||
|
||||
# For test execution, revert to a clean state
|
||||
git reset --hard HEAD
|
||||
echo "✅ Reset to clean state for test execution"
|
||||
else
|
||||
echo "✅ Local changes restored successfully"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "⚠️ Not a Git repository, using existing files"
|
||||
fi
|
||||
|
||||
- name: Verify Python Installation (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
if command -v python3 &> /dev/null; then
|
||||
PYTHON_VERSION=$(python3 --version)
|
||||
echo "✅ Python found: $PYTHON_VERSION"
|
||||
else
|
||||
echo "❌ Error: Python3 not found in PATH. Please install Python on this runner."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Setup Python Virtual Environment (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
cd ${{ matrix.install-path }}
|
||||
|
||||
# Create virtual environment if it doesn't exist
|
||||
if [ ! -d ".venv" ]; then
|
||||
echo "Creating virtual environment..."
|
||||
python3 -m venv .venv
|
||||
else
|
||||
echo "Using existing virtual environment"
|
||||
fi
|
||||
|
||||
# Activate virtual environment
|
||||
source .venv/bin/activate
|
||||
|
||||
# Install dependencies
|
||||
if [ -f "requirements.txt" ]; then
|
||||
pip install -r requirements.txt
|
||||
echo "✅ Installed dependencies from requirements.txt"
|
||||
|
||||
# Install Playwright browsers - add this line
|
||||
echo "Installing Playwright browsers..."
|
||||
python -m playwright install
|
||||
else
|
||||
pip install outleap requests behave playwright
|
||||
echo "⚠️ requirements.txt not found, installed basic dependencies"
|
||||
|
||||
# Install Playwright browsers - add this line
|
||||
echo "Installing Playwright browsers..."
|
||||
python -m playwright install
|
||||
fi
|
||||
|
||||
- name: Fetch & Download Installer Artifact (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
# Mac-specific Bash commands
|
||||
response=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -s ${{ env.ARTIFACTS_URL }})
|
||||
ARTIFACT_NAME=$(echo $response | jq -r '.artifacts[] | select(.name=="${{ matrix.artifact }}") | .archive_download_url')
|
||||
|
||||
if [ -z "$ARTIFACT_NAME" ]; then
|
||||
echo "❌ Error: ${{ matrix.artifact }} artifact not found!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Artifact found: $ARTIFACT_NAME"
|
||||
|
||||
# Secure download path
|
||||
DOWNLOAD_PATH="/tmp/secondlife-build-${{ env.BUILD_ID }}"
|
||||
mkdir -p $DOWNLOAD_PATH
|
||||
INSTALLER_PATH="$DOWNLOAD_PATH/installer.zip"
|
||||
|
||||
# Download the ZIP
|
||||
curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" -L $ARTIFACT_NAME -o $INSTALLER_PATH
|
||||
|
||||
# Ensure download succeeded
|
||||
if [ ! -f "$INSTALLER_PATH" ]; then
|
||||
echo "❌ Error: Failed to download ${{ matrix.artifact }}.zip"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set the path for other steps
|
||||
echo "DOWNLOAD_PATH=$DOWNLOAD_PATH" >> $GITHUB_ENV
|
||||
|
||||
- name: Extract Installer & Locate Executable (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
EXTRACT_PATH="${{ env.DOWNLOAD_PATH }}"
|
||||
INSTALLER_ZIP="$EXTRACT_PATH/installer.zip"
|
||||
|
||||
# Debug output
|
||||
echo "Extract Path: $EXTRACT_PATH"
|
||||
echo "Installer ZIP Path: $INSTALLER_ZIP"
|
||||
|
||||
# Verify ZIP exists
|
||||
if [ ! -f "$INSTALLER_ZIP" ]; then
|
||||
echo "❌ Error: ZIP file not found at $INSTALLER_ZIP!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ ZIP file exists and is valid. Extracting..."
|
||||
|
||||
# Extract the ZIP
|
||||
unzip -o "$INSTALLER_ZIP" -d "$EXTRACT_PATH"
|
||||
|
||||
# Find DMG file
|
||||
INSTALLER_PATH=$(find "$EXTRACT_PATH" -name "*.dmg" -type f | head -1)
|
||||
|
||||
if [ -z "$INSTALLER_PATH" ]; then
|
||||
echo "❌ Error: No installer DMG found in the extracted files!"
|
||||
echo "📂 Extracted Files:"
|
||||
ls -la "$EXTRACT_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Installer found: $INSTALLER_PATH"
|
||||
echo "INSTALLER_PATH=$INSTALLER_PATH" >> $GITHUB_ENV
|
||||
|
||||
- name: Install Second Life (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
# Mac installation
|
||||
echo "Mounting DMG installer..."
|
||||
MOUNT_POINT="/tmp/secondlife-dmg"
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
|
||||
# Mount the DMG
|
||||
hdiutil attach "$INSTALLER_PATH" -mountpoint "$MOUNT_POINT" -nobrowse
|
||||
|
||||
echo "✅ DMG mounted at $MOUNT_POINT"
|
||||
|
||||
echo "Installing application to default location from DMG..."
|
||||
|
||||
# Find the .app bundle in the DMG
|
||||
APP_PATH=$(find "$MOUNT_POINT" -name "*.app" -type d | head -1)
|
||||
|
||||
if [ -z "$APP_PATH" ]; then
|
||||
echo "❌ Error: No .app bundle found in the mounted DMG!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
APP_NAME=$(basename "$APP_PATH")
|
||||
DEST_PATH="/Applications/$APP_NAME"
|
||||
|
||||
# Handle existing installation
|
||||
if [ -d "$DEST_PATH" ]; then
|
||||
echo "Found existing installation at: $DEST_PATH"
|
||||
echo "Moving existing installation to trash..."
|
||||
|
||||
# Move to trash instead of force removing
|
||||
TRASH_PATH="$HOME/.Trash/$(date +%Y%m%d_%H%M%S)_$APP_NAME"
|
||||
mv "$DEST_PATH" "$TRASH_PATH" || {
|
||||
echo "⚠️ Could not move to trash, trying direct removal..."
|
||||
rm -rf "$DEST_PATH" || {
|
||||
echo "❌ Could not remove existing installation"
|
||||
echo "Please manually remove: $DEST_PATH"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
echo "✅ Existing installation handled successfully"
|
||||
fi
|
||||
|
||||
# Copy the .app to /Applications
|
||||
echo "Copying app from: $APP_PATH"
|
||||
echo "To destination: /Applications/"
|
||||
cp -R "$APP_PATH" /Applications/
|
||||
|
||||
# Verify the app was copied successfully
|
||||
if [ ! -d "$DEST_PATH" ]; then
|
||||
echo "❌ Error: Failed to install application to /Applications!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "✅ Application installed successfully to /Applications"
|
||||
|
||||
# Save mount point for cleanup
|
||||
echo "MOUNT_POINT=$MOUNT_POINT" >> $GITHUB_ENV
|
||||
|
||||
- name: Wait for Installation to Complete (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Waiting for installation to complete..."
|
||||
# Sleep to allow installation to finish (adjust as needed)
|
||||
sleep 30
|
||||
echo "✅ Installation completed"
|
||||
|
||||
- name: Cleanup After Installation (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
# Mac cleanup
|
||||
# Unmount the DMG
|
||||
echo "Unmounting DMG..."
|
||||
hdiutil detach "${{ env.MOUNT_POINT }}" -force
|
||||
|
||||
# Clean up temporary files
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -rf "${{ env.DOWNLOAD_PATH }}"
|
||||
rm -rf "${{ env.MOUNT_POINT }}"
|
||||
|
||||
echo "✅ Cleanup completed"
|
||||
|
||||
- name: Run QA Test Script (Mac)
|
||||
if: matrix.os == 'mac'
|
||||
shell: bash
|
||||
run: |
|
||||
echo "Running QA Test script on Mac runner: ${{ matrix.runner }}..."
|
||||
cd ${{ matrix.install-path }}
|
||||
|
||||
# Activate virtual environment
|
||||
source .venv/bin/activate
|
||||
|
||||
# Set runner name as environment variable
|
||||
export RUNNER_NAME="${{ matrix.runner }}"
|
||||
|
||||
# Run the test script
|
||||
python runTests.py
|
||||
|
||||
# - name: Upload Test Results
|
||||
# if: always()
|
||||
# uses: actions/upload-artifact@v4
|
||||
# with:
|
||||
# name: test-results-${{ matrix.runner }}
|
||||
# path: ${{ matrix.install-path }}/regressionTest/test_results.html
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v6
|
||||
- uses: actions/stale@v10
|
||||
id: stale
|
||||
with:
|
||||
stale-pr-message: This pull request is stale because it has been open 30 days with no activity. Remove stale label or comment or it will be closed in 7 days
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
echo NIGHTLY_DATE=${NIGHTLY_DATE} >> ${GITHUB_ENV}
|
||||
echo TAG_ID="$(echo ${{ github.sha }} | cut -c1-8)-${{ inputs.project || '${NIGHTLY_DATE}' }}" >> ${GITHUB_ENV}
|
||||
- name: Update Tag
|
||||
uses: actions/github-script@v7.0.1
|
||||
uses: actions/github-script@v8
|
||||
with:
|
||||
# use a real access token instead of GITHUB_TOKEN default.
|
||||
# required so that the results of this tag creation can trigger the build workflow
|
||||
|
||||
@@ -26,7 +26,6 @@ debian/files
|
||||
debian/secondlife-appearance-utility*
|
||||
debian/secondlife-viewer*
|
||||
indra/.distcc
|
||||
indra/cmake/*
|
||||
indra/out/*
|
||||
|
||||
indra/packages/*
|
||||
|
||||
@@ -7,14 +7,14 @@ repos:
|
||||
- id: no-trigraphs
|
||||
- id: copyright
|
||||
- id: end-of-file
|
||||
files: \.(cpp|c|h|py|glsl|cmake|txt)$
|
||||
files: \.(cpp|c|m|mm|h|py|glsl|cmake|txt)$
|
||||
exclude: language.txt
|
||||
- id: indent-with-spaces
|
||||
files: \.(cpp|c|h|inl|py|glsl|cmake)$
|
||||
files: \.(cpp|c|m|mm|h|inl|py|glsl|cmake)$
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: check-xml
|
||||
- id: mixed-line-ending
|
||||
- id: trailing-whitespace
|
||||
files: \.(cpp|c|h|inl|py|glsl|cmake|yaml|sh)$
|
||||
files: \.(cpp|c|m|mm|h|inl|py|glsl|cmake|yaml|sh)$
|
||||
|
||||
+13
-1
@@ -8,6 +8,7 @@ changes.
|
||||
## Table of contents
|
||||
|
||||
- [Communication](#communication)
|
||||
- [What to work on](#what-to-work-on)
|
||||
- [Reporting bugs and requesting features](#reporting-bugs-and-requesting-features)
|
||||
- [Contributing pull requests](#contributing-pull-requests)
|
||||
|
||||
@@ -32,8 +33,19 @@ developer-to-developer or support.
|
||||
- [Official forums][] exist for many topics including content creation,
|
||||
scripting, social topics and more.
|
||||
- The [opensource-dev mailing list][] is useful for announcements and
|
||||
discussion between viewer maintainers.
|
||||
discussion between viewer maintainers.
|
||||
- Our [discord channel](https://discord.com/channels/677442248157167619/1357059883400167585) is available for real-time discussion.
|
||||
|
||||
## What to work on
|
||||
|
||||
If you're looking for ways to contribute code, here are some ways to get involved:
|
||||
|
||||
- Explore existing issues on the [GitHub issue tracker](https://github.com/secondlife/viewer/issues) to find known problems, bugs, or enhancement discussions.
|
||||
- File new issues if you’ve discovered a bug or have a specific idea to propose. If your idea is user-facing, consider submitting it through feedback.secondlife.com so it can reach a broader audience and be prioritized by Linden Lab staff.
|
||||
- Look for the [help wanted](https://github.com/secondlife/viewer/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22help%20wanted%22) label. These are tasks the core maintainers have specifically identified as good candidates for community help.
|
||||
- Talk to maintainers before starting significant work. Even if an issue exists, discussing your approach first ensures alignment with ongoing efforts and increases the likelihood your pull request will be accepted.
|
||||
|
||||
Collaboration is essential. We encourage contributors to work closely with the Second Life engineering team and other developers to keep work consistent and maintainable.
|
||||
|
||||
## Reporting bugs and requesting features
|
||||
|
||||
|
||||
+416
-394
File diff suppressed because it is too large
Load Diff
@@ -40,7 +40,7 @@ retry_cmd()
|
||||
|
||||
build_dir_Darwin()
|
||||
{
|
||||
echo build-darwin-x86_64
|
||||
echo build-darwin-universal
|
||||
}
|
||||
|
||||
build_dir_Linux()
|
||||
@@ -70,7 +70,7 @@ installer_Darwin()
|
||||
{
|
||||
local package_name="$1"
|
||||
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\$"
|
||||
local pattern=".*$(viewer_channel_suffix ${package_name})_[0-9]+_[0-9]+_[0-9]+_[0-9]+_universal\\.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
|
||||
@@ -261,8 +261,8 @@ build()
|
||||
done
|
||||
fi
|
||||
|
||||
# *TODO: Make this a build extension.
|
||||
package_llphysicsextensions_tpv || fatal "failed building llphysicsextensions packages"
|
||||
# *TODO: Make this a build extension. disabled for now
|
||||
# package_llphysicsextensions_tpv || fatal "failed building llphysicsextensions packages"
|
||||
end_section "extensions $variant"
|
||||
|
||||
else
|
||||
@@ -387,7 +387,7 @@ do
|
||||
if `cat "$build_dir/build_ok"`
|
||||
then
|
||||
case "$variant" in
|
||||
Release)
|
||||
Release*)
|
||||
if [ -r "$build_dir/autobuild-package.xml" ]
|
||||
then
|
||||
begin_section "Autobuild metadata"
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
# Test plan for PRIM_MEDIA_FIRST_CLICK_INTERACT
|
||||
|
||||
## Requirements
|
||||
|
||||
- At least two accounts
|
||||
- At least one group
|
||||
- Land under your control
|
||||
|
||||
## Feature Brief
|
||||
|
||||
Historically media-on-a-prim (MOAP) in Second Life has been bound to a focus system which blocks mouse click/hover events, this feature creates exceptions to this focus system for a configurable set of objects to meet user preference.
|
||||
|
||||
## Testing
|
||||
|
||||
The following scripts and test cases cover each individual operational mode of the feature; in practice these modes can be combined by advanced users in any configuration they desire from debug settings. Even though the intended use case combines multiple modes, individual modes can be tested for functionality when tested as described below.
|
||||
|
||||
If testing an arbitrary combination of operational modes beyond what the GUI offers is desired, the parameters of the bitfield for calculation are located in lltoolpie.h under the MediaFirstClickTypes enum. As of writing there exists a total of ~127 possible unique/valid combinations, which is why testing each mode individually is considered the most efficient for a full functionality test.
|
||||
|
||||
### Scripts
|
||||
|
||||
#### Script A
|
||||
|
||||
This script creates a media surface that is eligible for media first-click interact. Depending on test conditions, this will exhibit new behavior.
|
||||
|
||||
```lsl
|
||||
default {
|
||||
state_entry() {
|
||||
llSetLinkMedia( LINK_THIS, 0, [
|
||||
PRIM_MEDIA_CURRENT_URL, "http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/agni/avatars.html",
|
||||
PRIM_MEDIA_HOME_URL, "http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/agni/avatars.html",
|
||||
PRIM_MEDIA_FIRST_CLICK_INTERACT, TRUE,
|
||||
PRIM_MEDIA_AUTO_PLAY, TRUE,
|
||||
PRIM_MEDIA_CONTROLS, PRIM_MEDIA_CONTROLS_MINI
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
#### Script B
|
||||
|
||||
This script creates a media surface that is NOT eligible for media first-click interact. In all but one test case, this will behave the same way.
|
||||
|
||||
```lsl
|
||||
default {
|
||||
state_entry() {
|
||||
llSetLinkMedia( LINK_THIS, 0, [
|
||||
PRIM_MEDIA_CURRENT_URL, "http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/agni/avatars.html",
|
||||
PRIM_MEDIA_HOME_URL, "http://lecs-viewer-web-components.s3.amazonaws.com/v3.0/agni/avatars.html",
|
||||
PRIM_MEDIA_FIRST_CLICK_INTERACT, FALSE,
|
||||
PRIM_MEDIA_AUTO_PLAY, TRUE,
|
||||
PRIM_MEDIA_CONTROLS, PRIM_MEDIA_CONTROLS_MINI
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Standard testing procedure
|
||||
|
||||
You will be asked to enable media faces on multiple cubes, make sure that the webpage loads on each, and interact with them in the following ways.
|
||||
|
||||
1. Enable media for the cube, and verify that it displays a webpage.
|
||||
2. Click on the terrain to clear any focus.
|
||||
3. Hover your mouse over UI elements of the webpage, and **observe** if they highlight/react to the mouse cursor.
|
||||
4. If hover events are not registered, clicking on the webpage and then **observe** if they begin reacting to hover events.
|
||||
5. Clicking on the terrain to clear any focus once again.
|
||||
6. Clicking on a UI element of the webpage and **observe** if it reacts to the first click, or requires a second click. *(Maximum of 2 clicks per attempt)*
|
||||
|
||||
These steps will be repeated for one or more pairs of cubes per test case to ensure that media first click interact is functioning within expectations. Unless otherwise mentioned for a specific test case, you simply need only be in the same region as the cubes to test with them.
|
||||
|
||||
## Test cases
|
||||
|
||||
All test cases begin with at least two cubes rezzed, one containing Script A henceforth referred to as Cube A and one with Script B referred to as Cube B. The steps of some test cases may impact the condition of the cubes, so keeping a spare set rezzed or in inventory to rapidly duplicate should improve efficiency if testing cases in series.
|
||||
|
||||
### Case 1 (MEDIA_FIRST_CLICK_NONE)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `0`
|
||||
|
||||
Starting with Cube A and Cube B, perform the testing procedure on each.
|
||||
|
||||
**Expected observations:** Both webpages do not react to hover events until clicked, both webpages do not react to clicks until clicked once to establish focus
|
||||
|
||||
### Case 2 (MEDIA_FIRST_CLICK_HUD)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `1`
|
||||
|
||||
Starting with Cube A and Cube B, attach them both to your HUD and perform the testing procedure on each. You may need to rotate or scale the cubes to fit on your screen before beginning testing. You may attach both at the same time, or only one at a time.
|
||||
|
||||
**Expected observations:** The webpage on Cube A will react to mouse cursor hover events and clicks without needing a focus click, but the webpage on Cube B will not.
|
||||
|
||||
### Case 3 (MEDIA_FIRST_CLICK_OWN)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `2`
|
||||
|
||||
This test case requires two pairs of cubes, and the second pair must not be owned by your testing account. What owns them is not important, it can be a group or your second testing account.
|
||||
|
||||
Perform the testing procedure on both sets of cubes.
|
||||
|
||||
**Expected observations:** The webpage on Cube A will react to mouse cursor hover events and clicks without needing a focus click, but the webpage on Cube B will not. The other pair of cubes will react the same as your Cube B.
|
||||
|
||||
### Case 4 (MEDIA_FIRST_CLICK_GROUP)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `4`
|
||||
|
||||
This test case requires two cubes, and the second cube must be deeded or set to a group that your testing account is a member of. As long as the second set of cubes is set to a group that your test account is a member of, the avatar that owns them does not matter.
|
||||
|
||||
Perform the testing procedure on both sets of cubes.
|
||||
|
||||
**Expected observations:** The cube owned by your primary account will not react to mouse cursor hover events and clicks without needing a focus click. The cube set to group will react to mouse cursor hover events and clicks without needing a focus click.
|
||||
|
||||
### Case 5 (MEDIA_FIRST_CLICK_FRIEND)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `8`
|
||||
|
||||
This test case requires three sets of cubes, one owned by you, one owned by another avatar on your friend list, and a third set owned by an avatar that is not on your friend list, or deeded to group. You can optionally use two sets of cubes, and dissolve friendship with your second account to test non-friend cubes.
|
||||
|
||||
Perform the testing procedure on all cubes
|
||||
|
||||
**Expected observations:** Cube A owned by a friended avatar will react to mouse cursor hover events and clicks without needing a focus click. All other cubes will not.
|
||||
|
||||
### Case 6 (MEDIA_FIRST_CLICK_LAND)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `16`
|
||||
|
||||
This is the most tricky test case due to the multiple combinations that this operational mode considers valid. You will need multiple cubes, and can omit Cube B for brevity unless running a full test pass. This is probably most efficiently tested from your second account, using your first account to adjust the test parameters to fit other sub-cases.
|
||||
|
||||
Note: This requires the avatar that is performing the tests to physically be in the same parcel as the test cube(s). If you are standing outside of the parcel the media cubes are in, they will never react to mouse cursor hover events and clicks without needing a focus click under this operational mode.
|
||||
|
||||
1. Place down a set of cubes owned by the same avatar as the land
|
||||
- The second account should see Cube A react to mouse cursor hover events and clicks without needing a focus click
|
||||
- Cube B if tested, will not react in all further sub-cases and will not be mentioned further.
|
||||
|
||||
2. Adjust the conditions of the cubes and parcel such that they are owned by another avatar, but have the same group as the land set
|
||||
- The second account should see Cube A react to mouse cursor hover events and clicks without needing a focus click
|
||||
|
||||
3. Adjust the conditions of the cubes and parcel such that they are deeded to the same group that the parcel is deeded to
|
||||
- The second account should see Cube A react to mouse cursor hover events and clicks without needing a focus click
|
||||
|
||||
4. Adjust the conditions of the cubes and parcel such that the parcel and cubes do not share an owner, or a group
|
||||
- The second account should see Cube A NOT react to mouse cursor hover events until clicked, and clicks WILL need a focus click before registering.
|
||||
|
||||
### Case 7 (MEDIA_FIRST_CLICK_ANY) (optional)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `32767`
|
||||
|
||||
Repeat test cases 1-6.
|
||||
|
||||
1. Test case 1 should fail
|
||||
2. Test cases 2-6 should pass
|
||||
|
||||
### Case 8 (MEDIA_FIRST_CLICK_BYPASS_MOAP_FLAG) (optional)
|
||||
|
||||
Ensure that debug setting `MediaFirstClickInteract` is set to `65535`
|
||||
|
||||
Repeat test cases 1-6, there is no pass/fail for this run.
|
||||
|
||||
All cubes including B types should exhibit the same first-click interact behavior.
|
||||
+16
-1
@@ -10,7 +10,13 @@
|
||||
## Nicky: Ideally we want at least 3.21 for good preset support
|
||||
## We're not there yet, but once done, there is a kludge in Linking.cmake
|
||||
# "if(${CMAKE_VERSION} VERSION_LESS "3.20.0")" that can also be removed
|
||||
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
|
||||
cmake_minimum_required(VERSION 3.16.0...4.0 FATAL_ERROR)
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.29.0")
|
||||
cmake_policy(SET CMP0156 NEW)
|
||||
endif()
|
||||
if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.31.0")
|
||||
cmake_policy(SET CMP0179 NEW)
|
||||
endif()
|
||||
|
||||
set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
|
||||
"The root project/makefile/solution name. Defaults to SecondLife.")
|
||||
@@ -33,6 +39,14 @@ if (NOT DEFINED CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
endif()
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_SCAN_FOR_MODULES OFF) # This slows down build massively
|
||||
|
||||
set(CMAKE_OPTIMIZE_DEPENDENCIES ON)
|
||||
|
||||
set(CMAKE_COLOR_DIAGNOSTICS ON)
|
||||
|
||||
# Speeds up cmake generation significantly in some cases
|
||||
set(CMAKE_XCODE_GENERATE_TOP_LEVEL_PROJECT_ONLY ON)
|
||||
|
||||
include(Variables)
|
||||
include(BuildVersion)
|
||||
@@ -56,6 +70,7 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llinventory)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llmath)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llmeshoptimizer)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llmessage)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llphysicsextensionsos)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llprimitive)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llrender)
|
||||
add_subdirectory(${LIBS_OPEN_PREFIX}llfilesystem)
|
||||
|
||||
+34
-30
@@ -34,7 +34,10 @@ add_compile_definitions(BOOST_BIND_GLOBAL_PLACEHOLDERS)
|
||||
|
||||
# Force enable SSE2 instructions in GLM per the manual
|
||||
# https://github.com/g-truc/glm/blob/master/manual.md#section2_10
|
||||
add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_FORCE_SSE2=1)
|
||||
add_compile_definitions(GLM_FORCE_DEFAULT_ALIGNED_GENTYPES=1 GLM_ENABLE_EXPERIMENTAL=1)
|
||||
|
||||
# SSE2NEON throws a pointless warning when compiler optimizations are enabled
|
||||
add_compile_definitions(SSE2NEON_SUPPRESS_WARNINGS=1)
|
||||
|
||||
# Configure crash reporting
|
||||
set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
|
||||
@@ -48,6 +51,11 @@ if(NON_RELEASE_CRASH_REPORTING)
|
||||
add_compile_definitions( LL_SEND_CRASH_REPORTS=1)
|
||||
endif()
|
||||
|
||||
set(USE_LTO OFF CACHE BOOL "Enable Link Time Optimization")
|
||||
if(USE_LTO)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
endif()
|
||||
|
||||
# Don't bother with a MinSizeRel or Debug builds.
|
||||
set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release" CACHE STRING "Supported build types." FORCE)
|
||||
|
||||
@@ -73,6 +81,8 @@ if (WINDOWS)
|
||||
NOMINMAX
|
||||
# DOM_DYNAMIC # For shared library colladadom
|
||||
_CRT_SECURE_NO_WARNINGS # Allow use of sprintf etc
|
||||
_CRT_NONSTDC_NO_DEPRECATE # Allow use of sprintf etc
|
||||
_CRT_OBSOLETE_NO_WARNINGS
|
||||
_WINSOCK_DEPRECATED_NO_WARNINGS # Disable deprecated WinSock API warnings
|
||||
)
|
||||
add_compile_options(
|
||||
@@ -101,7 +111,7 @@ if (WINDOWS)
|
||||
|
||||
#ND: When using something like buildcache (https://github.com/mbitsnbites/buildcache)
|
||||
# to make those wrappers work /Zi must be changed to /Z7, as /Zi due to it's nature is not compatible with caching
|
||||
if( ${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*")
|
||||
if(${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*")
|
||||
add_compile_options( /Z7 )
|
||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
@@ -155,46 +165,40 @@ if (LINUX)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
endif (LINUX)
|
||||
|
||||
|
||||
if (DARWIN)
|
||||
# Use rpath loading on macos
|
||||
set(CMAKE_MACOSX_RPATH TRUE)
|
||||
|
||||
# Warnings should be fatal -- thanks, Nicky Perian, for spotting reversed default
|
||||
set(CLANG_DISABLE_FATAL_WARNINGS OFF)
|
||||
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 "-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}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}")
|
||||
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.
|
||||
## Really?? On developer machines too?
|
||||
##set(ENABLE_SIGNING TRUE)
|
||||
##set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.")
|
||||
|
||||
# required for clang-15/xcode-15 since our boost package still uses deprecated std::unary_function/binary_function
|
||||
# see https://developer.apple.com/documentation/xcode-release-notes/xcode-15-release-notes#C++-Standard-Library
|
||||
add_compile_definitions(_LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION)
|
||||
endif (DARWIN)
|
||||
# Ensure debug symbols are always generated
|
||||
add_compile_options(-g --debug) # --debug is a clang synonym for -g that bypasses cmake behaviors
|
||||
|
||||
# Silence GL deprecation warnings
|
||||
add_compile_definitions(GL_SILENCE_DEPRECATION=1)
|
||||
endif(DARWIN)
|
||||
|
||||
if (LINUX OR DARWIN)
|
||||
set(GCC_WARNINGS -Wall -Wno-sign-compare -Wno-trigraphs)
|
||||
add_compile_options(-Wall -Wno-sign-compare -Wno-trigraphs -Wno-reorder -Wno-unused-but-set-variable -Wno-unused-variable)
|
||||
|
||||
if (NOT GCC_DISABLE_FATAL_WARNINGS)
|
||||
list(APPEND GCC_WARNINGS -Werror)
|
||||
endif (NOT GCC_DISABLE_FATAL_WARNINGS)
|
||||
|
||||
list(APPEND GCC_WARNINGS -Wno-reorder -Wno-non-virtual-dtor )
|
||||
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 13)
|
||||
list(APPEND GCC_WARNINGS -Wno-unused-but-set-variable -Wno-unused-variable )
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
# libstdc++ headers contain deprecated declarations that fail on clang
|
||||
# macOS currently has many deprecated calls
|
||||
add_compile_options(-Wno-unused-local-typedef)
|
||||
endif()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
add_compile_options(-Wno-stringop-truncation -Wno-parentheses -Wno-maybe-uninitialized)
|
||||
endif()
|
||||
|
||||
if (NOT GCC_DISABLE_FATAL_WARNINGS AND NOT CLANG_DISABLE_FATAL_WARNINGS)
|
||||
add_compile_options(-Werror)
|
||||
endif ()
|
||||
|
||||
add_compile_options(${GCC_WARNINGS})
|
||||
add_compile_options(-m${ADDRESS_SIZE})
|
||||
endif (LINUX OR DARWIN)
|
||||
|
||||
|
||||
|
||||
|
||||
+21
-31
@@ -9,35 +9,25 @@ use_system_binary( apr apr-util )
|
||||
use_prebuilt_binary(apr_suite)
|
||||
|
||||
if (WINDOWS)
|
||||
if (LLCOMMON_LINK_SHARED)
|
||||
set(APR_selector "lib")
|
||||
else (LLCOMMON_LINK_SHARED)
|
||||
set(APR_selector "")
|
||||
endif (LLCOMMON_LINK_SHARED)
|
||||
target_link_libraries( ll::apr INTERFACE
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apr-1.lib
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}aprutil-1.lib
|
||||
)
|
||||
target_compile_definitions( ll::apr INTERFACE APR_DECLARE_STATIC=1 APU_DECLARE_STATIC=1 API_DECLARE_STATIC=1)
|
||||
elseif (DARWIN)
|
||||
if (LLCOMMON_LINK_SHARED)
|
||||
set(APR_selector "0.dylib")
|
||||
set(APRUTIL_selector "0.dylib")
|
||||
else (LLCOMMON_LINK_SHARED)
|
||||
set(APR_selector "a")
|
||||
set(APRUTIL_selector "a")
|
||||
endif (LLCOMMON_LINK_SHARED)
|
||||
|
||||
target_link_libraries( ll::apr INTERFACE
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.${APR_selector}
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.${APR_selector}
|
||||
iconv
|
||||
)
|
||||
else()
|
||||
target_link_libraries( ll::apr INTERFACE
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libapr-1.a
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libaprutil-1.a
|
||||
rt
|
||||
)
|
||||
target_compile_definitions(ll::apr INTERFACE APR_DECLARE_STATIC=1 APU_DECLARE_STATIC=1 API_DECLARE_STATIC=1)
|
||||
endif ()
|
||||
target_include_directories( ll::apr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/apr-1 )
|
||||
|
||||
find_library(APR_LIBRARY
|
||||
NAMES
|
||||
apr-1.lib
|
||||
libapr-1.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(APRUTIL_LIBRARY
|
||||
NAMES
|
||||
aprutil-1.lib
|
||||
libaprutil-1.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::apr INTERFACE ${APR_LIBRARY} ${APRUTIL_LIBRARY})
|
||||
|
||||
if(DARWIN)
|
||||
target_link_libraries(ll::apr INTERFACE iconv)
|
||||
endif()
|
||||
|
||||
target_include_directories(ll::apr SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/apr-1)
|
||||
|
||||
+25
-19
@@ -9,23 +9,29 @@ use_system_binary(vorbis)
|
||||
use_prebuilt_binary(ogg_vorbis)
|
||||
target_include_directories( ll::vorbis SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include )
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries(ll::vorbis INTERFACE
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libogg.lib
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libogg.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisenc.lib
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbisenc.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisfile.lib
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbisfile.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libvorbis.lib
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libvorbis.lib
|
||||
)
|
||||
else (WINDOWS)
|
||||
target_link_libraries(ll::vorbis INTERFACE
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libogg.a
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisenc.a
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libvorbisfile.a
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libvorbis.a
|
||||
)
|
||||
endif (WINDOWS)
|
||||
find_library(OGG_LIBRARY
|
||||
NAMES
|
||||
libogg.lib
|
||||
libogg.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(VORBIS_LIBRARY
|
||||
NAMES
|
||||
libvorbis.lib
|
||||
libvorbis.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(VORBISENC_LIBRARY
|
||||
NAMES
|
||||
libvorbisenc.lib
|
||||
libvorbisenc.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(VORBISFILE_LIBRARY
|
||||
NAMES
|
||||
libvorbisfile.lib
|
||||
libvorbisfile.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::vorbis INTERFACE ${VORBISENC_LIBRARY} ${VORBISFILE_LIBRARY} ${VORBIS_LIBRARY} ${OGG_LIBRARY} )
|
||||
|
||||
|
||||
+110
-32
@@ -17,40 +17,118 @@ use_prebuilt_binary(boost)
|
||||
set(addrsfx "-x${ADDRESS_SIZE}")
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::boost INTERFACE
|
||||
libboost_context-mt${addrsfx}
|
||||
libboost_fiber-mt${addrsfx}
|
||||
libboost_filesystem-mt${addrsfx}
|
||||
libboost_program_options-mt${addrsfx}
|
||||
libboost_regex-mt${addrsfx}
|
||||
libboost_system-mt${addrsfx}
|
||||
libboost_thread-mt${addrsfx}
|
||||
libboost_url-mt${addrsfx})
|
||||
elseif (LINUX)
|
||||
target_link_libraries( ll::boost INTERFACE
|
||||
boost_context-mt${addrsfx}
|
||||
boost_fiber-mt${addrsfx}
|
||||
boost_filesystem-mt${addrsfx}
|
||||
boost_program_options-mt${addrsfx}
|
||||
boost_regex-mt${addrsfx}
|
||||
boost_signals-mt${addrsfx}
|
||||
boost_system-mt${addrsfx}
|
||||
boost_thread-mt${addrsfx}
|
||||
boost_url-mt${addrsfx})
|
||||
elseif (DARWIN)
|
||||
target_link_libraries( ll::boost INTERFACE
|
||||
boost_context-mt${addrsfx}
|
||||
boost_fiber-mt${addrsfx}
|
||||
boost_filesystem-mt${addrsfx}
|
||||
boost_program_options-mt${addrsfx}
|
||||
boost_regex-mt${addrsfx}
|
||||
boost_system-mt${addrsfx}
|
||||
boost_thread-mt${addrsfx}
|
||||
boost_url-mt${addrsfx})
|
||||
|
||||
find_library(BOOST_CONTEXT_LIBRARY
|
||||
NAMES
|
||||
libboost_context-mt
|
||||
libboost_context-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_FIBER_LIBRARY
|
||||
NAMES
|
||||
libboost_fiber-mt
|
||||
libboost_fiber-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_FILESYSTEM_LIBRARY
|
||||
NAMES
|
||||
libboost_filesystem-mt
|
||||
libboost_filesystem-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_PROGRAMOPTIONS_LIBRARY
|
||||
NAMES
|
||||
libboost_program_options-mt
|
||||
libboost_program_options-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_REGEX_LIBRARY
|
||||
NAMES
|
||||
libboost_regex-mt
|
||||
libboost_regex-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_SYSTEM_LIBRARY
|
||||
NAMES
|
||||
libboost_system-mt
|
||||
libboost_system-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_THREAD_LIBRARY
|
||||
NAMES
|
||||
libboost_thread-mt
|
||||
libboost_thread-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_URL_LIBRARY
|
||||
NAMES
|
||||
libboost_url-mt
|
||||
libboost_url-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
else (WINDOWS)
|
||||
|
||||
find_library(BOOST_CONTEXT_LIBRARY
|
||||
NAMES
|
||||
boost_context-mt
|
||||
boost_context-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_FIBER_LIBRARY
|
||||
NAMES
|
||||
boost_fiber-mt
|
||||
boost_fiber-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_FILESYSTEM_LIBRARY
|
||||
NAMES
|
||||
boost_filesystem-mt
|
||||
boost_filesystem-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_PROGRAMOPTIONS_LIBRARY
|
||||
NAMES
|
||||
boost_program_options-mt
|
||||
boost_program_options-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_REGEX_LIBRARY
|
||||
NAMES
|
||||
boost_regex-mt
|
||||
boost_regex-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_SYSTEM_LIBRARY
|
||||
NAMES
|
||||
boost_system-mt
|
||||
boost_system-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_THREAD_LIBRARY
|
||||
NAMES
|
||||
boost_thread-mt
|
||||
boost_thread-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(BOOST_URL_LIBRARY
|
||||
NAMES
|
||||
boost_url-mt
|
||||
boost_url-mt${addrsfx}
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
endif (WINDOWS)
|
||||
|
||||
target_link_libraries(ll::boost INTERFACE
|
||||
${BOOST_FIBER_LIBRARY}
|
||||
${BOOST_CONTEXT_LIBRARY}
|
||||
${BOOST_FILESYSTEM_LIBRARY}
|
||||
${BOOST_PROGRAMOPTIONS_LIBRARY}
|
||||
${BOOST_REGEX_LIBRARY}
|
||||
${BOOST_SYSTEM_LIBRARY}
|
||||
${BOOST_THREAD_LIBRARY}
|
||||
${BOOST_URL_LIBRARY})
|
||||
|
||||
if (LINUX)
|
||||
set(BOOST_SYSTEM_LIBRARY ${BOOST_SYSTEM_LIBRARY} rt)
|
||||
set(BOOST_THREAD_LIBRARY ${BOOST_THREAD_LIBRARY} rt)
|
||||
target_link_libraries(ll::boost INTERFACE rt)
|
||||
endif (LINUX)
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ elseif (DARWIN)
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a
|
||||
${APPKIT_LIBRARY}
|
||||
"-F ${CEF_LIBRARY}"
|
||||
)
|
||||
|
||||
elseif (LINUX)
|
||||
|
||||
@@ -20,6 +20,7 @@ set(cmake_SOURCE_FILES
|
||||
Copy3rdPartyLibs.cmake
|
||||
DBusGlib.cmake
|
||||
DeploySharedLibs.cmake
|
||||
Discord.cmake
|
||||
DragDrop.cmake
|
||||
EXPAT.cmake
|
||||
FindAutobuild.cmake
|
||||
@@ -52,13 +53,16 @@ set(cmake_SOURCE_FILES
|
||||
Prebuilt.cmake
|
||||
PulseAudio.cmake
|
||||
Python.cmake
|
||||
SSE2NEON.cmake
|
||||
TemplateCheck.cmake
|
||||
TinyEXR.cmake
|
||||
TinyGLTF.cmake
|
||||
Tracy.cmake
|
||||
Tut.cmake
|
||||
UI.cmake
|
||||
UnixInstall.cmake
|
||||
Variables.cmake
|
||||
VHACD.cmake
|
||||
ViewerMiscLibs.cmake
|
||||
VisualLeakDetector.cmake
|
||||
LibVLCPlugin.cmake
|
||||
|
||||
+9
-15
@@ -7,19 +7,13 @@ add_library( ll::libcurl INTERFACE IMPORTED )
|
||||
|
||||
use_system_binary(libcurl)
|
||||
use_prebuilt_binary(curl)
|
||||
if (WINDOWS)
|
||||
target_link_libraries(ll::libcurl INTERFACE
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libcurl.lib
|
||||
ll::openssl
|
||||
ll::nghttp2
|
||||
ll::zlib-ng
|
||||
)
|
||||
else ()
|
||||
target_link_libraries(ll::libcurl INTERFACE
|
||||
${ARCH_PREBUILT_DIRS_RELEASE}/libcurl.a
|
||||
ll::openssl
|
||||
ll::nghttp2
|
||||
ll::zlib-ng
|
||||
)
|
||||
endif ()
|
||||
|
||||
find_library(CURL_LIBRARY
|
||||
NAMES
|
||||
libcurl.lib
|
||||
libcurl.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::libcurl INTERFACE ${CURL_LIBRARY} ll::openssl ll::nghttp2 ll::zlib-ng)
|
||||
|
||||
target_include_directories( ll::libcurl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
|
||||
include(CMakeCopyIfDifferent)
|
||||
include(Linking)
|
||||
if (USE_DISCORD)
|
||||
include(Discord)
|
||||
endif ()
|
||||
include(OPENAL)
|
||||
|
||||
# When we copy our dependent libraries, we almost always want to copy them to
|
||||
@@ -56,11 +59,6 @@ if(WINDOWS)
|
||||
openjp2.dll
|
||||
)
|
||||
|
||||
if(LLCOMMON_LINK_SHARED)
|
||||
set(release_files ${release_files} libapr-1.dll)
|
||||
set(release_files ${release_files} libaprutil-1.dll)
|
||||
endif()
|
||||
|
||||
# Filenames are different for 32/64 bit BugSplat file and we don't
|
||||
# have any control over them so need to branch.
|
||||
if (USE_BUGSPLAT)
|
||||
@@ -75,6 +73,10 @@ if(WINDOWS)
|
||||
endif(ADDRESS_SIZE EQUAL 32)
|
||||
endif (USE_BUGSPLAT)
|
||||
|
||||
if (TARGET ll::discord_sdk)
|
||||
list(APPEND release_files discord_partner_sdk.dll)
|
||||
endif ()
|
||||
|
||||
if (TARGET ll::openal)
|
||||
list(APPEND release_files openal32.dll alut.dll)
|
||||
endif ()
|
||||
@@ -171,14 +173,9 @@ elseif(DARWIN)
|
||||
libndofdev.dylib
|
||||
)
|
||||
|
||||
if(LLCOMMON_LINK_SHARED)
|
||||
set(release_files ${release_files}
|
||||
libapr-1.0.dylib
|
||||
libapr-1.dylib
|
||||
libaprutil-1.0.dylib
|
||||
libaprutil-1.dylib
|
||||
)
|
||||
endif()
|
||||
if (TARGET ll::discord_sdk)
|
||||
list(APPEND release_files libdiscord_partner_sdk.dylib)
|
||||
endif ()
|
||||
|
||||
if (TARGET ll::openal)
|
||||
list(APPEND release_files libalut.dylib libopenal.dylib)
|
||||
@@ -225,13 +222,6 @@ elseif(LINUX)
|
||||
libgmodule-2.0.so
|
||||
libgobject-2.0.so
|
||||
)
|
||||
|
||||
if(LLCOMMON_LINK_SHARED)
|
||||
set(release_files ${release_files}
|
||||
libapr-1.so.0
|
||||
libaprutil-1.so.0
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
else(WINDOWS)
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
include(Prebuilt)
|
||||
|
||||
include_guard()
|
||||
|
||||
add_library(ll::discord_sdk INTERFACE IMPORTED)
|
||||
target_compile_definitions(ll::discord_sdk INTERFACE LL_DISCORD=1)
|
||||
|
||||
use_prebuilt_binary(discord_sdk)
|
||||
|
||||
target_include_directories(ll::discord_sdk SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/discord_sdk)
|
||||
target_link_libraries(ll::discord_sdk INTERFACE discord_partner_sdk)
|
||||
+13
-10
@@ -2,18 +2,21 @@
|
||||
include(Prebuilt)
|
||||
|
||||
include_guard()
|
||||
add_library( ll::expat INTERFACE IMPORTED )
|
||||
add_library(ll::expat INTERFACE IMPORTED)
|
||||
|
||||
use_system_binary(expat)
|
||||
use_prebuilt_binary(expat)
|
||||
|
||||
if (WINDOWS)
|
||||
target_compile_definitions( ll::expat INTERFACE XML_STATIC=1)
|
||||
target_link_libraries( ll::expat INTERFACE
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libexpatd.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libexpat.lib)
|
||||
else ()
|
||||
target_link_libraries( ll::expat INTERFACE
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libexpat.a
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libexpat.a)
|
||||
target_compile_definitions(ll::expat INTERFACE XML_STATIC=1)
|
||||
endif ()
|
||||
target_include_directories( ll::expat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include )
|
||||
|
||||
find_library(EXPAT_LIBRARY
|
||||
NAMES
|
||||
libexpat.lib
|
||||
libexpat.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::expat INTERFACE ${EXPAT_LIBRARY})
|
||||
|
||||
target_include_directories(ll::expat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
|
||||
|
||||
@@ -9,9 +9,10 @@ use_system_binary(freetype)
|
||||
use_prebuilt_binary(freetype)
|
||||
target_include_directories( ll::freetype SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/freetype2/)
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::freetype INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/freetype.lib)
|
||||
else()
|
||||
target_link_libraries( ll::freetype INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libfreetype.a)
|
||||
endif()
|
||||
find_library(FREETYPE_LIBRARY
|
||||
NAMES
|
||||
freetype.lib
|
||||
libfreetype.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::freetype INTERFACE ${FREETYPE_LIBRARY})
|
||||
|
||||
+10
-10
@@ -8,17 +8,17 @@ use_prebuilt_binary(dictionaries)
|
||||
add_library( ll::hunspell INTERFACE IMPORTED )
|
||||
use_system_binary(hunspell)
|
||||
use_prebuilt_binary(libhunspell)
|
||||
|
||||
if (WINDOWS)
|
||||
target_compile_definitions( ll::hunspell INTERFACE HUNSPELL_STATIC=1)
|
||||
target_link_libraries( ll::hunspell INTERFACE
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/libhunspell.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell.lib
|
||||
)
|
||||
elseif(DARWIN)
|
||||
target_link_libraries( ll::hunspell INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell-1.7.a
|
||||
)
|
||||
elseif(LINUX)
|
||||
target_link_libraries( ll::hunspell INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libhunspell-1.7.a
|
||||
)
|
||||
endif()
|
||||
|
||||
find_library(HUNSPELL_LIBRARY
|
||||
NAMES
|
||||
libhunspell.lib
|
||||
libhunspell-1.7.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::hunspell INTERFACE ${HUNSPELL_LIBRARY})
|
||||
|
||||
target_include_directories( ll::hunspell SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/hunspell)
|
||||
|
||||
+10
-10
@@ -8,13 +8,13 @@ add_library( ll::libjpeg INTERFACE IMPORTED )
|
||||
|
||||
use_system_binary(libjpeg)
|
||||
use_prebuilt_binary(libjpeg-turbo)
|
||||
if (LINUX)
|
||||
target_link_libraries( ll::libjpeg INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a)
|
||||
elseif (DARWIN)
|
||||
target_link_libraries( ll::libjpeg INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libjpeg.a)
|
||||
elseif (WINDOWS)
|
||||
target_link_libraries( ll::libjpeg INTERFACE
|
||||
debug ${ARCH_PREBUILT_DIRS_DEBUG}/jpeg.lib
|
||||
optimized ${ARCH_PREBUILT_DIRS_RELEASE}/jpeg.lib)
|
||||
endif (LINUX)
|
||||
target_include_directories( ll::libjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
|
||||
|
||||
find_library(JPEG_LIBRARY
|
||||
NAMES
|
||||
jpeg.lib
|
||||
libjpeg.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::libjpeg INTERFACE ${JPEG_LIBRARY})
|
||||
|
||||
target_include_directories(ll::libjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
|
||||
|
||||
@@ -92,6 +92,13 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
|
||||
target_include_directories (PROJECT_${project}_TEST_${name} PRIVATE ${LIBS_OPEN_DIR}/test )
|
||||
|
||||
set_target_properties(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
|
||||
if (DARWIN)
|
||||
set_target_properties(PROJECT_${project}_TEST_${name}
|
||||
PROPERTIES
|
||||
BUILD_WITH_INSTALL_RPATH 1
|
||||
INSTALL_RPATH "@executable_path/Resources"
|
||||
)
|
||||
endif(DARWIN)
|
||||
|
||||
#
|
||||
# Per-codefile additional / external project dep and lib dep property extraction
|
||||
@@ -225,7 +232,10 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
|
||||
# test binaries always need to be signed for local development
|
||||
set_target_properties(INTEGRATION_TEST_${testname}
|
||||
PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-")
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "-"
|
||||
BUILD_WITH_INSTALL_RPATH 1
|
||||
INSTALL_RPATH "@executable_path/Resources"
|
||||
)
|
||||
endif ()
|
||||
|
||||
# Add link deps to the executable
|
||||
|
||||
+14
-2
@@ -13,14 +13,26 @@ add_library( ll::kdu INTERFACE IMPORTED )
|
||||
if (USE_KDU)
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(kdu)
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::kdu INTERFACE kdu.lib)
|
||||
find_library(KDU_LIBRARY
|
||||
NAMES
|
||||
kdu
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
else (WINDOWS)
|
||||
target_link_libraries( ll::kdu INTERFACE libkdu.a)
|
||||
find_library(KDU_LIBRARY
|
||||
NAMES
|
||||
libkdu.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
endif (WINDOWS)
|
||||
|
||||
target_link_libraries(ll::kdu INTERFACE ${KDU_LIBRARY})
|
||||
|
||||
target_include_directories( ll::kdu SYSTEM INTERFACE
|
||||
${AUTOBUILD_INSTALL_DIR}/include/kdu
|
||||
${LIBS_OPEN_DIR}/llkdu
|
||||
)
|
||||
target_compile_definitions(ll::kdu INTERFACE KDU_NO_THREADS=1)
|
||||
endif (USE_KDU)
|
||||
|
||||
@@ -22,14 +22,25 @@ if (HAVOK)
|
||||
include(Havok)
|
||||
use_prebuilt_binary(llphysicsextensions_source)
|
||||
set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/src)
|
||||
target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions)
|
||||
if(DARWIN)
|
||||
set(LLPHYSICSEXTENSIONS_STUB_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub)
|
||||
# can't set these library dependencies per-arch here, need to do it using XCODE_ATTRIBUTE_OTHER_LDFLAGS[arch=*] in newview/CMakeLists.txt
|
||||
#target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions)
|
||||
#target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensionsstub)
|
||||
else()
|
||||
target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions)
|
||||
target_compile_definitions( llphysicsextensions_impl INTERFACE LL_HAVOK=1 )
|
||||
endif()
|
||||
target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
|
||||
elseif (HAVOK_TPV)
|
||||
use_prebuilt_binary(llphysicsextensions_tpv)
|
||||
target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions_tpv)
|
||||
else (HAVOK)
|
||||
use_prebuilt_binary(llphysicsextensions_stub)
|
||||
set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub)
|
||||
target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensionsstub)
|
||||
endif (HAVOK)
|
||||
|
||||
target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
|
||||
if (NOT DARWIN)
|
||||
if(WINDOWS)
|
||||
target_link_libraries( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS}/llphysicsextensions_tpv.lib)
|
||||
elseif(LINUX)
|
||||
target_link_libraries( llphysicsextensions_impl INTERFACE ${ARCH_PREBUILT_DIRS}/libllphysicsextensions_tpv.a)
|
||||
endif()
|
||||
target_compile_definitions( llphysicsextensions_impl INTERFACE LL_HAVOK=1 )
|
||||
endif()
|
||||
target_include_directories( llphysicsextensions_impl INTERFACE ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
|
||||
endif ()
|
||||
|
||||
@@ -24,26 +24,35 @@ use_prebuilt_binary(colladadom)
|
||||
use_prebuilt_binary(minizip-ng) # needed for colladadom
|
||||
use_prebuilt_binary(libxml2)
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::minizip-ng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/minizip.lib )
|
||||
else()
|
||||
target_link_libraries( ll::minizip-ng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libminizip.a )
|
||||
endif()
|
||||
find_library(MINIZIPNG_LIBRARY
|
||||
NAMES
|
||||
minizip.lib
|
||||
libminizip.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::minizip-ng INTERFACE ${MINIZIPNG_LIBRARY})
|
||||
|
||||
find_library(LIBXML2_LIBRARY
|
||||
NAMES
|
||||
libxml2.lib
|
||||
libxml2.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::libxml INTERFACE ${LIBXML2_LIBRARY})
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::libxml INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libxml2.lib Bcrypt.lib)
|
||||
else()
|
||||
target_link_libraries( ll::libxml INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libxml2.a)
|
||||
target_link_libraries( ll::libxml INTERFACE Bcrypt.lib)
|
||||
endif()
|
||||
|
||||
target_include_directories( ll::colladadom SYSTEM INTERFACE
|
||||
${LIBS_PREBUILT_DIR}/include/collada
|
||||
${LIBS_PREBUILT_DIR}/include/collada/1.4
|
||||
)
|
||||
if (WINDOWS)
|
||||
target_link_libraries(ll::colladadom INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libcollada14dom23-s.lib ll::libxml ll::minizip-ng )
|
||||
elseif (DARWIN)
|
||||
target_link_libraries(ll::colladadom INTERFACE collada14dom ll::boost ll::libxml ll::minizip-ng)
|
||||
elseif (LINUX)
|
||||
target_link_libraries(ll::colladadom INTERFACE collada14dom ll::boost ll::libxml ll::minizip-ng)
|
||||
endif()
|
||||
|
||||
find_library(COLLADADOM_LIBRARY
|
||||
NAMES
|
||||
libcollada14dom23-s.lib
|
||||
collada14dom
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::colladadom INTERFACE ${COLLADADOM_LIBRARY} ll::boost ll::libxml ll::minizip-ng)
|
||||
|
||||
@@ -9,20 +9,16 @@ use_prebuilt_binary(vlc-bin)
|
||||
set(LIBVLCPLUGIN ON CACHE BOOL
|
||||
"LIBVLCPLUGIN support for the llplugin/llmedia test apps.")
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::libvlc INTERFACE
|
||||
libvlc.lib
|
||||
libvlccore.lib
|
||||
)
|
||||
elseif (DARWIN)
|
||||
target_link_libraries( ll::libvlc INTERFACE
|
||||
libvlc.dylib
|
||||
libvlccore.dylib
|
||||
)
|
||||
elseif (LINUX)
|
||||
# Specify a full path to make sure we get a static link
|
||||
target_link_libraries( ll::libvlc INTERFACE
|
||||
${LIBS_PREBUILT_DIR}/lib/libvlc.a
|
||||
${LIBS_PREBUILT_DIR}/lib/libvlccore.a
|
||||
)
|
||||
endif (WINDOWS)
|
||||
find_library(VLC_LIBRARY
|
||||
NAMES
|
||||
libvlc.lib
|
||||
libvlc.dylib
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(VLCCORE_LIBRARY
|
||||
NAMES
|
||||
libvlccore.lib
|
||||
libvlccore.dylib
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::libvlc INTERFACE ${VLC_LIBRARY} ${VLCCORE_LIBRARY})
|
||||
|
||||
@@ -38,9 +38,10 @@ endif ()
|
||||
# windows) and CMAKE_BUILD_TYPE on Makefile based generators (like linux). The reason for this is
|
||||
# that CMAKE_BUILD_TYPE is essentially meaningless at configuration time for IDE generators and
|
||||
# CMAKE_CFG_INTDIR is meaningless at build time for Makefile generators
|
||||
|
||||
link_directories(${AUTOBUILD_INSTALL_DIR}/lib/$<LOWER_CASE:$<CONFIG>>)
|
||||
link_directories(${AUTOBUILD_INSTALL_DIR}/lib/release)
|
||||
if(NOT DARWIN)
|
||||
link_directories(${AUTOBUILD_INSTALL_DIR}/lib/$<LOWER_CASE:$<CONFIG>>)
|
||||
link_directories(${AUTOBUILD_INSTALL_DIR}/lib/release)
|
||||
endif(NOT DARWIN)
|
||||
|
||||
add_library( ll::oslibraries INTERFACE IMPORTED )
|
||||
|
||||
@@ -67,24 +68,25 @@ elseif (WINDOWS)
|
||||
legacy_stdio_definitions
|
||||
)
|
||||
else()
|
||||
include(CMakeFindFrameworks)
|
||||
find_library(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
find_library(CARBON_LIBRARY Carbon)
|
||||
find_library(COCOA_LIBRARY Cocoa)
|
||||
find_library(IOKIT_LIBRARY IOKit)
|
||||
|
||||
find_library(AGL_LIBRARY AGL)
|
||||
find_library(APPKIT_LIBRARY AppKit)
|
||||
find_library(COREAUDIO_LIBRARY CoreAudio)
|
||||
find_library(COREGRAPHICS_LIBRARY CoreGraphics)
|
||||
find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
|
||||
|
||||
target_link_libraries( ll::oslibraries INTERFACE
|
||||
${COCOA_LIBRARY}
|
||||
${IOKIT_LIBRARY}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${CARBON_LIBRARY}
|
||||
${AGL_LIBRARY}
|
||||
${APPKIT_LIBRARY}
|
||||
${COREAUDIO_LIBRARY}
|
||||
${AUDIOTOOLBOX_LIBRARY}
|
||||
${COREGRAPHICS_LIBRARY}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ add_library( ll::meshoptimizer INTERFACE IMPORTED )
|
||||
use_system_binary(meshoptimizer)
|
||||
use_prebuilt_binary(meshoptimizer)
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.lib)
|
||||
elseif (LINUX)
|
||||
target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.o)
|
||||
elseif (DARWIN)
|
||||
target_link_libraries( ll::meshoptimizer INTERFACE libmeshoptimizer.a)
|
||||
endif (WINDOWS)
|
||||
find_library(MESHOPTIMIZER_LIBRARY
|
||||
NAMES
|
||||
meshoptimizer.lib
|
||||
libmeshoptimizer.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_include_directories( ll::meshoptimizer SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/meshoptimizer)
|
||||
target_link_libraries(ll::meshoptimizer INTERFACE ${MESHOPTIMIZER_LIBRARY})
|
||||
|
||||
target_include_directories(ll::meshoptimizer SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/meshoptimizer)
|
||||
|
||||
@@ -13,12 +13,15 @@ if (NDOF)
|
||||
use_prebuilt_binary(open-libndofdev)
|
||||
endif (WINDOWS OR DARWIN)
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::ndof INTERFACE libndofdev)
|
||||
elseif (DARWIN OR LINUX)
|
||||
target_link_libraries( ll::ndof INTERFACE ndofdev)
|
||||
endif (WINDOWS)
|
||||
target_compile_definitions( ll::ndof INTERFACE LIB_NDOF=1)
|
||||
find_library(NDOF_LIBRARY
|
||||
NAMES
|
||||
libndofdev
|
||||
ndofdev
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::ndof INTERFACE ${NDOF_LIBRARY})
|
||||
|
||||
target_compile_definitions(ll::ndof INTERFACE LIB_NDOF=1)
|
||||
endif (NDOF)
|
||||
|
||||
|
||||
|
||||
@@ -6,9 +6,12 @@ add_library( ll::nghttp2 INTERFACE IMPORTED )
|
||||
|
||||
use_system_binary(nghttp2)
|
||||
use_prebuilt_binary(nghttp2)
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::nghttp2 INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/nghttp2.lib)
|
||||
else ()
|
||||
target_link_libraries( ll::nghttp2 INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libnghttp2.a)
|
||||
endif ()
|
||||
|
||||
find_library(NGHTTP2_LIBRARY
|
||||
NAMES
|
||||
nghttp2.lib
|
||||
libnghttp2.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::nghttp2 INTERFACE ${NGHTTP2_LIBRARY})
|
||||
target_include_directories( ll::nghttp2 SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/nghttp2)
|
||||
|
||||
+18
-17
@@ -8,7 +8,7 @@ include_guard()
|
||||
# to have memory leaks, has no option to play music streams
|
||||
# It probably makes sense to to completely remove it
|
||||
|
||||
set(USE_OPENAL OFF CACHE BOOL "Enable OpenAL")
|
||||
set(USE_OPENAL ON CACHE BOOL "Enable OpenAL")
|
||||
# ND: To streamline arguments passed, switch from OPENAL to USE_OPENAL
|
||||
# To not break all old build scripts convert old arguments but warn about it
|
||||
if(OPENAL)
|
||||
@@ -22,20 +22,21 @@ if (USE_OPENAL)
|
||||
target_compile_definitions( ll::openal INTERFACE LL_OPENAL=1)
|
||||
use_prebuilt_binary(openal)
|
||||
|
||||
if(WINDOWS)
|
||||
target_link_libraries( ll::openal INTERFACE
|
||||
OpenAL32
|
||||
alut
|
||||
)
|
||||
elseif(LINUX)
|
||||
target_link_libraries( ll::openal INTERFACE
|
||||
openal
|
||||
alut
|
||||
)
|
||||
else()
|
||||
target_link_libraries( ll::openal INTERFACE
|
||||
openal
|
||||
alut
|
||||
)
|
||||
endif()
|
||||
find_library(OPENAL_LIBRARY
|
||||
NAMES
|
||||
OpenAL32
|
||||
openal
|
||||
libopenal.dylib
|
||||
libopenal.so
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(ALUT_LIBRARY
|
||||
NAMES
|
||||
alut
|
||||
libalut.dylib
|
||||
libalut.so
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::openal INTERFACE ${OPENAL_LIBRARY} ${ALUT_LIBRARY})
|
||||
|
||||
endif ()
|
||||
|
||||
@@ -1,11 +1,22 @@
|
||||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
include_guard()
|
||||
|
||||
include(Prebuilt)
|
||||
include(Linking)
|
||||
|
||||
add_library( ll::openjpeg INTERFACE IMPORTED )
|
||||
|
||||
use_system_binary(openjpeg)
|
||||
use_prebuilt_binary(openjpeg)
|
||||
|
||||
target_link_libraries(ll::openjpeg INTERFACE openjp2 )
|
||||
target_include_directories( ll::openjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/openjpeg)
|
||||
find_library(OPENJPEG_LIBRARY
|
||||
NAMES
|
||||
openjp2
|
||||
openjp2.lib
|
||||
libopenjp2.a
|
||||
libopenjp2.so
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::openjpeg INTERFACE ${OPENJPEG_LIBRARY})
|
||||
|
||||
target_include_directories(ll::openjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/openjpeg)
|
||||
|
||||
@@ -7,12 +7,24 @@ add_library( ll::openssl INTERFACE IMPORTED )
|
||||
|
||||
use_system_binary(openssl)
|
||||
use_prebuilt_binary(openssl)
|
||||
|
||||
find_library(SSL_LIBRARY
|
||||
NAMES
|
||||
libssl.lib
|
||||
libssl.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
find_library(CRYPTO_LIBRARY
|
||||
NAMES
|
||||
libcrypto.lib
|
||||
libcrypto.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::openssl INTERFACE ${SSL_LIBRARY} ${CRYPTO_LIBRARY})
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries(ll::openssl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libssl.lib ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto.lib Crypt32.lib)
|
||||
elseif (LINUX)
|
||||
target_link_libraries(ll::openssl INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libssl.a ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto.a dl)
|
||||
else()
|
||||
target_link_libraries(ll::openssl INTERFACE ssl crypto)
|
||||
target_link_libraries(ll::openssl INTERFACE Crypt32.lib)
|
||||
endif (WINDOWS)
|
||||
target_include_directories( ll::openssl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
|
||||
|
||||
target_include_directories(ll::openssl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
|
||||
|
||||
|
||||
@@ -6,9 +6,12 @@ add_library( ll::libpng INTERFACE IMPORTED )
|
||||
|
||||
use_system_binary(libpng)
|
||||
use_prebuilt_binary(libpng)
|
||||
if (WINDOWS)
|
||||
target_link_libraries(ll::libpng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libpng16.lib)
|
||||
else()
|
||||
target_link_libraries(ll::libpng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libpng16.a)
|
||||
endif()
|
||||
target_include_directories( ll::libpng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/libpng16)
|
||||
|
||||
find_library(LIBPNG_LIBRARY
|
||||
NAMES
|
||||
libpng16.lib
|
||||
libpng16.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::libpng INTERFACE ${LIBPNG_LIBRARY})
|
||||
target_include_directories(ll::libpng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/libpng16)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
include(OpenGL)
|
||||
|
||||
add_library( ll::pluginlibraries INTERFACE IMPORTED )
|
||||
|
||||
if (WINDOWS)
|
||||
@@ -13,4 +15,6 @@ if (WINDOWS)
|
||||
)
|
||||
endif (WINDOWS)
|
||||
|
||||
target_link_libraries( ll::pluginlibraries INTERFACE OpenGL::GL)
|
||||
|
||||
target_include_directories( ll::pluginlibraries INTERFACE ${CMAKE_SOURCE_DIR}/llimage ${CMAKE_SOURCE_DIR}/llrender)
|
||||
|
||||
@@ -13,7 +13,7 @@ elseif (WINDOWS)
|
||||
foreach(hive HKEY_CURRENT_USER HKEY_LOCAL_MACHINE)
|
||||
# prefer more recent Python versions to older ones, if multiple versions
|
||||
# are installed
|
||||
foreach(pyver 3.12 3.11 3.10 3.9 3.8 3.7)
|
||||
foreach(pyver 3.13 3.12 3.11 3.10 3.9 3.8 3.7)
|
||||
list(APPEND regpaths "[${hive}\\SOFTWARE\\Python\\PythonCore\\${pyver}\\InstallPath]")
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
include(Prebuilt)
|
||||
|
||||
add_library(ll::sse2neon INTERFACE IMPORTED)
|
||||
|
||||
if (DARWIN)
|
||||
use_system_binary(sse2neon)
|
||||
use_prebuilt_binary(sse2neon)
|
||||
|
||||
target_include_directories( ll::sse2neon SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/sse2neon)
|
||||
endif()
|
||||
@@ -15,6 +15,7 @@ endif()
|
||||
if (USE_TRACY)
|
||||
option(USE_TRACY_ON_DEMAND "Use on-demand Tracy profiling." ON)
|
||||
option(USE_TRACY_LOCAL_ONLY "Disallow remote Tracy profiling." OFF)
|
||||
option(USE_TRACY_GPU "Use Tracy GPU profiling" OFF)
|
||||
|
||||
use_system_binary(tracy)
|
||||
use_prebuilt_binary(tracy)
|
||||
@@ -31,9 +32,8 @@ if (USE_TRACY)
|
||||
target_compile_definitions(ll::tracy INTERFACE -DTRACY_NO_BROADCAST=1 -DTRACY_ONLY_LOCALHOST=1)
|
||||
endif ()
|
||||
|
||||
# GHA runners don't always provide invariant TSC support, but always build with LL_TESTS enabled
|
||||
if (DARWIN AND LL_TESTS)
|
||||
target_compile_definitions(ll::tracy INTERFACE -DTRACY_TIMER_FALLBACK=1)
|
||||
if (USE_TRACY_GPU AND NOT DARWIN) # Tracy OpenGL mode is incompatible with macOS/iOS
|
||||
target_compile_definitions(ll::tracy INTERFACE -DLL_PROFILER_ENABLE_TRACY_OPENGL=1)
|
||||
endif ()
|
||||
|
||||
# See: indra/llcommon/llprofiler.h
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# -*- cmake -*-
|
||||
include(Prebuilt)
|
||||
|
||||
add_library(ll::vhacd INTERFACE IMPORTED)
|
||||
|
||||
use_system_binary(vhacd)
|
||||
use_prebuilt_binary(vhacd)
|
||||
|
||||
target_include_directories(ll::vhacd SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/vhacd/)
|
||||
@@ -144,52 +144,19 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(DARWIN 1)
|
||||
|
||||
string(REGEX MATCH "-mmacosx-version-min=([^ ]+)" scratch "$ENV{LL_BUILD}")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "${CMAKE_MATCH_1}")
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "${CMAKE_MATCH_1}" CACHE STRING "macOS Deploy Target" FORCE)
|
||||
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}'")
|
||||
# Use dwarf symbols for most libraries for compilation speed
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT "dwarf")
|
||||
|
||||
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}'")
|
||||
|
||||
# allow disabling this check by setting LL_SKIP_REQUIRE_SYSROOT either ON as cmake cache var or non-empty as environment var
|
||||
set(LL_SKIP_REQUIRE_SYSROOT OFF CACHE BOOL "Skip requirement to set toolchain sysroot ahead of time. Not skipped by default for consistency, but skipping can be useful for selecting alternative xcode versions side by side")
|
||||
if("$ENV{LL_SKIP_REQUIRE_SYSROOT}" STREQUAL "" AND NOT ${LL_SKIP_REQUIRE_SYSROOT})
|
||||
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)
|
||||
endif()
|
||||
message(STATUS "CMAKE_OSX_SYSROOT = '${CMAKE_OSX_SYSROOT}'")
|
||||
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_VERSION "com.apple.compilers.llvm.clang.1_0")
|
||||
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)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CLANG_X86_VECTOR_INSTRUCTIONS sse4.2)
|
||||
# we must hard code this to off for now. xcode's built in signing does not
|
||||
# handle embedded app bundles such as CEF and others. Any signing for local
|
||||
# development must be done after the build as we do in viewer_manifest.py for
|
||||
@@ -204,9 +171,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING YES)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION NO)
|
||||
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(CMAKE_OSX_ARCHITECTURES "arm64;x86_64" CACHE STRING "macOS Build Arch" FORCE)
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
||||
# Default deploy grid
|
||||
|
||||
+12
-20
@@ -1,32 +1,24 @@
|
||||
# -*- cmake -*-
|
||||
include_guard()
|
||||
|
||||
include(Linking)
|
||||
include(Prebuilt)
|
||||
|
||||
include_guard()
|
||||
|
||||
add_library( ll::webrtc INTERFACE IMPORTED )
|
||||
target_include_directories( ll::webrtc SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/webrtc" "${LIBS_PREBUILT_DIR}/include/webrtc/third_party/abseil-cpp")
|
||||
use_prebuilt_binary(webrtc)
|
||||
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::webrtc INTERFACE webrtc.lib )
|
||||
elseif (DARWIN)
|
||||
FIND_LIBRARY(COREAUDIO_LIBRARY CoreAudio)
|
||||
FIND_LIBRARY(COREGRAPHICS_LIBRARY CoreGraphics)
|
||||
FIND_LIBRARY(AUDIOTOOLBOX_LIBRARY AudioToolbox)
|
||||
FIND_LIBRARY(COREFOUNDATION_LIBRARY CoreFoundation)
|
||||
FIND_LIBRARY(COCOA_LIBRARY Cocoa)
|
||||
find_library(WEBRTC_LIBRARY
|
||||
NAMES
|
||||
webrtc
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries( ll::webrtc INTERFACE
|
||||
libwebrtc.a
|
||||
${COREAUDIO_LIBRARY}
|
||||
${AUDIOTOOLBOX_LIBRARY}
|
||||
${COREGRAPHICS_LIBRARY}
|
||||
${COREFOUNDATION_LIBRARY}
|
||||
${COCOA_LIBRARY}
|
||||
)
|
||||
target_link_libraries( ll::webrtc INTERFACE ${WEBRTC_LIBRARY} )
|
||||
|
||||
if (DARWIN)
|
||||
target_link_libraries( ll::webrtc INTERFACE ll::oslibraries )
|
||||
elseif (LINUX)
|
||||
target_link_libraries( ll::webrtc INTERFACE libwebrtc.a X11 )
|
||||
endif (WINDOWS)
|
||||
target_link_libraries( ll::webrtc INTERFACE X11 )
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
@@ -11,11 +11,14 @@ if(USE_CONAN )
|
||||
endif()
|
||||
|
||||
use_prebuilt_binary(zlib-ng)
|
||||
if (WINDOWS)
|
||||
target_link_libraries( ll::zlib-ng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/zlib.lib )
|
||||
else()
|
||||
target_link_libraries( ll::zlib-ng INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/libz.a )
|
||||
endif (WINDOWS)
|
||||
|
||||
find_library(ZLIBNG_LIBRARY
|
||||
NAMES
|
||||
zlib.lib
|
||||
libz.a
|
||||
PATHS "${ARCH_PREBUILT_DIRS_RELEASE}" REQUIRED NO_DEFAULT_PATH)
|
||||
|
||||
target_link_libraries(ll::zlib-ng INTERFACE ${ZLIBNG_LIBRARY})
|
||||
|
||||
if( NOT LINUX )
|
||||
target_include_directories( ll::zlib-ng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/zlib-ng)
|
||||
|
||||
@@ -23,8 +23,14 @@ if (USE_BUGSPLAT)
|
||||
elseif (DARWIN)
|
||||
find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED
|
||||
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
find_library(CRASHREPORTED_LIBRARIES CrashReporter REQUIRED
|
||||
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
find_library(HOCKEYSDK_LIBRARIES HockeySDK REQUIRED
|
||||
NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
|
||||
target_link_libraries( ll::bugsplat INTERFACE
|
||||
${BUGSPLAT_LIBRARIES}
|
||||
${CRASHREPORTED_LIBRARIES}
|
||||
${HOCKEYSDK_LIBRARIES}
|
||||
)
|
||||
else (WINDOWS)
|
||||
message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF")
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
# -*- cmake -*-
|
||||
if (XXHASH_CMAKE_INCLUDED)
|
||||
return()
|
||||
endif (XXHASH_CMAKE_INCLUDED)
|
||||
set (XXHASH_CMAKE_INCLUDED TRUE)
|
||||
include_guard()
|
||||
|
||||
include(Prebuilt)
|
||||
use_prebuilt_binary(xxhash)
|
||||
|
||||
@@ -1,19 +1,5 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
# 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 3.8.0 FATAL_ERROR)
|
||||
|
||||
set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
|
||||
"The root project/makefile/solution name. Defaults to SecondLife.")
|
||||
project(${ROOT_PROJECT_NAME})
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
|
||||
|
||||
include(Variables)
|
||||
|
||||
# add a target to generate API documentation with Doxygen
|
||||
find_package(Doxygen)
|
||||
if(DOXYGEN_FOUND)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
# -*- cmake -*-
|
||||
add_subdirectory(llui_libtest)
|
||||
IF (LLIMAGE_LIBTEST)
|
||||
MESSAGE(STATUS "Build llimage_libtest")
|
||||
add_subdirectory(llimage_libtest)
|
||||
ELSE (LLIMAGE_LIBTEST)
|
||||
MESSAGE(STATUS "Skip llimage_libtest")
|
||||
ENDIF (LLIMAGE_LIBTEST)
|
||||
add_subdirectory(llimage_libtest)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- cmake -*-
|
||||
|
||||
# Integration tests of the llimage library (JPEG2000, PNG, jpeg, etc... images reading and writing)
|
||||
if (LL_TESTS)
|
||||
|
||||
project (llimage_libtest)
|
||||
|
||||
@@ -8,9 +9,7 @@ include(00-Common)
|
||||
include(LLCommon)
|
||||
include(LLImage)
|
||||
include(LLMath)
|
||||
include(LLImageJ2COJ)
|
||||
include(LLKDU)
|
||||
include(LLFileSystem)
|
||||
|
||||
set(llimage_libtest_SOURCE_FILES
|
||||
llimage_libtest.cpp
|
||||
@@ -24,17 +23,9 @@ set(llimage_libtest_HEADER_FILES
|
||||
list(APPEND llimage_libtest_SOURCE_FILES ${llimage_libtest_HEADER_FILES})
|
||||
|
||||
add_executable(llimage_libtest
|
||||
WIN32
|
||||
MACOSX_BUNDLE
|
||||
${llimage_libtest_SOURCE_FILES}
|
||||
)
|
||||
|
||||
set_target_properties(llimage_libtest
|
||||
PROPERTIES
|
||||
WIN32_EXECUTABLE
|
||||
FALSE
|
||||
)
|
||||
|
||||
# Libraries on which this application depends on
|
||||
# Sort by high-level to low-level
|
||||
target_link_libraries(llimage_libtest
|
||||
@@ -42,64 +33,9 @@ target_link_libraries(llimage_libtest
|
||||
llfilesystem
|
||||
llmath
|
||||
llimage
|
||||
llkdu
|
||||
llimagej2coj
|
||||
)
|
||||
|
||||
if (DARWIN)
|
||||
# Path inside the app bundle where we'll need to copy libraries
|
||||
set(LLIMAGE_LIBTEST_DESTINATION_DIR
|
||||
${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/llimage_libtest.app/Contents/Resources
|
||||
)
|
||||
# Create the Contents/Resources directory
|
||||
add_custom_command(
|
||||
TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
ARGS
|
||||
-E
|
||||
make_directory
|
||||
${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
COMMENT "Creating Resources directory in app bundle."
|
||||
)
|
||||
else (DARWIN)
|
||||
set(LLIMAGE_LIBTEST_DESTINATION_DIR
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/
|
||||
)
|
||||
endif (DARWIN)
|
||||
|
||||
get_target_property(BUILT_LLCOMMON llcommon LOCATION)
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${BUILT_LLCOMMON} ${LLIMAGE_LIBTEST_DESTINATION_DIR}
|
||||
DEPENDS ${BUILT_LLCOMMON}
|
||||
)
|
||||
|
||||
if (DARWIN)
|
||||
# Copy the required libraries to the package app
|
||||
add_custom_command(TARGET llimage_libtest POST_BUILD
|
||||
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 ${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 ${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)
|
||||
# Check indra/test_apps/llplugintest/CMakeLists.txt for an example of what to copy over for Windows and how
|
||||
endif (WINDOWS)
|
||||
|
||||
# Ensure people working on the viewer don't break this library
|
||||
# *NOTE: This could be removed, or only built by TeamCity, if the build
|
||||
# and link times become too long.
|
||||
add_dependencies(viewer llimage_libtest)
|
||||
|
||||
endif(LL_TESTS)
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
#include "v4coloru.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llcleanup.h"
|
||||
#include "lltrace.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
// system libraries
|
||||
#include <iostream>
|
||||
@@ -573,10 +575,10 @@ int main(int argc, char** argv)
|
||||
|
||||
|
||||
// Create the logging thread if required
|
||||
if (LLFastTimer::sMetricLog)
|
||||
if (LLTrace::BlockTimer::sMetricLog)
|
||||
{
|
||||
LLFastTimer::sLogLock = new LLMutex(NULL);
|
||||
fast_timer_log_thread = new LogThread(LLFastTimer::sLogName);
|
||||
LLTrace::BlockTimer::setLogLock(new LLMutex());
|
||||
fast_timer_log_thread = new LogThread(LLTrace::BlockTimer::sLogName);
|
||||
fast_timer_log_thread->start();
|
||||
}
|
||||
|
||||
@@ -618,9 +620,9 @@ int main(int argc, char** argv)
|
||||
// Output perf data if requested by user
|
||||
if (analyze_performance)
|
||||
{
|
||||
std::string baseline_name = LLFastTimer::sLogName + "_baseline.slp";
|
||||
std::string current_name = LLFastTimer::sLogName + ".slp";
|
||||
std::string report_name = LLFastTimer::sLogName + "_report.csv";
|
||||
std::string baseline_name = LLTrace::BlockTimer::sLogName + "_baseline.slp";
|
||||
std::string current_name = LLTrace::BlockTimer::sLogName + ".slp";
|
||||
std::string report_name = LLTrace::BlockTimer::sLogName + "_report.csv";
|
||||
|
||||
std::cout << "Analyzing performance, check report in : " << report_name << std::endl;
|
||||
|
||||
@@ -628,9 +630,9 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
// Stop the perf gathering system if needed
|
||||
if (LLFastTimer::sMetricLog)
|
||||
if (LLTrace::BlockTimer::sMetricLog)
|
||||
{
|
||||
LLMetricPerformanceTesterBasic::deleteTester(LLFastTimer::sLogName);
|
||||
LLMetricPerformanceTesterBasic::deleteTester(LLTrace::BlockTimer::sLogName);
|
||||
sAllDone = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ set(llappearance_SOURCE_FILES
|
||||
llavatarjoint.cpp
|
||||
llavatarjointmesh.cpp
|
||||
lldriverparam.cpp
|
||||
lljointdata.h
|
||||
lllocaltextureobject.cpp
|
||||
llpolyskeletaldistortion.cpp
|
||||
llpolymesh.cpp
|
||||
|
||||
@@ -29,16 +29,17 @@
|
||||
#include "llavatarappearance.h"
|
||||
#include "llavatarappearancedefines.h"
|
||||
#include "llavatarjointmesh.h"
|
||||
#include "lljointdata.h"
|
||||
#include "llstl.h"
|
||||
#include "lldir.h"
|
||||
#include "llpolymorph.h"
|
||||
#include "llpolymesh.h"
|
||||
#include "llpolyskeletaldistortion.h"
|
||||
#include "llstl.h"
|
||||
#include "lltexglobalcolor.h"
|
||||
#include "llwearabledata.h"
|
||||
#include "boost/bind.hpp"
|
||||
#include "boost/tokenizer.hpp"
|
||||
#include "v4math.h"
|
||||
|
||||
using namespace LLAvatarAppearanceDefines;
|
||||
|
||||
@@ -71,11 +72,13 @@ public:
|
||||
mChildren.clear();
|
||||
}
|
||||
bool parseXml(LLXmlTreeNode* node);
|
||||
glm::mat4 getJointMatrix();
|
||||
|
||||
private:
|
||||
std::string mName;
|
||||
std::string mSupport;
|
||||
std::string mAliases;
|
||||
std::string mGroup;
|
||||
bool mIsJoint;
|
||||
LLVector3 mPos;
|
||||
LLVector3 mEnd;
|
||||
@@ -105,11 +108,17 @@ public:
|
||||
S32 getNumBones() const { return mNumBones; }
|
||||
S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
|
||||
|
||||
private:
|
||||
typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
|
||||
static void getJointMatricesAndHierarhy(
|
||||
LLAvatarBoneInfo* bone_info,
|
||||
LLJointData& data,
|
||||
const glm::mat4& parent_mat);
|
||||
|
||||
private:
|
||||
S32 mNumBones;
|
||||
S32 mNumCollisionVolumes;
|
||||
LLAvatarAppearance::joint_alias_map_t mJointAliasMap;
|
||||
typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
|
||||
bone_info_list_t mBoneInfoList;
|
||||
};
|
||||
|
||||
@@ -799,7 +808,6 @@ void LLAvatarAppearance::buildCharacter()
|
||||
bool status = loadAvatar();
|
||||
stop_glerror();
|
||||
|
||||
// gPrintMessagesThisFrame = true;
|
||||
LL_DEBUGS() << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << LL_ENDL;
|
||||
|
||||
if (!status)
|
||||
@@ -1599,6 +1607,15 @@ bool LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
|
||||
mSupport = "base";
|
||||
}
|
||||
|
||||
// Skeleton has 133 bones, but shader only allows 110 (LL_MAX_JOINTS_PER_MESH_OBJECT)
|
||||
// Groups can be used by importer to cut out unused groups of joints
|
||||
static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
|
||||
if (!node->getFastAttributeString(group_string, mGroup))
|
||||
{
|
||||
LL_WARNS() << "Bone without group " << mName << LL_ENDL;
|
||||
mGroup = "global";
|
||||
}
|
||||
|
||||
if (mIsJoint)
|
||||
{
|
||||
static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
|
||||
@@ -1624,6 +1641,21 @@ bool LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 LLAvatarBoneInfo::getJointMatrix()
|
||||
{
|
||||
glm::mat4 mat(1.0f);
|
||||
// 1. Scaling
|
||||
mat = glm::scale(mat, glm::vec3(mScale[0], mScale[1], mScale[2]));
|
||||
// 2. Rotation (Euler angles rad)
|
||||
mat = glm::rotate(mat, mRot[0], glm::vec3(1, 0, 0));
|
||||
mat = glm::rotate(mat, mRot[1], glm::vec3(0, 1, 0));
|
||||
mat = glm::rotate(mat, mRot[2], glm::vec3(0, 0, 1));
|
||||
// 3. Position
|
||||
mat = glm::translate(mat, glm::vec3(mPos[0], mPos[1], mPos[2]));
|
||||
return mat;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLAvatarSkeletonInfo::parseXml()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1654,6 +1686,25 @@ bool LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLAvatarSkeletonInfo::getJointMatricesAndHierarhy(
|
||||
LLAvatarBoneInfo* bone_info,
|
||||
LLJointData& data,
|
||||
const glm::mat4& parent_mat)
|
||||
{
|
||||
data.mName = bone_info->mName;
|
||||
data.mJointMatrix = bone_info->getJointMatrix();
|
||||
data.mScale = glm::vec3(bone_info->mScale[0], bone_info->mScale[1], bone_info->mScale[2]);
|
||||
data.mRotation = bone_info->mRot;
|
||||
data.mRestMatrix = parent_mat * data.mJointMatrix;
|
||||
data.mIsJoint = bone_info->mIsJoint;
|
||||
data.mGroup = bone_info->mGroup;
|
||||
for (LLAvatarBoneInfo* child_info : bone_info->mChildren)
|
||||
{
|
||||
LLJointData& child_data = data.mChildren.emplace_back();
|
||||
getJointMatricesAndHierarhy(child_info, child_data, data.mRestMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
//Make aliases for joint and push to map.
|
||||
void LLAvatarAppearance::makeJointAliases(LLAvatarBoneInfo *bone_info)
|
||||
{
|
||||
@@ -1715,6 +1766,16 @@ const LLAvatarAppearance::joint_alias_map_t& LLAvatarAppearance::getJointAliases
|
||||
return mJointAliasMap;
|
||||
}
|
||||
|
||||
void LLAvatarAppearance::getJointMatricesAndHierarhy(std::vector<LLJointData> &data) const
|
||||
{
|
||||
glm::mat4 identity(1.f);
|
||||
for (LLAvatarBoneInfo* bone_info : sAvatarSkeletonInfo->mBoneInfoList)
|
||||
{
|
||||
LLJointData& child_data = data.emplace_back();
|
||||
LLAvatarSkeletonInfo::getJointMatricesAndHierarhy(bone_info, child_data, identity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "lltexlayer.h"
|
||||
#include "llviewervisualparam.h"
|
||||
#include "llxmltree.h"
|
||||
#include "v4math.h"
|
||||
|
||||
class LLTexLayerSet;
|
||||
class LLTexGlobalColor;
|
||||
@@ -41,6 +42,7 @@ class LLTexGlobalColorInfo;
|
||||
class LLWearableData;
|
||||
class LLAvatarBoneInfo;
|
||||
class LLAvatarSkeletonInfo;
|
||||
class LLJointData;
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// LLAvatarAppearance
|
||||
@@ -138,7 +140,7 @@ public:
|
||||
LLVector3 mHeadOffset{}; // current head position
|
||||
LLAvatarJoint* mRoot{ nullptr };
|
||||
|
||||
typedef std::map<std::string, LLJoint*> joint_map_t;
|
||||
typedef std::map<std::string, LLJoint*, std::less<>> joint_map_t;
|
||||
joint_map_t mJointMap;
|
||||
|
||||
typedef std::map<std::string, LLVector3> joint_state_map_t;
|
||||
@@ -151,9 +153,11 @@ public:
|
||||
public:
|
||||
typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
|
||||
const avatar_joint_list_t& getSkeleton() { return mSkeleton; }
|
||||
typedef std::map<std::string, std::string> joint_alias_map_t;
|
||||
typedef std::map<std::string, std::string, std::less<>> joint_alias_map_t;
|
||||
const joint_alias_map_t& getJointAliases();
|
||||
|
||||
typedef std::map<std::string, std::string> joint_parent_map_t; // matrix plus parent
|
||||
typedef std::map<std::string, glm::mat4> joint_rest_map_t;
|
||||
void getJointMatricesAndHierarhy(std::vector<LLJointData> &data) const;
|
||||
|
||||
protected:
|
||||
static bool parseSkeletonFile(const std::string& filename, LLXmlTree& skeleton_xml_tree);
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file lljointdata.h
|
||||
* @brief LLJointData class for holding individual joint data and skeleton
|
||||
*
|
||||
* $LicenseInfo:firstyear=2025&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2025, 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_LLJOINTDATA_H
|
||||
#define LL_LLJOINTDATA_H
|
||||
|
||||
#include "v4math.h"
|
||||
|
||||
// may be just move LLAvatarBoneInfo
|
||||
class LLJointData
|
||||
{
|
||||
public:
|
||||
std::string mName;
|
||||
std::string mGroup;
|
||||
glm::mat4 mJointMatrix;
|
||||
glm::mat4 mRestMatrix;
|
||||
glm::vec3 mScale;
|
||||
LLVector3 mRotation;
|
||||
|
||||
typedef std::vector<LLJointData> bones_t;
|
||||
bones_t mChildren;
|
||||
|
||||
bool mIsJoint; // if not, collision_volume
|
||||
enum SupportCategory
|
||||
{
|
||||
SUPPORT_BASE,
|
||||
SUPPORT_EXTENDED
|
||||
};
|
||||
SupportCategory mSupport;
|
||||
void setSupport(const std::string& support)
|
||||
{
|
||||
if (support == "extended")
|
||||
{
|
||||
mSupport = SUPPORT_EXTENDED;
|
||||
}
|
||||
else
|
||||
{
|
||||
mSupport = SUPPORT_BASE;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif //LL_LLJOINTDATA_H
|
||||
@@ -283,6 +283,7 @@ bool LLPolyMeshSharedData::loadMesh( const std::string& fileName )
|
||||
LLFILE* fp = LLFile::fopen(fileName, "rb"); /*Flawfinder: ignore*/
|
||||
if (!fp)
|
||||
{
|
||||
LLError::LLUserWarningMsg::showMissingFiles();
|
||||
LL_ERRS() << "can't open: " << fileName << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
@@ -981,7 +982,7 @@ void LLPolyMesh::initializeForMorph()
|
||||
LLVector4a::memcpyNonAliased16((F32*) mScaledNormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
|
||||
LLVector4a::memcpyNonAliased16((F32*) mBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
|
||||
LLVector4a::memcpyNonAliased16((F32*) mScaledBinormals, (F32*) mSharedData->mBaseNormals, sizeof(LLVector4a) * mSharedData->mNumVertices);
|
||||
LLVector4a::memcpyNonAliased16((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices + mSharedData->mNumVertices%2));
|
||||
memcpy((F32*) mTexCoords, (F32*) mSharedData->mTexCoords, sizeof(LLVector2) * (mSharedData->mNumVertices)); // allocated in LLPolyMeshSharedData::allocateVertexData
|
||||
|
||||
for (S32 i = 0; i < mSharedData->mNumVertices; ++i)
|
||||
{
|
||||
|
||||
@@ -550,12 +550,12 @@ void LLPolyMorphTarget::apply( ESex avatar_sex )
|
||||
|
||||
mLastSex = avatar_sex;
|
||||
|
||||
// Check for NaN condition (NaN is detected if a variable doesn't equal itself.
|
||||
if (mCurWeight != mCurWeight)
|
||||
// Check for NaN condition
|
||||
if (llisnan(mCurWeight))
|
||||
{
|
||||
mCurWeight = 0.0;
|
||||
mCurWeight = 0.f;
|
||||
}
|
||||
if (mLastWeight != mLastWeight)
|
||||
if (llisnan(mLastWeight))
|
||||
{
|
||||
mLastWeight = mCurWeight+.001f;
|
||||
}
|
||||
|
||||
@@ -1293,7 +1293,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
||||
{
|
||||
if (!force_render && !hasMorph())
|
||||
{
|
||||
LL_DEBUGS() << "skipping renderMorphMasks for " << getUUID() << LL_ENDL;
|
||||
LL_DEBUGS("Morph") << "skipping renderMorphMasks for " << getUUID() << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
@@ -1325,7 +1325,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
||||
success &= param->render( x, y, width, height );
|
||||
if (!success && !force_render)
|
||||
{
|
||||
LL_DEBUGS() << "Failed to render param " << param->getID() << " ; skipping morph mask." << LL_ENDL;
|
||||
LL_DEBUGS("Morph") << "Failed to render param " << param->getID() << " ; skipping morph mask." << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1365,7 +1365,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS() << "Skipping rendering of " << getInfo()->mStaticImageFileName
|
||||
LL_WARNS("Morph") << "Skipping rendering of " << getInfo()->mStaticImageFileName
|
||||
<< "; expected 1 or 4 components." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
@@ -1404,8 +1404,8 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
||||
// We can get bad morph masks during login, on minimize, and occasional gl errors.
|
||||
// We should only be doing this when we believe something has changed with respect to the user's appearance.
|
||||
{
|
||||
LL_DEBUGS("Avatar") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL;
|
||||
// clear out a slot if we have filled our cache
|
||||
LL_DEBUGS("Morph") << "gl alpha cache of morph mask not found, doing readback: " << getName() << LL_ENDL;
|
||||
// clear out a slot if we have filled our cache
|
||||
S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1;
|
||||
while ((S32)mAlphaCache.size() >= max_cache_entries)
|
||||
{
|
||||
@@ -1444,13 +1444,20 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
|
||||
}
|
||||
|
||||
glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp);
|
||||
|
||||
U8* alpha_cursor = alpha_data;
|
||||
U8* pixel = temp;
|
||||
for (int i = 0; i < pixels; i++)
|
||||
GLenum error = glGetError();
|
||||
if (error != GL_NO_ERROR)
|
||||
{
|
||||
*alpha_cursor++ = pixel[3];
|
||||
pixel += 4;
|
||||
LL_INFOS("Morph") << "GL Error while reading back morph texture. Error code: " << error << LL_ENDL;
|
||||
}
|
||||
else
|
||||
{
|
||||
U8* alpha_cursor = alpha_data;
|
||||
U8* pixel = temp;
|
||||
for (int i = 0; i < pixels; i++)
|
||||
{
|
||||
*alpha_cursor++ = pixel[3];
|
||||
pixel += 4;
|
||||
}
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->disable();
|
||||
|
||||
@@ -645,9 +645,10 @@ void LLWearable::addVisualParam(LLVisualParam *param)
|
||||
|
||||
void LLWearable::setVisualParamWeight(S32 param_index, F32 value)
|
||||
{
|
||||
if( is_in_map(mVisualParamIndexMap, param_index ) )
|
||||
visual_param_index_map_t::iterator found = mVisualParamIndexMap.find(param_index);
|
||||
if(found != mVisualParamIndexMap.end())
|
||||
{
|
||||
LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
|
||||
LLVisualParam *wearable_param = found->second;
|
||||
wearable_param->setWeight(value);
|
||||
}
|
||||
else
|
||||
@@ -658,10 +659,10 @@ void LLWearable::setVisualParamWeight(S32 param_index, F32 value)
|
||||
|
||||
F32 LLWearable::getVisualParamWeight(S32 param_index) const
|
||||
{
|
||||
if( is_in_map(mVisualParamIndexMap, param_index ) )
|
||||
visual_param_index_map_t::const_iterator found = mVisualParamIndexMap.find(param_index);
|
||||
if(found != mVisualParamIndexMap.end())
|
||||
{
|
||||
const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
|
||||
return wearable_param->getWeight();
|
||||
return found->second->getWeight();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -726,7 +727,7 @@ void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
|
||||
if (!avatarp) return;
|
||||
|
||||
// Pull params
|
||||
for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
|
||||
for( const LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
|
||||
{
|
||||
// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
|
||||
// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
|
||||
|
||||
@@ -79,7 +79,7 @@ bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title)
|
||||
ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
|
||||
|
||||
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &major);
|
||||
alcGetIntegerv(device, ALC_MAJOR_VERSION, 1, &minor);
|
||||
alcGetIntegerv(device, ALC_MINOR_VERSION, 1, &minor);
|
||||
LL_INFOS() << "ALC version: " << major << "." << minor << LL_ENDL;
|
||||
|
||||
LL_INFOS() << "ALC default device: "
|
||||
@@ -190,6 +190,8 @@ LLAudioChannelOpenAL::~LLAudioChannelOpenAL()
|
||||
void LLAudioChannelOpenAL::cleanup()
|
||||
{
|
||||
alSourceStop(mALSource);
|
||||
alSourcei(mALSource, AL_BUFFER, AL_NONE);
|
||||
|
||||
mCurrentBufferp = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,38 +34,6 @@
|
||||
#include "llmath.h"
|
||||
#include "llapr.h"
|
||||
|
||||
//#if LL_DARWIN
|
||||
// MBW -- XXX -- Getting rid of SecondLifeVorbis for now
|
||||
#if 0
|
||||
#include "VorbisFramework.h"
|
||||
|
||||
#define vorbis_analysis mac_vorbis_analysis
|
||||
#define vorbis_analysis_headerout mac_vorbis_analysis_headerout
|
||||
#define vorbis_analysis_init mac_vorbis_analysis_init
|
||||
#define vorbis_encode_ctl mac_vorbis_encode_ctl
|
||||
#define vorbis_encode_setup_init mac_vorbis_encode_setup_init
|
||||
#define vorbis_encode_setup_managed mac_vorbis_encode_setup_managed
|
||||
|
||||
#define vorbis_info_init mac_vorbis_info_init
|
||||
#define vorbis_info_clear mac_vorbis_info_clear
|
||||
#define vorbis_comment_init mac_vorbis_comment_init
|
||||
#define vorbis_comment_clear mac_vorbis_comment_clear
|
||||
#define vorbis_block_init mac_vorbis_block_init
|
||||
#define vorbis_block_clear mac_vorbis_block_clear
|
||||
#define vorbis_dsp_clear mac_vorbis_dsp_clear
|
||||
#define vorbis_analysis_buffer mac_vorbis_analysis_buffer
|
||||
#define vorbis_analysis_wrote mac_vorbis_analysis_wrote
|
||||
#define vorbis_analysis_blockout mac_vorbis_analysis_blockout
|
||||
|
||||
#define ogg_stream_packetin mac_ogg_stream_packetin
|
||||
#define ogg_stream_init mac_ogg_stream_init
|
||||
#define ogg_stream_flush mac_ogg_stream_flush
|
||||
#define ogg_stream_pageout mac_ogg_stream_pageout
|
||||
#define ogg_page_eos mac_ogg_page_eos
|
||||
#define ogg_stream_clear mac_ogg_stream_clear
|
||||
|
||||
#endif
|
||||
|
||||
S32 check_for_invalid_wav_formats(const std::string& in_fname, std::string& error_msg)
|
||||
{
|
||||
U16 num_channels = 0;
|
||||
|
||||
@@ -131,7 +131,7 @@ LLQuaternion::Order bvhStringToOrder( char *str )
|
||||
// LLBVHLoader()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map )
|
||||
LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map )
|
||||
{
|
||||
reset();
|
||||
errorLine = 0;
|
||||
@@ -156,9 +156,9 @@ LLBVHLoader::LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &error
|
||||
}
|
||||
|
||||
// Recognize all names we've been told are legal.
|
||||
for (std::map<std::string, std::string>::value_type& alias_pair : joint_alias_map)
|
||||
for (const auto& [alias, joint] : joint_alias_map)
|
||||
{
|
||||
makeTranslation( alias_pair.first , alias_pair.second );
|
||||
makeTranslation(alias, joint);
|
||||
}
|
||||
|
||||
char error_text[128]; /* Flawfinder: ignore */
|
||||
|
||||
@@ -227,7 +227,7 @@ class LLBVHLoader
|
||||
friend class LLKeyframeMotion;
|
||||
public:
|
||||
// Constructor
|
||||
LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string>& joint_alias_map );
|
||||
LLBVHLoader(const char* buffer, ELoadStatus &loadStatus, S32 &errorLine, std::map<std::string, std::string, std::less<>>& joint_alias_map );
|
||||
~LLBVHLoader();
|
||||
|
||||
/*
|
||||
|
||||
@@ -77,12 +77,11 @@ LLCharacter::~LLCharacter()
|
||||
//-----------------------------------------------------------------------------
|
||||
// getJoint()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLJoint *LLCharacter::getJoint( const std::string &name )
|
||||
LLJoint* LLCharacter::getJoint(std::string_view name)
|
||||
{
|
||||
LLJoint* joint = NULL;
|
||||
LLJoint* joint = nullptr;
|
||||
|
||||
LLJoint *root = getRootJoint();
|
||||
if (root)
|
||||
if (LLJoint* root = getRootJoint())
|
||||
{
|
||||
joint = root->findJoint(name);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
// get the specified joint
|
||||
// default implementation does recursive search,
|
||||
// subclasses may optimize/cache results.
|
||||
virtual LLJoint *getJoint( const std::string &name );
|
||||
virtual LLJoint* getJoint(std::string_view name);
|
||||
|
||||
// get the position of the character
|
||||
virtual LLVector3 getCharacterPosition() = 0;
|
||||
@@ -119,6 +119,8 @@ public:
|
||||
|
||||
virtual void addDebugText( const std::string& text ) = 0;
|
||||
|
||||
virtual std::string getDebugName() const { return getID().asString(); }
|
||||
|
||||
virtual const LLUUID& getID() const = 0;
|
||||
//-------------------------------------------------------------------------
|
||||
// End Interface
|
||||
|
||||
@@ -242,21 +242,20 @@ LLJoint *LLJoint::getRoot()
|
||||
//-----------------------------------------------------------------------------
|
||||
// findJoint()
|
||||
//-----------------------------------------------------------------------------
|
||||
LLJoint *LLJoint::findJoint( const std::string &name )
|
||||
LLJoint* LLJoint::findJoint(std::string_view name)
|
||||
{
|
||||
if (name == getName())
|
||||
return this;
|
||||
|
||||
for (LLJoint* joint : mChildren)
|
||||
{
|
||||
LLJoint *found = joint->findJoint(name);
|
||||
if (found)
|
||||
if (LLJoint* found = joint->findJoint(name))
|
||||
{
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ public:
|
||||
LLJoint *getRoot();
|
||||
|
||||
// search for child joints by name
|
||||
LLJoint *findJoint( const std::string &name );
|
||||
LLJoint* findJoint(std::string_view name);
|
||||
|
||||
// add/remove children
|
||||
void addChild( LLJoint *joint );
|
||||
|
||||
@@ -11,7 +11,7 @@ include(LLSharedLibs)
|
||||
include(Copy3rdPartyLibs)
|
||||
include(ZLIBNG)
|
||||
include(Tracy)
|
||||
|
||||
include(SSE2NEON)
|
||||
|
||||
set(llcommon_SOURCE_FILES
|
||||
apply.cpp
|
||||
@@ -277,6 +277,7 @@ target_link_libraries(
|
||||
ll::boost
|
||||
ll::oslibraries
|
||||
ll::tracy
|
||||
ll::sse2neon
|
||||
)
|
||||
|
||||
target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
+28
-19
@@ -12,7 +12,10 @@
|
||||
#if ! defined(LL_FSYSPATH_H)
|
||||
#define LL_FSYSPATH_H
|
||||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
// While std::filesystem::path can be directly constructed from std::string on
|
||||
// both Posix and Windows, that's not what we want on Windows. Per
|
||||
@@ -33,37 +36,43 @@
|
||||
// char"), the "native narrow encoding" isn't UTF-8, so file paths containing
|
||||
// non-ASCII characters get mangled.
|
||||
//
|
||||
// Once we're building with C++20, we could pass a UTF-8 std::string through a
|
||||
// vector<char8_t> to engage std::filesystem::path's own UTF-8 conversion. But
|
||||
// sigh, as of 2024-04-03 we're not yet there.
|
||||
//
|
||||
// Anyway, encapsulating the important UTF-8 conversions in our own subclass
|
||||
// allows us to migrate forward to C++20 conventions without changing
|
||||
// referencing code.
|
||||
// Encapsulating the important UTF-8 conversions in our own subclass allows us
|
||||
// to migrate forward to C++20 conventions without changing referencing code.
|
||||
|
||||
class fsyspath: public std::filesystem::path
|
||||
{
|
||||
using super = std::filesystem::path;
|
||||
|
||||
// In C++20 (__cpp_lib_char8_t), std::filesystem::u8path() is deprecated.
|
||||
// std::filesystem::path(iter, iter) performs UTF-8 conversions when the
|
||||
// value_type of the iterators is char8_t. While we could copy into a
|
||||
// temporary std::u8string and from there into std::filesystem::path, to
|
||||
// minimize string copying we'll define a transform_iterator that accepts
|
||||
// a std::string_view::iterator and dereferences to char8_t.
|
||||
struct u8ify
|
||||
{
|
||||
char8_t operator()(char c) const { return char8_t(c); }
|
||||
};
|
||||
using u8iter = boost::transform_iterator<u8ify, std::string_view::iterator>;
|
||||
|
||||
public:
|
||||
// default
|
||||
fsyspath() {}
|
||||
// construct from UTF-8 encoded std::string
|
||||
fsyspath(const std::string& path): super(std::filesystem::u8path(path)) {}
|
||||
// construct from UTF-8 encoded const char*
|
||||
fsyspath(const char* path): super(std::filesystem::u8path(path)) {}
|
||||
// construct from UTF-8 encoded string
|
||||
fsyspath(const std::string& path): fsyspath(std::string_view(path)) {}
|
||||
fsyspath(const char* path): fsyspath(std::string_view(path)) {}
|
||||
fsyspath(std::string_view path):
|
||||
super(u8iter(path.begin(), u8ify()), u8iter(path.end(), u8ify()))
|
||||
{}
|
||||
// construct from existing path
|
||||
fsyspath(const super& path): super(path) {}
|
||||
|
||||
fsyspath& operator=(const super& p) { super::operator=(p); return *this; }
|
||||
fsyspath& operator=(const std::string& p)
|
||||
fsyspath& operator=(const super& p) { super::operator=(p); return *this; }
|
||||
fsyspath& operator=(const std::string& p) { return (*this) = std::string_view(p); }
|
||||
fsyspath& operator=(const char* p) { return (*this) = std::string_view(p); }
|
||||
fsyspath& operator=(std::string_view p)
|
||||
{
|
||||
super::operator=(std::filesystem::u8path(p));
|
||||
return *this;
|
||||
}
|
||||
fsyspath& operator=(const char* p)
|
||||
{
|
||||
super::operator=(std::filesystem::u8path(p));
|
||||
assign(u8iter(p.begin(), u8ify()), u8iter(p.end(), u8ify()));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
+194
-192
@@ -31,15 +31,15 @@
|
||||
|
||||
class LLUUID;
|
||||
|
||||
static const F32 REGION_WIDTH_METERS = 256.f;
|
||||
static const S32 REGION_WIDTH_UNITS = 256;
|
||||
static const U32 REGION_WIDTH_U32 = 256;
|
||||
static constexpr F32 REGION_WIDTH_METERS = 256.f;
|
||||
static constexpr S32 REGION_WIDTH_UNITS = 256;
|
||||
static constexpr U32 REGION_WIDTH_U32 = 256;
|
||||
|
||||
const F32 REGION_HEIGHT_METERS = 4096.f;
|
||||
constexpr F32 REGION_HEIGHT_METERS = 4096.f;
|
||||
|
||||
const F32 DEFAULT_AGENT_DEPTH = 0.45f;
|
||||
const F32 DEFAULT_AGENT_WIDTH = 0.60f;
|
||||
const F32 DEFAULT_AGENT_HEIGHT = 1.9f;
|
||||
constexpr F32 DEFAULT_AGENT_DEPTH = 0.45f;
|
||||
constexpr F32 DEFAULT_AGENT_WIDTH = 0.60f;
|
||||
constexpr F32 DEFAULT_AGENT_HEIGHT = 1.9f;
|
||||
|
||||
enum ETerrainBrushType
|
||||
{
|
||||
@@ -67,112 +67,112 @@ enum EMouseClickType{
|
||||
|
||||
// keys
|
||||
// Bit masks for various keyboard modifier keys.
|
||||
const MASK MASK_NONE = 0x0000;
|
||||
const MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs
|
||||
const MASK MASK_ALT = 0x0002;
|
||||
const MASK MASK_SHIFT = 0x0004;
|
||||
const MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys
|
||||
const MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows
|
||||
const MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL;
|
||||
constexpr MASK MASK_NONE = 0x0000;
|
||||
constexpr MASK MASK_CONTROL = 0x0001; // Mapped to cmd on Macs
|
||||
constexpr MASK MASK_ALT = 0x0002;
|
||||
constexpr MASK MASK_SHIFT = 0x0004;
|
||||
constexpr MASK MASK_NORMALKEYS = 0x0007; // A real mask - only get the bits for normal modifier keys
|
||||
constexpr MASK MASK_MAC_CONTROL = 0x0008; // Un-mapped Ctrl key on Macs, not used on Windows
|
||||
constexpr MASK MASK_MODIFIERS = MASK_CONTROL|MASK_ALT|MASK_SHIFT|MASK_MAC_CONTROL;
|
||||
|
||||
// Special keys go into >128
|
||||
const KEY KEY_SPECIAL = 0x80; // special keys start here
|
||||
const KEY KEY_RETURN = 0x81;
|
||||
const KEY KEY_LEFT = 0x82;
|
||||
const KEY KEY_RIGHT = 0x83;
|
||||
const KEY KEY_UP = 0x84;
|
||||
const KEY KEY_DOWN = 0x85;
|
||||
const KEY KEY_ESCAPE = 0x86;
|
||||
const KEY KEY_BACKSPACE =0x87;
|
||||
const KEY KEY_DELETE = 0x88;
|
||||
const KEY KEY_SHIFT = 0x89;
|
||||
const KEY KEY_CONTROL = 0x8A;
|
||||
const KEY KEY_ALT = 0x8B;
|
||||
const KEY KEY_HOME = 0x8C;
|
||||
const KEY KEY_END = 0x8D;
|
||||
const KEY KEY_PAGE_UP = 0x8E;
|
||||
const KEY KEY_PAGE_DOWN = 0x8F;
|
||||
const KEY KEY_HYPHEN = 0x90;
|
||||
const KEY KEY_EQUALS = 0x91;
|
||||
const KEY KEY_INSERT = 0x92;
|
||||
const KEY KEY_CAPSLOCK = 0x93;
|
||||
const KEY KEY_TAB = 0x94;
|
||||
const KEY KEY_ADD = 0x95;
|
||||
const KEY KEY_SUBTRACT =0x96;
|
||||
const KEY KEY_MULTIPLY =0x97;
|
||||
const KEY KEY_DIVIDE = 0x98;
|
||||
const KEY KEY_F1 = 0xA1;
|
||||
const KEY KEY_F2 = 0xA2;
|
||||
const KEY KEY_F3 = 0xA3;
|
||||
const KEY KEY_F4 = 0xA4;
|
||||
const KEY KEY_F5 = 0xA5;
|
||||
const KEY KEY_F6 = 0xA6;
|
||||
const KEY KEY_F7 = 0xA7;
|
||||
const KEY KEY_F8 = 0xA8;
|
||||
const KEY KEY_F9 = 0xA9;
|
||||
const KEY KEY_F10 = 0xAA;
|
||||
const KEY KEY_F11 = 0xAB;
|
||||
const KEY KEY_F12 = 0xAC;
|
||||
constexpr KEY KEY_SPECIAL = 0x80; // special keys start here
|
||||
constexpr KEY KEY_RETURN = 0x81;
|
||||
constexpr KEY KEY_LEFT = 0x82;
|
||||
constexpr KEY KEY_RIGHT = 0x83;
|
||||
constexpr KEY KEY_UP = 0x84;
|
||||
constexpr KEY KEY_DOWN = 0x85;
|
||||
constexpr KEY KEY_ESCAPE = 0x86;
|
||||
constexpr KEY KEY_BACKSPACE =0x87;
|
||||
constexpr KEY KEY_DELETE = 0x88;
|
||||
constexpr KEY KEY_SHIFT = 0x89;
|
||||
constexpr KEY KEY_CONTROL = 0x8A;
|
||||
constexpr KEY KEY_ALT = 0x8B;
|
||||
constexpr KEY KEY_HOME = 0x8C;
|
||||
constexpr KEY KEY_END = 0x8D;
|
||||
constexpr KEY KEY_PAGE_UP = 0x8E;
|
||||
constexpr KEY KEY_PAGE_DOWN = 0x8F;
|
||||
constexpr KEY KEY_HYPHEN = 0x90;
|
||||
constexpr KEY KEY_EQUALS = 0x91;
|
||||
constexpr KEY KEY_INSERT = 0x92;
|
||||
constexpr KEY KEY_CAPSLOCK = 0x93;
|
||||
constexpr KEY KEY_TAB = 0x94;
|
||||
constexpr KEY KEY_ADD = 0x95;
|
||||
constexpr KEY KEY_SUBTRACT =0x96;
|
||||
constexpr KEY KEY_MULTIPLY =0x97;
|
||||
constexpr KEY KEY_DIVIDE = 0x98;
|
||||
constexpr KEY KEY_F1 = 0xA1;
|
||||
constexpr KEY KEY_F2 = 0xA2;
|
||||
constexpr KEY KEY_F3 = 0xA3;
|
||||
constexpr KEY KEY_F4 = 0xA4;
|
||||
constexpr KEY KEY_F5 = 0xA5;
|
||||
constexpr KEY KEY_F6 = 0xA6;
|
||||
constexpr KEY KEY_F7 = 0xA7;
|
||||
constexpr KEY KEY_F8 = 0xA8;
|
||||
constexpr KEY KEY_F9 = 0xA9;
|
||||
constexpr KEY KEY_F10 = 0xAA;
|
||||
constexpr KEY KEY_F11 = 0xAB;
|
||||
constexpr KEY KEY_F12 = 0xAC;
|
||||
|
||||
const KEY KEY_PAD_UP = 0xC0;
|
||||
const KEY KEY_PAD_DOWN = 0xC1;
|
||||
const KEY KEY_PAD_LEFT = 0xC2;
|
||||
const KEY KEY_PAD_RIGHT = 0xC3;
|
||||
const KEY KEY_PAD_HOME = 0xC4;
|
||||
const KEY KEY_PAD_END = 0xC5;
|
||||
const KEY KEY_PAD_PGUP = 0xC6;
|
||||
const KEY KEY_PAD_PGDN = 0xC7;
|
||||
const KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle
|
||||
const KEY KEY_PAD_INS = 0xC9;
|
||||
const KEY KEY_PAD_DEL = 0xCA;
|
||||
const KEY KEY_PAD_RETURN = 0xCB;
|
||||
const KEY KEY_PAD_ADD = 0xCC; // not used
|
||||
const KEY KEY_PAD_SUBTRACT = 0xCD; // not used
|
||||
const KEY KEY_PAD_MULTIPLY = 0xCE; // not used
|
||||
const KEY KEY_PAD_DIVIDE = 0xCF; // not used
|
||||
constexpr KEY KEY_PAD_UP = 0xC0;
|
||||
constexpr KEY KEY_PAD_DOWN = 0xC1;
|
||||
constexpr KEY KEY_PAD_LEFT = 0xC2;
|
||||
constexpr KEY KEY_PAD_RIGHT = 0xC3;
|
||||
constexpr KEY KEY_PAD_HOME = 0xC4;
|
||||
constexpr KEY KEY_PAD_END = 0xC5;
|
||||
constexpr KEY KEY_PAD_PGUP = 0xC6;
|
||||
constexpr KEY KEY_PAD_PGDN = 0xC7;
|
||||
constexpr KEY KEY_PAD_CENTER = 0xC8; // the 5 in the middle
|
||||
constexpr KEY KEY_PAD_INS = 0xC9;
|
||||
constexpr KEY KEY_PAD_DEL = 0xCA;
|
||||
constexpr KEY KEY_PAD_RETURN = 0xCB;
|
||||
constexpr KEY KEY_PAD_ADD = 0xCC; // not used
|
||||
constexpr KEY KEY_PAD_SUBTRACT = 0xCD; // not used
|
||||
constexpr KEY KEY_PAD_MULTIPLY = 0xCE; // not used
|
||||
constexpr KEY KEY_PAD_DIVIDE = 0xCF; // not used
|
||||
|
||||
const KEY KEY_BUTTON0 = 0xD0;
|
||||
const KEY KEY_BUTTON1 = 0xD1;
|
||||
const KEY KEY_BUTTON2 = 0xD2;
|
||||
const KEY KEY_BUTTON3 = 0xD3;
|
||||
const KEY KEY_BUTTON4 = 0xD4;
|
||||
const KEY KEY_BUTTON5 = 0xD5;
|
||||
const KEY KEY_BUTTON6 = 0xD6;
|
||||
const KEY KEY_BUTTON7 = 0xD7;
|
||||
const KEY KEY_BUTTON8 = 0xD8;
|
||||
const KEY KEY_BUTTON9 = 0xD9;
|
||||
const KEY KEY_BUTTON10 = 0xDA;
|
||||
const KEY KEY_BUTTON11 = 0xDB;
|
||||
const KEY KEY_BUTTON12 = 0xDC;
|
||||
const KEY KEY_BUTTON13 = 0xDD;
|
||||
const KEY KEY_BUTTON14 = 0xDE;
|
||||
const KEY KEY_BUTTON15 = 0xDF;
|
||||
constexpr KEY KEY_BUTTON0 = 0xD0;
|
||||
constexpr KEY KEY_BUTTON1 = 0xD1;
|
||||
constexpr KEY KEY_BUTTON2 = 0xD2;
|
||||
constexpr KEY KEY_BUTTON3 = 0xD3;
|
||||
constexpr KEY KEY_BUTTON4 = 0xD4;
|
||||
constexpr KEY KEY_BUTTON5 = 0xD5;
|
||||
constexpr KEY KEY_BUTTON6 = 0xD6;
|
||||
constexpr KEY KEY_BUTTON7 = 0xD7;
|
||||
constexpr KEY KEY_BUTTON8 = 0xD8;
|
||||
constexpr KEY KEY_BUTTON9 = 0xD9;
|
||||
constexpr KEY KEY_BUTTON10 = 0xDA;
|
||||
constexpr KEY KEY_BUTTON11 = 0xDB;
|
||||
constexpr KEY KEY_BUTTON12 = 0xDC;
|
||||
constexpr KEY KEY_BUTTON13 = 0xDD;
|
||||
constexpr KEY KEY_BUTTON14 = 0xDE;
|
||||
constexpr KEY KEY_BUTTON15 = 0xDF;
|
||||
|
||||
const KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only.
|
||||
constexpr KEY KEY_NONE = 0xFF; // not sent from keyboard. For internal use only.
|
||||
|
||||
const S32 KEY_COUNT = 256;
|
||||
constexpr S32 KEY_COUNT = 256;
|
||||
|
||||
|
||||
const F32 DEFAULT_WATER_HEIGHT = 20.0f;
|
||||
constexpr F32 DEFAULT_WATER_HEIGHT = 20.0f;
|
||||
|
||||
// Maturity ratings for simulators
|
||||
const U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG
|
||||
const U8 SIM_ACCESS_PG = 13;
|
||||
const U8 SIM_ACCESS_MATURE = 21;
|
||||
const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
|
||||
const U8 SIM_ACCESS_DOWN = 254;
|
||||
const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
|
||||
constexpr U8 SIM_ACCESS_MIN = 0; // Treated as 'unknown', usually ends up being SIM_ACCESS_PG
|
||||
constexpr U8 SIM_ACCESS_PG = 13;
|
||||
constexpr U8 SIM_ACCESS_MATURE = 21;
|
||||
constexpr U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
|
||||
constexpr U8 SIM_ACCESS_DOWN = 254;
|
||||
constexpr U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
|
||||
|
||||
// attachment constants
|
||||
const U8 ATTACHMENT_ADD = 0x80;
|
||||
constexpr U8 ATTACHMENT_ADD = 0x80;
|
||||
|
||||
// god levels
|
||||
const U8 GOD_MAINTENANCE = 250;
|
||||
const U8 GOD_FULL = 200;
|
||||
const U8 GOD_LIAISON = 150;
|
||||
const U8 GOD_CUSTOMER_SERVICE = 100;
|
||||
const U8 GOD_LIKE = 1;
|
||||
const U8 GOD_NOT = 0;
|
||||
constexpr U8 GOD_MAINTENANCE = 250;
|
||||
constexpr U8 GOD_FULL = 200;
|
||||
constexpr U8 GOD_LIAISON = 150;
|
||||
constexpr U8 GOD_CUSTOMER_SERVICE = 100;
|
||||
constexpr U8 GOD_LIKE = 1;
|
||||
constexpr U8 GOD_NOT = 0;
|
||||
|
||||
// "agent id" for things that should be done to ALL agents
|
||||
LL_COMMON_API extern const LLUUID LL_UUID_ALL_AGENTS;
|
||||
@@ -239,121 +239,123 @@ LL_COMMON_API extern const LLUUID BLANK_OBJECT_NORMAL;
|
||||
LL_COMMON_API extern const LLUUID BLANK_MATERIAL_ASSET_ID;
|
||||
|
||||
// radius within which a chat message is fully audible
|
||||
const F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
constexpr F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
|
||||
// media commands
|
||||
const U32 PARCEL_MEDIA_COMMAND_STOP = 0;
|
||||
const U32 PARCEL_MEDIA_COMMAND_PAUSE = 1;
|
||||
const U32 PARCEL_MEDIA_COMMAND_PLAY = 2;
|
||||
const U32 PARCEL_MEDIA_COMMAND_LOOP = 3;
|
||||
const U32 PARCEL_MEDIA_COMMAND_TEXTURE = 4;
|
||||
const U32 PARCEL_MEDIA_COMMAND_URL = 5;
|
||||
const U32 PARCEL_MEDIA_COMMAND_TIME = 6;
|
||||
const U32 PARCEL_MEDIA_COMMAND_AGENT = 7;
|
||||
const U32 PARCEL_MEDIA_COMMAND_UNLOAD = 8;
|
||||
const U32 PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9;
|
||||
const U32 PARCEL_MEDIA_COMMAND_TYPE = 10;
|
||||
const U32 PARCEL_MEDIA_COMMAND_SIZE = 11;
|
||||
const U32 PARCEL_MEDIA_COMMAND_DESC = 12;
|
||||
const U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_STOP = 0;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_PAUSE = 1;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_PLAY = 2;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_LOOP = 3;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_TEXTURE = 4;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_URL = 5;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_TIME = 6;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_AGENT = 7;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_UNLOAD = 8;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_AUTO_ALIGN = 9;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_TYPE = 10;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_SIZE = 11;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_DESC = 12;
|
||||
constexpr U32 PARCEL_MEDIA_COMMAND_LOOP_SET = 13;
|
||||
|
||||
const S32 CHAT_CHANNEL_DEBUG = S32_MAX;
|
||||
|
||||
// agent constants
|
||||
const U32 CONTROL_AT_POS_INDEX = 0;
|
||||
const U32 CONTROL_AT_NEG_INDEX = 1;
|
||||
const U32 CONTROL_LEFT_POS_INDEX = 2;
|
||||
const U32 CONTROL_LEFT_NEG_INDEX = 3;
|
||||
const U32 CONTROL_UP_POS_INDEX = 4;
|
||||
const U32 CONTROL_UP_NEG_INDEX = 5;
|
||||
const U32 CONTROL_PITCH_POS_INDEX = 6;
|
||||
const U32 CONTROL_PITCH_NEG_INDEX = 7;
|
||||
const U32 CONTROL_YAW_POS_INDEX = 8;
|
||||
const U32 CONTROL_YAW_NEG_INDEX = 9;
|
||||
const U32 CONTROL_FAST_AT_INDEX = 10;
|
||||
const U32 CONTROL_FAST_LEFT_INDEX = 11;
|
||||
const U32 CONTROL_FAST_UP_INDEX = 12;
|
||||
const U32 CONTROL_FLY_INDEX = 13;
|
||||
const U32 CONTROL_STOP_INDEX = 14;
|
||||
const U32 CONTROL_FINISH_ANIM_INDEX = 15;
|
||||
const U32 CONTROL_STAND_UP_INDEX = 16;
|
||||
const U32 CONTROL_SIT_ON_GROUND_INDEX = 17;
|
||||
const U32 CONTROL_MOUSELOOK_INDEX = 18;
|
||||
const U32 CONTROL_NUDGE_AT_POS_INDEX = 19;
|
||||
const U32 CONTROL_NUDGE_AT_NEG_INDEX = 20;
|
||||
const U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21;
|
||||
const U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22;
|
||||
const U32 CONTROL_NUDGE_UP_POS_INDEX = 23;
|
||||
const U32 CONTROL_NUDGE_UP_NEG_INDEX = 24;
|
||||
const U32 CONTROL_TURN_LEFT_INDEX = 25;
|
||||
const U32 CONTROL_TURN_RIGHT_INDEX = 26;
|
||||
const U32 CONTROL_AWAY_INDEX = 27;
|
||||
const U32 CONTROL_LBUTTON_DOWN_INDEX = 28;
|
||||
const U32 CONTROL_LBUTTON_UP_INDEX = 29;
|
||||
const U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30;
|
||||
const U32 CONTROL_ML_LBUTTON_UP_INDEX = 31;
|
||||
const U32 TOTAL_CONTROLS = 32;
|
||||
constexpr U32 CONTROL_AT_POS_INDEX = 0;
|
||||
constexpr U32 CONTROL_AT_NEG_INDEX = 1;
|
||||
constexpr U32 CONTROL_LEFT_POS_INDEX = 2;
|
||||
constexpr U32 CONTROL_LEFT_NEG_INDEX = 3;
|
||||
constexpr U32 CONTROL_UP_POS_INDEX = 4;
|
||||
constexpr U32 CONTROL_UP_NEG_INDEX = 5;
|
||||
constexpr U32 CONTROL_PITCH_POS_INDEX = 6;
|
||||
constexpr U32 CONTROL_PITCH_NEG_INDEX = 7;
|
||||
constexpr U32 CONTROL_YAW_POS_INDEX = 8;
|
||||
constexpr U32 CONTROL_YAW_NEG_INDEX = 9;
|
||||
constexpr U32 CONTROL_FAST_AT_INDEX = 10;
|
||||
constexpr U32 CONTROL_FAST_LEFT_INDEX = 11;
|
||||
constexpr U32 CONTROL_FAST_UP_INDEX = 12;
|
||||
constexpr U32 CONTROL_FLY_INDEX = 13;
|
||||
constexpr U32 CONTROL_STOP_INDEX = 14;
|
||||
constexpr U32 CONTROL_FINISH_ANIM_INDEX = 15;
|
||||
constexpr U32 CONTROL_STAND_UP_INDEX = 16;
|
||||
constexpr U32 CONTROL_SIT_ON_GROUND_INDEX = 17;
|
||||
constexpr U32 CONTROL_MOUSELOOK_INDEX = 18;
|
||||
constexpr U32 CONTROL_NUDGE_AT_POS_INDEX = 19;
|
||||
constexpr U32 CONTROL_NUDGE_AT_NEG_INDEX = 20;
|
||||
constexpr U32 CONTROL_NUDGE_LEFT_POS_INDEX = 21;
|
||||
constexpr U32 CONTROL_NUDGE_LEFT_NEG_INDEX = 22;
|
||||
constexpr U32 CONTROL_NUDGE_UP_POS_INDEX = 23;
|
||||
constexpr U32 CONTROL_NUDGE_UP_NEG_INDEX = 24;
|
||||
constexpr U32 CONTROL_TURN_LEFT_INDEX = 25;
|
||||
constexpr U32 CONTROL_TURN_RIGHT_INDEX = 26;
|
||||
constexpr U32 CONTROL_AWAY_INDEX = 27;
|
||||
constexpr U32 CONTROL_LBUTTON_DOWN_INDEX = 28;
|
||||
constexpr U32 CONTROL_LBUTTON_UP_INDEX = 29;
|
||||
constexpr U32 CONTROL_ML_LBUTTON_DOWN_INDEX = 30;
|
||||
constexpr U32 CONTROL_ML_LBUTTON_UP_INDEX = 31;
|
||||
constexpr U32 TOTAL_CONTROLS = 32;
|
||||
|
||||
const U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001
|
||||
const U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002
|
||||
const U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004
|
||||
const U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008
|
||||
const U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010
|
||||
const U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020
|
||||
const U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040
|
||||
const U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080
|
||||
const U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100
|
||||
const U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200
|
||||
constexpr U32 AGENT_CONTROL_AT_POS = 0x1 << CONTROL_AT_POS_INDEX; // 0x00000001
|
||||
constexpr U32 AGENT_CONTROL_AT_NEG = 0x1 << CONTROL_AT_NEG_INDEX; // 0x00000002
|
||||
constexpr U32 AGENT_CONTROL_LEFT_POS = 0x1 << CONTROL_LEFT_POS_INDEX; // 0x00000004
|
||||
constexpr U32 AGENT_CONTROL_LEFT_NEG = 0x1 << CONTROL_LEFT_NEG_INDEX; // 0x00000008
|
||||
constexpr U32 AGENT_CONTROL_UP_POS = 0x1 << CONTROL_UP_POS_INDEX; // 0x00000010
|
||||
constexpr U32 AGENT_CONTROL_UP_NEG = 0x1 << CONTROL_UP_NEG_INDEX; // 0x00000020
|
||||
constexpr U32 AGENT_CONTROL_PITCH_POS = 0x1 << CONTROL_PITCH_POS_INDEX; // 0x00000040
|
||||
constexpr U32 AGENT_CONTROL_PITCH_NEG = 0x1 << CONTROL_PITCH_NEG_INDEX; // 0x00000080
|
||||
constexpr U32 AGENT_CONTROL_YAW_POS = 0x1 << CONTROL_YAW_POS_INDEX; // 0x00000100
|
||||
constexpr U32 AGENT_CONTROL_YAW_NEG = 0x1 << CONTROL_YAW_NEG_INDEX; // 0x00000200
|
||||
|
||||
const U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400
|
||||
const U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800
|
||||
const U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000
|
||||
constexpr U32 AGENT_CONTROL_FAST_AT = 0x1 << CONTROL_FAST_AT_INDEX; // 0x00000400
|
||||
constexpr U32 AGENT_CONTROL_FAST_LEFT = 0x1 << CONTROL_FAST_LEFT_INDEX; // 0x00000800
|
||||
constexpr U32 AGENT_CONTROL_FAST_UP = 0x1 << CONTROL_FAST_UP_INDEX; // 0x00001000
|
||||
|
||||
const U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000
|
||||
const U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000
|
||||
const U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000
|
||||
const U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000
|
||||
const U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000
|
||||
const U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000
|
||||
constexpr U32 AGENT_CONTROL_FLY = 0x1 << CONTROL_FLY_INDEX; // 0x00002000
|
||||
constexpr U32 AGENT_CONTROL_STOP = 0x1 << CONTROL_STOP_INDEX; // 0x00004000
|
||||
constexpr U32 AGENT_CONTROL_FINISH_ANIM = 0x1 << CONTROL_FINISH_ANIM_INDEX; // 0x00008000
|
||||
constexpr U32 AGENT_CONTROL_STAND_UP = 0x1 << CONTROL_STAND_UP_INDEX; // 0x00010000
|
||||
constexpr U32 AGENT_CONTROL_SIT_ON_GROUND = 0x1 << CONTROL_SIT_ON_GROUND_INDEX; // 0x00020000
|
||||
constexpr U32 AGENT_CONTROL_MOUSELOOK = 0x1 << CONTROL_MOUSELOOK_INDEX; // 0x00040000
|
||||
|
||||
const U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000
|
||||
const U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000
|
||||
const U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000
|
||||
const U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000
|
||||
const U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000
|
||||
const U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000
|
||||
const U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000
|
||||
const U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_AT_POS = 0x1 << CONTROL_NUDGE_AT_POS_INDEX; // 0x00080000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_AT_NEG = 0x1 << CONTROL_NUDGE_AT_NEG_INDEX; // 0x00100000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_LEFT_POS = 0x1 << CONTROL_NUDGE_LEFT_POS_INDEX; // 0x00200000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_LEFT_NEG = 0x1 << CONTROL_NUDGE_LEFT_NEG_INDEX; // 0x00400000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_UP_POS = 0x1 << CONTROL_NUDGE_UP_POS_INDEX; // 0x00800000
|
||||
constexpr U32 AGENT_CONTROL_NUDGE_UP_NEG = 0x1 << CONTROL_NUDGE_UP_NEG_INDEX; // 0x01000000
|
||||
constexpr U32 AGENT_CONTROL_TURN_LEFT = 0x1 << CONTROL_TURN_LEFT_INDEX; // 0x02000000
|
||||
constexpr U32 AGENT_CONTROL_TURN_RIGHT = 0x1 << CONTROL_TURN_RIGHT_INDEX; // 0x04000000
|
||||
|
||||
const U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000
|
||||
constexpr U32 AGENT_CONTROL_AWAY = 0x1 << CONTROL_AWAY_INDEX; // 0x08000000
|
||||
|
||||
const U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000
|
||||
const U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000
|
||||
const U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000
|
||||
const U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000
|
||||
constexpr U32 AGENT_CONTROL_LBUTTON_DOWN = 0x1 << CONTROL_LBUTTON_DOWN_INDEX; // 0x10000000
|
||||
constexpr U32 AGENT_CONTROL_LBUTTON_UP = 0x1 << CONTROL_LBUTTON_UP_INDEX; // 0x20000000
|
||||
constexpr U32 AGENT_CONTROL_ML_LBUTTON_DOWN = 0x1 << CONTROL_ML_LBUTTON_DOWN_INDEX; // 0x40000000
|
||||
constexpr U32 AGENT_CONTROL_ML_LBUTTON_UP = ((U32)0x1) << CONTROL_ML_LBUTTON_UP_INDEX; // 0x80000000
|
||||
|
||||
// move these up so that we can hide them in "State" for object updates
|
||||
// (for now)
|
||||
const U32 AGENT_ATTACH_OFFSET = 4;
|
||||
const U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET;
|
||||
constexpr U32 AGENT_ATTACH_OFFSET = 4;
|
||||
constexpr U32 AGENT_ATTACH_MASK = 0xf << AGENT_ATTACH_OFFSET;
|
||||
|
||||
// RN: this method swaps the upper and lower nibbles to maintain backward
|
||||
// compatibility with old objects that only used the upper nibble
|
||||
#define ATTACHMENT_ID_FROM_STATE(state) ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4)))
|
||||
|
||||
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!
|
||||
const U8 CLICK_ACTION_NONE = 0;
|
||||
const U8 CLICK_ACTION_TOUCH = 0;
|
||||
const U8 CLICK_ACTION_SIT = 1;
|
||||
const U8 CLICK_ACTION_BUY = 2;
|
||||
const U8 CLICK_ACTION_PAY = 3;
|
||||
const U8 CLICK_ACTION_OPEN = 4;
|
||||
const U8 CLICK_ACTION_PLAY = 5;
|
||||
const U8 CLICK_ACTION_OPEN_MEDIA = 6;
|
||||
const U8 CLICK_ACTION_ZOOM = 7;
|
||||
const U8 CLICK_ACTION_DISABLED = 8;
|
||||
const U8 CLICK_ACTION_IGNORE = 9;
|
||||
constexpr U8 CLICK_ACTION_NONE = 0;
|
||||
constexpr U8 CLICK_ACTION_TOUCH = 0;
|
||||
constexpr U8 CLICK_ACTION_SIT = 1;
|
||||
constexpr U8 CLICK_ACTION_BUY = 2;
|
||||
constexpr U8 CLICK_ACTION_PAY = 3;
|
||||
constexpr U8 CLICK_ACTION_OPEN = 4;
|
||||
constexpr U8 CLICK_ACTION_PLAY = 5;
|
||||
constexpr U8 CLICK_ACTION_OPEN_MEDIA = 6;
|
||||
constexpr U8 CLICK_ACTION_ZOOM = 7;
|
||||
constexpr U8 CLICK_ACTION_DISABLED = 8;
|
||||
constexpr U8 CLICK_ACTION_IGNORE = 9;
|
||||
// DO NOT CHANGE THE SEQUENCE OF THIS LIST!!
|
||||
|
||||
constexpr U32 BEACON_SHOW_MAP = 0x0001;
|
||||
constexpr U32 BEACON_FOCUS_MAP = 0x0002;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,12 +28,6 @@
|
||||
#define LL_LINDEN_COMMON_H
|
||||
|
||||
#include "llprofiler.h"
|
||||
#if TRACY_ENABLE && !defined(LL_PROFILER_ENABLE_TRACY_OPENGL) // hooks for memory profiling
|
||||
void *tracy_aligned_malloc(size_t size, size_t alignment);
|
||||
void tracy_aligned_free(void *memblock);
|
||||
#define _aligned_malloc(X, Y) tracy_aligned_malloc((X), (Y))
|
||||
#define _aligned_free(X) tracy_aligned_free((X))
|
||||
#endif
|
||||
|
||||
// *NOTE: Please keep includes here to a minimum!
|
||||
//
|
||||
|
||||
@@ -229,7 +229,7 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv)
|
||||
if(wargv[ii][1] == '-') ++offset;
|
||||
|
||||
#if LL_WINDOWS
|
||||
name.assign(utf16str_to_utf8str(&wargv[ii][offset]));
|
||||
name.assign(ll_convert_wide_to_string(&wargv[ii][offset]));
|
||||
#else
|
||||
name.assign(wstring_to_utf8str(&wargv[ii][offset]));
|
||||
#endif
|
||||
@@ -253,7 +253,7 @@ bool LLApp::parseCommandOptions(int argc, wchar_t** wargv)
|
||||
++ii;
|
||||
|
||||
#if LL_WINDOWS
|
||||
value.assign(utf16str_to_utf8str((wargv[ii])));
|
||||
value.assign(ll_convert_wide_to_string((wargv[ii])));
|
||||
#else
|
||||
value.assign(wstring_to_utf8str((wargv[ii])));
|
||||
#endif
|
||||
|
||||
@@ -282,7 +282,7 @@ public:
|
||||
LLRunner& getRunner() { return mRunner; }
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
virtual void reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { }
|
||||
virtual bool reportCrashToBugsplat(void* pExcepInfo /*EXCEPTION_POINTERS*/) { return false; }
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "llassettype.h"
|
||||
#include "lldictionary.h"
|
||||
#include "llmemory.h"
|
||||
#include "llsd.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -246,3 +247,19 @@ bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
LLSD LLAssetType::getTypeNames()
|
||||
{
|
||||
LLSD type_names;
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
for (S32 type = AT_TEXTURE; type < AT_COUNT; ++type)
|
||||
{
|
||||
const AssetEntry *entry = dict->lookup((LLAssetType::EType) type);
|
||||
// skip llassettype_bad_lookup
|
||||
if (entry)
|
||||
{
|
||||
type_names.append(entry->mTypeName);
|
||||
}
|
||||
}
|
||||
return type_names;
|
||||
}
|
||||
|
||||
@@ -165,6 +165,8 @@ public:
|
||||
static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
|
||||
static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
|
||||
|
||||
static LLSD getTypeNames();
|
||||
|
||||
static const std::string BADLOOKUP;
|
||||
|
||||
protected:
|
||||
|
||||
+37
-39
@@ -33,23 +33,12 @@
|
||||
#include "lltracethreadrecorder.h"
|
||||
#include "llcleanup.h"
|
||||
|
||||
thread_local bool gProfilerEnabled = false;
|
||||
|
||||
#if (TRACY_ENABLE)
|
||||
#if LL_PROFILER_CONFIGURATION >= LL_PROFILER_CONFIG_TRACY && TRACY_ENABLE
|
||||
// Override new/delete for tracy memory profiling
|
||||
|
||||
void* ll_tracy_new(size_t size)
|
||||
{
|
||||
void* ptr;
|
||||
if (gProfilerEnabled)
|
||||
{
|
||||
//LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
ptr = (malloc)(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = (malloc)(size);
|
||||
}
|
||||
void* ptr = (malloc)(size);
|
||||
if (!ptr)
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
@@ -58,6 +47,29 @@ void* ll_tracy_new(size_t size)
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* ll_tracy_aligned_new(size_t size, size_t alignment)
|
||||
{
|
||||
void* ptr = ll_aligned_malloc_fallback(size, alignment);
|
||||
if (!ptr)
|
||||
{
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
LL_PROFILE_ALLOC(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void ll_tracy_delete(void* ptr)
|
||||
{
|
||||
LL_PROFILE_FREE(ptr);
|
||||
(free)(ptr);
|
||||
}
|
||||
|
||||
void ll_tracy_aligned_delete(void* ptr)
|
||||
{
|
||||
LL_PROFILE_FREE(ptr);
|
||||
ll_aligned_free_fallback(ptr);
|
||||
}
|
||||
|
||||
void* operator new(size_t size)
|
||||
{
|
||||
return ll_tracy_new(size);
|
||||
@@ -68,18 +80,14 @@ void* operator new[](std::size_t count)
|
||||
return ll_tracy_new(count);
|
||||
}
|
||||
|
||||
void ll_tracy_delete(void* ptr)
|
||||
void* operator new(size_t size, std::align_val_t align)
|
||||
{
|
||||
LL_PROFILE_FREE(ptr);
|
||||
if (gProfilerEnabled)
|
||||
{
|
||||
//LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
(free)(ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
(free)(ptr);
|
||||
}
|
||||
return ll_tracy_aligned_new(size, (size_t)align);
|
||||
}
|
||||
|
||||
void* operator new[](std::size_t count, std::align_val_t align)
|
||||
{
|
||||
return ll_tracy_aligned_new(count, (size_t)align);
|
||||
}
|
||||
|
||||
void operator delete(void *ptr) noexcept
|
||||
@@ -92,27 +100,17 @@ void operator delete[](void* ptr) noexcept
|
||||
ll_tracy_delete(ptr);
|
||||
}
|
||||
|
||||
// C-style malloc/free can't be so easily overridden, so we define tracy versions and use
|
||||
// a pre-processor #define in linden_common.h to redirect to them. The parens around the native
|
||||
// functions below prevents recursive substitution by the preprocessor.
|
||||
//
|
||||
// Unaligned mallocs are rare in LL code but hooking them causes problems in 3p lib code (looking at
|
||||
// you, Havok), so we'll only capture the aligned version.
|
||||
|
||||
void *tracy_aligned_malloc(size_t size, size_t alignment)
|
||||
void operator delete(void *ptr, std::align_val_t align) noexcept
|
||||
{
|
||||
auto ptr = ll_aligned_malloc_fallback(size, alignment);
|
||||
if (ptr) LL_PROFILE_ALLOC(ptr, size);
|
||||
return ptr;
|
||||
ll_tracy_aligned_delete(ptr);
|
||||
}
|
||||
|
||||
void tracy_aligned_free(void *memblock)
|
||||
void operator delete[](void* ptr, std::align_val_t align) noexcept
|
||||
{
|
||||
LL_PROFILE_FREE(memblock);
|
||||
ll_aligned_free_fallback(memblock);
|
||||
ll_tracy_aligned_delete(ptr);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // TRACY_ENABLE && !LL_PROFILER_ENABLE_TRACY_OPENGL
|
||||
|
||||
//static
|
||||
bool LLCommon::sAprInitialized = false;
|
||||
|
||||
+41
-16
@@ -310,25 +310,54 @@ namespace
|
||||
|
||||
static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
|
||||
|
||||
U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
|
||||
U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS* exception_infop)
|
||||
{
|
||||
if (code == STATUS_MSC_EXCEPTION)
|
||||
if (LLApp::instance()->reportCrashToBugsplat((void*)exception_infop))
|
||||
{
|
||||
// Handled
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else if (code == STATUS_MSC_EXCEPTION)
|
||||
{
|
||||
// C++ exception, go on
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
else
|
||||
{
|
||||
// handle it
|
||||
// handle it, convert to std::exception
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void cpphandle(const LLCoros::callable_t& callable, const std::string& name)
|
||||
{
|
||||
// SE and C++ can not coexists, thus two handlers
|
||||
try
|
||||
{
|
||||
callable();
|
||||
}
|
||||
catch (const LLCoros::Stop& exc)
|
||||
{
|
||||
LL_INFOS("LLCoros") << "coroutine " << name << " terminating because "
|
||||
<< exc.what() << LL_ENDL;
|
||||
}
|
||||
catch (const LLContinueError&)
|
||||
{
|
||||
// Any uncaught exception derived from LLContinueError will be caught
|
||||
// here and logged. This coroutine will terminate but the rest of the
|
||||
// viewer will carry on.
|
||||
LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << name));
|
||||
}
|
||||
}
|
||||
|
||||
void sehandle(const LLCoros::callable_t& callable)
|
||||
void sehandle(const LLCoros::callable_t& callable, const std::string& name)
|
||||
{
|
||||
__try
|
||||
{
|
||||
callable();
|
||||
// handle stop and continue exceptions first
|
||||
cpphandle(callable, name);
|
||||
}
|
||||
__except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
|
||||
{
|
||||
@@ -340,16 +369,7 @@ void sehandle(const LLCoros::callable_t& callable)
|
||||
throw std::exception(integer_string);
|
||||
}
|
||||
}
|
||||
|
||||
#else // ! LL_WINDOWS
|
||||
|
||||
inline void sehandle(const LLCoros::callable_t& callable)
|
||||
{
|
||||
callable();
|
||||
}
|
||||
|
||||
#endif // ! LL_WINDOWS
|
||||
|
||||
#endif // LL_WINDOWS
|
||||
} // anonymous namespace
|
||||
|
||||
// Top-level wrapper around caller's coroutine callable.
|
||||
@@ -362,10 +382,14 @@ void LLCoros::toplevel(std::string name, callable_t callable)
|
||||
// set it as current
|
||||
mCurrent.reset(&corodata);
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
// can not use __try directly, toplevel requires unwinding, thus use of a wrapper
|
||||
sehandle(callable, name);
|
||||
#else // LL_WINDOWS
|
||||
// run the code the caller actually wants in the coroutine
|
||||
try
|
||||
{
|
||||
sehandle(callable);
|
||||
callable();
|
||||
}
|
||||
catch (const Stop& exc)
|
||||
{
|
||||
@@ -387,6 +411,7 @@ void LLCoros::toplevel(std::string name, callable_t callable)
|
||||
<< name << LL_ENDL;
|
||||
LLCoros::instance().saveException(name, std::current_exception());
|
||||
}
|
||||
#endif // else LL_WINDOWS
|
||||
}
|
||||
|
||||
//static
|
||||
|
||||
@@ -77,6 +77,15 @@ std::string LLDate::asRFC1123() const
|
||||
return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT"));
|
||||
}
|
||||
|
||||
std::string LLDate::toLocalDateString (std::string fmt) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
time_t locSeconds = (time_t) mSecondsSinceEpoch;
|
||||
struct tm * lt = localtime (&locSeconds);
|
||||
return toHTTPDateString(lt, fmt);
|
||||
}
|
||||
|
||||
std::string LLDate::toHTTPDateString (std::string fmt) const
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED;
|
||||
|
||||
@@ -77,6 +77,7 @@ public:
|
||||
std::string asRFC1123() const;
|
||||
void toStream(std::ostream&) const;
|
||||
bool split(S32 *year, S32 *month = NULL, S32 *day = NULL, S32 *hour = NULL, S32 *min = NULL, S32 *sec = NULL) const;
|
||||
std::string toLocalDateString(std::string fmt) const;
|
||||
std::string toHTTPDateString (std::string fmt) const;
|
||||
static std::string toHTTPDateString (tm * gmt, std::string fmt);
|
||||
/**
|
||||
|
||||
@@ -171,13 +171,13 @@ constexpr U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 +
|
||||
|
||||
// recursion tail
|
||||
template <typename T>
|
||||
inline auto llmax(T data)
|
||||
constexpr auto llmax(T data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
template <typename T0, typename T1, typename... Ts>
|
||||
inline auto llmax(T0 d0, T1 d1, Ts... rest)
|
||||
constexpr auto llmax(T0 d0, T1 d1, Ts... rest)
|
||||
{
|
||||
auto maxrest = llmax(d1, rest...);
|
||||
return (d0 > maxrest)? d0 : maxrest;
|
||||
@@ -185,20 +185,20 @@ inline auto llmax(T0 d0, T1 d1, Ts... rest)
|
||||
|
||||
// recursion tail
|
||||
template <typename T>
|
||||
inline auto llmin(T data)
|
||||
constexpr auto llmin(T data)
|
||||
{
|
||||
return data;
|
||||
}
|
||||
|
||||
template <typename T0, typename T1, typename... Ts>
|
||||
inline auto llmin(T0 d0, T1 d1, Ts... rest)
|
||||
constexpr auto llmin(T0 d0, T1 d1, Ts... rest)
|
||||
{
|
||||
auto minrest = llmin(d1, rest...);
|
||||
return (d0 < minrest) ? d0 : minrest;
|
||||
}
|
||||
|
||||
template <typename A, typename MIN, typename MAX>
|
||||
inline A llclamp(A a, MIN minval, MAX maxval)
|
||||
constexpr A llclamp(A a, MIN minval, MAX maxval)
|
||||
{
|
||||
A aminval{ static_cast<A>(minval) }, amaxval{ static_cast<A>(maxval) };
|
||||
if ( a < aminval )
|
||||
@@ -213,13 +213,13 @@ inline A llclamp(A a, MIN minval, MAX maxval)
|
||||
}
|
||||
|
||||
template <class LLDATATYPE>
|
||||
inline LLDATATYPE llclampf(LLDATATYPE a)
|
||||
constexpr LLDATATYPE llclampf(LLDATATYPE a)
|
||||
{
|
||||
return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(1));
|
||||
}
|
||||
|
||||
template <class LLDATATYPE>
|
||||
inline LLDATATYPE llclampb(LLDATATYPE a)
|
||||
constexpr LLDATATYPE llclampb(LLDATATYPE a)
|
||||
{
|
||||
return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(255));
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace {
|
||||
//
|
||||
if (s.size())
|
||||
{
|
||||
OutputDebugString(utf8str_to_utf16str(s).c_str());
|
||||
OutputDebugString(ll_convert<std::wstring>(s).c_str());
|
||||
OutputDebugString(TEXT("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ bool BlockTimer::sLog = false;
|
||||
std::string BlockTimer::sLogName = "";
|
||||
bool BlockTimer::sMetricLog = false;
|
||||
|
||||
#if LL_LINUX
|
||||
#if LL_LINUX || (LL_DARWIN && LL_ARM64)
|
||||
U64 BlockTimer::sClockResolution = 1000000000; // Nanosecond resolution
|
||||
#else
|
||||
U64 BlockTimer::sClockResolution = 1000000; // Microsecond resolution
|
||||
|
||||
@@ -30,9 +30,14 @@
|
||||
#include "llinstancetracker.h"
|
||||
#include "lltrace.h"
|
||||
#include "lltreeiterators.h"
|
||||
#include "llprocessor.h"
|
||||
|
||||
#if LL_X86 || LL_X86_64
|
||||
#if LL_WINDOWS
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <x86intrin.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define LL_FAST_TIMER_ON 1
|
||||
@@ -68,35 +73,10 @@ public:
|
||||
//
|
||||
// Windows implementation of CPU clock
|
||||
//
|
||||
|
||||
//
|
||||
// NOTE: put back in when we aren't using platform sdk anymore
|
||||
//
|
||||
// because MS has different signatures for these functions in winnt.h
|
||||
// need to rename them to avoid conflicts
|
||||
//#define _interlockedbittestandset _renamed_interlockedbittestandset
|
||||
//#define _interlockedbittestandreset _renamed_interlockedbittestandreset
|
||||
//#include <intrin.h>
|
||||
//#undef _interlockedbittestandset
|
||||
//#undef _interlockedbittestandreset
|
||||
|
||||
//inline U32 getCPUClockCount32()
|
||||
//{
|
||||
// U64 time_stamp = __rdtsc();
|
||||
// return (U32)(time_stamp >> 8);
|
||||
//}
|
||||
//
|
||||
//// return full timer value, *not* shifted by 8 bits
|
||||
//inline U64 getCPUClockCount64()
|
||||
//{
|
||||
// return __rdtsc();
|
||||
//}
|
||||
|
||||
|
||||
#if LL_FASTTIMER_USE_RDTSC
|
||||
|
||||
// shift off lower 8 bits for lower resolution but longer term timing
|
||||
// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
|
||||
#if LL_FASTTIMER_USE_RDTSC
|
||||
static U32 getCPUClockCount32()
|
||||
{
|
||||
unsigned __int64 val = __rdtsc();
|
||||
@@ -159,23 +139,37 @@ public:
|
||||
#endif // (LL_LINUX) && !(defined(__i386__) || defined(__amd64__))
|
||||
|
||||
|
||||
#if (LL_LINUX || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
|
||||
#if LL_DARWIN && LL_ARM64
|
||||
//
|
||||
// Mac+Linux FAST x86 implementation of CPU clock
|
||||
// Mac implementation of CPU clock - non-x86.
|
||||
//
|
||||
static U64 getCPUClockCount64()
|
||||
{
|
||||
return clock_gettime_nsec_np(CLOCK_UPTIME_RAW);
|
||||
}
|
||||
|
||||
static U32 getCPUClockCount32()
|
||||
{
|
||||
U32 low(0),high(0);
|
||||
__asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) );
|
||||
return (low>>8) | (high<<24);
|
||||
return (U32)(getCPUClockCount64() >> 8);
|
||||
}
|
||||
#endif // LL_DARWIN && LL_ARM64
|
||||
|
||||
#if (LL_LINUX || LL_DARWIN) && (LL_X86 || LL_X86_64)
|
||||
//
|
||||
// Mac+Linux FAST x86 implementation of CPU clock
|
||||
//
|
||||
#if LL_FASTTIMER_USE_RDTSC
|
||||
static U32 getCPUClockCount32()
|
||||
{
|
||||
U64 time_stamp = __rdtsc() >> 8U;
|
||||
return static_cast<U32>(time_stamp);
|
||||
}
|
||||
|
||||
static U64 getCPUClockCount64()
|
||||
{
|
||||
U32 low(0),high(0);
|
||||
__asm__ volatile (".byte 0x0f, 0x31": "=a"(low), "=d"(high) );
|
||||
return (U64)low | ( ((U64)high) << 32);
|
||||
return static_cast<U64>(__rdtsc());
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static BlockTimerStatHandle& getRootTimeBlock();
|
||||
|
||||
+268
-146
@@ -35,7 +35,6 @@
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include "llwin32headers.h"
|
||||
#include <stdlib.h> // Windows errno
|
||||
#include <vector>
|
||||
#else
|
||||
#include <errno.h>
|
||||
@@ -49,6 +48,86 @@ static std::string empty;
|
||||
// variants of strerror() to report errors.
|
||||
|
||||
#if LL_WINDOWS
|
||||
// For the situations where we directly call into Windows API functions we need to translate
|
||||
// the Windows error codes into errno values
|
||||
namespace
|
||||
{
|
||||
struct errentry
|
||||
{
|
||||
unsigned long oserr; // Windows OS error value
|
||||
int errcode; // System V error code
|
||||
};
|
||||
}
|
||||
|
||||
// translation table between Windows OS error value and System V errno code
|
||||
static errentry const errtable[]
|
||||
{
|
||||
{ ERROR_INVALID_FUNCTION, EINVAL }, // 1
|
||||
{ ERROR_FILE_NOT_FOUND, ENOENT }, // 2
|
||||
{ ERROR_PATH_NOT_FOUND, ENOENT }, // 3
|
||||
{ ERROR_TOO_MANY_OPEN_FILES, EMFILE }, // 4
|
||||
{ ERROR_ACCESS_DENIED, EACCES }, // 5
|
||||
{ ERROR_INVALID_HANDLE, EBADF }, // 6
|
||||
{ ERROR_ARENA_TRASHED, ENOMEM }, // 7
|
||||
{ ERROR_NOT_ENOUGH_MEMORY, ENOMEM }, // 8
|
||||
{ ERROR_INVALID_BLOCK, ENOMEM }, // 9
|
||||
{ ERROR_BAD_ENVIRONMENT, E2BIG }, // 10
|
||||
{ ERROR_BAD_FORMAT, ENOEXEC }, // 11
|
||||
{ ERROR_INVALID_ACCESS, EINVAL }, // 12
|
||||
{ ERROR_INVALID_DATA, EINVAL }, // 13
|
||||
{ ERROR_INVALID_DRIVE, ENOENT }, // 15
|
||||
{ ERROR_CURRENT_DIRECTORY, EACCES }, // 16
|
||||
{ ERROR_NOT_SAME_DEVICE, EXDEV }, // 17
|
||||
{ ERROR_NO_MORE_FILES, ENOENT }, // 18
|
||||
{ ERROR_LOCK_VIOLATION, EACCES }, // 33
|
||||
{ ERROR_BAD_NETPATH, ENOENT }, // 53
|
||||
{ ERROR_NETWORK_ACCESS_DENIED, EACCES }, // 65
|
||||
{ ERROR_BAD_NET_NAME, ENOENT }, // 67
|
||||
{ ERROR_FILE_EXISTS, EEXIST }, // 80
|
||||
{ ERROR_CANNOT_MAKE, EACCES }, // 82
|
||||
{ ERROR_FAIL_I24, EACCES }, // 83
|
||||
{ ERROR_INVALID_PARAMETER, EINVAL }, // 87
|
||||
{ ERROR_NO_PROC_SLOTS, EAGAIN }, // 89
|
||||
{ ERROR_DRIVE_LOCKED, EACCES }, // 108
|
||||
{ ERROR_BROKEN_PIPE, EPIPE }, // 109
|
||||
{ ERROR_DISK_FULL, ENOSPC }, // 112
|
||||
{ ERROR_INVALID_TARGET_HANDLE, EBADF }, // 114
|
||||
{ ERROR_WAIT_NO_CHILDREN, ECHILD }, // 128
|
||||
{ ERROR_CHILD_NOT_COMPLETE, ECHILD }, // 129
|
||||
{ ERROR_DIRECT_ACCESS_HANDLE, EBADF }, // 130
|
||||
{ ERROR_NEGATIVE_SEEK, EINVAL }, // 131
|
||||
{ ERROR_SEEK_ON_DEVICE, EACCES }, // 132
|
||||
{ ERROR_DIR_NOT_EMPTY, ENOTEMPTY }, // 145
|
||||
{ ERROR_NOT_LOCKED, EACCES }, // 158
|
||||
{ ERROR_BAD_PATHNAME, ENOENT }, // 161
|
||||
{ ERROR_MAX_THRDS_REACHED, EAGAIN }, // 164
|
||||
{ ERROR_LOCK_FAILED, EACCES }, // 167
|
||||
{ ERROR_ALREADY_EXISTS, EEXIST }, // 183
|
||||
{ ERROR_FILENAME_EXCED_RANGE, ENOENT }, // 206
|
||||
{ ERROR_NESTING_NOT_ALLOWED, EAGAIN }, // 215
|
||||
{ ERROR_NO_UNICODE_TRANSLATION, EILSEQ }, // 1113
|
||||
{ ERROR_NOT_ENOUGH_QUOTA, ENOMEM } // 1816
|
||||
};
|
||||
|
||||
static int set_errno_from_oserror(unsigned long oserr)
|
||||
{
|
||||
if (!oserr)
|
||||
return 0;
|
||||
|
||||
// Check the table for the Windows OS error code
|
||||
for (const struct errentry &entry : errtable)
|
||||
{
|
||||
if (oserr == entry.oserr)
|
||||
{
|
||||
_set_errno(entry.errcode);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
_set_errno(EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// On Windows, use strerror_s().
|
||||
std::string strerr(int errn)
|
||||
{
|
||||
@@ -57,7 +136,67 @@ std::string strerr(int errn)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
typedef std::basic_ios<char,std::char_traits < char > > _Myios;
|
||||
inline bool is_slash(wchar_t const c)
|
||||
{
|
||||
return c == L'\\' || c == L'/';
|
||||
}
|
||||
|
||||
static std::wstring utf8path_to_wstring(const std::string& utf8path)
|
||||
{
|
||||
if (utf8path.size() >= MAX_PATH)
|
||||
{
|
||||
// By prepending "\\?\" to a path, Windows widechar file APIs will not fail on long path names
|
||||
std::wstring utf16path = L"\\\\?\\" + ll_convert<std::wstring>(utf8path);
|
||||
// We need to make sure that the path does not contain forward slashes as above
|
||||
// prefix does bypass the path normalization that replaces slashes with backslashes
|
||||
// before passing the path to kernel mode APIs
|
||||
std::replace(utf16path.begin(), utf16path.end(), L'/', L'\\');
|
||||
return utf16path;
|
||||
}
|
||||
return ll_convert<std::wstring>(utf8path);
|
||||
}
|
||||
|
||||
static unsigned short get_fileattr(const std::wstring& utf16path, bool dontFollowSymLink = false)
|
||||
{
|
||||
unsigned long flags = FILE_FLAG_BACKUP_SEMANTICS;
|
||||
if (dontFollowSymLink)
|
||||
{
|
||||
flags |= FILE_FLAG_OPEN_REPARSE_POINT;
|
||||
}
|
||||
HANDLE file_handle = CreateFileW(utf16path.c_str(), FILE_READ_ATTRIBUTES,
|
||||
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
nullptr, OPEN_EXISTING, flags, nullptr);
|
||||
if (file_handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
FILE_ATTRIBUTE_TAG_INFO attribute_info;
|
||||
if (GetFileInformationByHandleEx(file_handle, FileAttributeTagInfo, &attribute_info, sizeof(attribute_info)))
|
||||
{
|
||||
// A volume path alone (only drive letter) is not recognized as directory while it technically is
|
||||
bool is_directory = (attribute_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
|
||||
(iswalpha(utf16path[0]) && utf16path[1] == ':' &&
|
||||
(!utf16path[2] || (is_slash(utf16path[2]) && !utf16path[3])));
|
||||
unsigned short st_mode = is_directory ? S_IFDIR :
|
||||
(attribute_info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT ? S_IFLNK : S_IFREG);
|
||||
st_mode |= (attribute_info.FileAttributes & FILE_ATTRIBUTE_READONLY) ? S_IREAD : S_IREAD | S_IWRITE;
|
||||
// we do not try to guess executable flag
|
||||
|
||||
// propagate user bits to group/other fields:
|
||||
st_mode |= (st_mode & 0700) >> 3;
|
||||
st_mode |= (st_mode & 0700) >> 6;
|
||||
|
||||
CloseHandle(file_handle);
|
||||
return st_mode;
|
||||
}
|
||||
}
|
||||
// Retrieve last error and set errno before calling CloseHandle()
|
||||
set_errno_from_oserror(GetLastError());
|
||||
|
||||
if (file_handle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(file_handle);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
// On Posix we want to call strerror_r(), but alarmingly, there are two
|
||||
@@ -108,18 +247,13 @@ std::string strerr(int errn)
|
||||
}
|
||||
#endif // ! LL_WINDOWS
|
||||
|
||||
// On either system, shorthand call just infers global 'errno'.
|
||||
std::string strerr()
|
||||
{
|
||||
return strerr(errno);
|
||||
}
|
||||
|
||||
int warnif(const std::string& desc, const std::string& filename, int rc, int accept=0)
|
||||
static int warnif(const std::string& desc, const std::string& filename, int rc, int accept = 0)
|
||||
{
|
||||
if (rc < 0)
|
||||
{
|
||||
// Capture errno before we start emitting output
|
||||
int errn = errno;
|
||||
|
||||
// For certain operations, a particular errno value might be
|
||||
// acceptable -- e.g. stat() could permit ENOENT, mkdir() could permit
|
||||
// EEXIST. Don't warn if caller explicitly says this errno is okay.
|
||||
@@ -176,68 +310,59 @@ int warnif(const std::string& desc, const std::string& filename, int rc, int acc
|
||||
// static
|
||||
int LLFile::mkdir(const std::string& dirname, int perms)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// permissions are ignored on Windows
|
||||
std::string utf8dirname = dirname;
|
||||
llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname);
|
||||
int rc = _wmkdir(utf16dirname.c_str());
|
||||
#else
|
||||
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. There is no known case in which we want to call out as
|
||||
// an error the requested directory already existing.
|
||||
#if LL_WINDOWS
|
||||
// permissions are ignored on Windows
|
||||
int rc = 0;
|
||||
std::wstring utf16dirname = utf8path_to_wstring(dirname);
|
||||
if (!CreateDirectoryW(utf16dirname.c_str(), nullptr))
|
||||
{
|
||||
// Only treat other errors than an already existing file as a real error
|
||||
unsigned long oserr = GetLastError();
|
||||
if (oserr != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
rc = set_errno_from_oserror(oserr);
|
||||
}
|
||||
}
|
||||
#else
|
||||
int rc = ::mkdir(dirname.c_str(), (mode_t)perms);
|
||||
if (rc < 0 && errno == EEXIST)
|
||||
{
|
||||
// this is not the error you want, move along
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
// anything else might be a problem
|
||||
return warnif("mkdir", dirname, rc, EEXIST);
|
||||
return warnif("mkdir", dirname, rc);
|
||||
}
|
||||
|
||||
// static
|
||||
int LLFile::rmdir(const std::string& dirname)
|
||||
int LLFile::rmdir(const std::string& dirname, int suppress_error)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// permissions are ignored on Windows
|
||||
std::string utf8dirname = dirname;
|
||||
llutf16string utf16dirname = utf8str_to_utf16str(utf8dirname);
|
||||
std::wstring utf16dirname = utf8path_to_wstring(dirname);
|
||||
int rc = _wrmdir(utf16dirname.c_str());
|
||||
#else
|
||||
int rc = ::rmdir(dirname.c_str());
|
||||
#endif
|
||||
return warnif("rmdir", dirname, rc);
|
||||
return warnif("rmdir", dirname, rc, suppress_error);
|
||||
}
|
||||
|
||||
// static
|
||||
LLFILE* LLFile::fopen(const std::string& filename, const char* mode) /* Flawfinder: ignore */
|
||||
LLFILE* LLFile::fopen(const std::string& filename, const char* mode)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
std::string utf8filename = filename;
|
||||
std::string utf8mode = std::string(mode);
|
||||
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
|
||||
llutf16string utf16mode = utf8str_to_utf16str(utf8mode);
|
||||
return _wfopen(utf16filename.c_str(),utf16mode.c_str());
|
||||
std::wstring utf16filename = utf8path_to_wstring(filename);
|
||||
std::wstring utf16mode = ll_convert<std::wstring>(std::string(mode));
|
||||
return _wfopen(utf16filename.c_str(), utf16mode.c_str());
|
||||
#else
|
||||
return ::fopen(filename.c_str(),mode); /* Flawfinder: ignore */
|
||||
#endif
|
||||
}
|
||||
|
||||
LLFILE* LLFile::_fsopen(const std::string& filename, const char* mode, int sharingFlag)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
std::string utf8filename = filename;
|
||||
std::string utf8mode = std::string(mode);
|
||||
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
|
||||
llutf16string utf16mode = utf8str_to_utf16str(utf8mode);
|
||||
return _wfsopen(utf16filename.c_str(),utf16mode.c_str(),sharingFlag);
|
||||
#else
|
||||
llassert(0);//No corresponding function on non-windows
|
||||
return NULL;
|
||||
return ::fopen(filename.c_str(),mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
int LLFile::close(LLFILE * file)
|
||||
{
|
||||
int ret_value = 0;
|
||||
@@ -248,9 +373,10 @@ int LLFile::close(LLFILE * file)
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
// static
|
||||
std::string LLFile::getContents(const std::string& filename)
|
||||
{
|
||||
LLFILE* fp = fopen(filename, "rb"); /* Flawfinder: ignore */
|
||||
LLFILE* fp = LLFile::fopen(filename, "rb");
|
||||
if (fp)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
@@ -267,45 +393,80 @@ std::string LLFile::getContents(const std::string& filename)
|
||||
return LLStringUtil::null;
|
||||
}
|
||||
|
||||
int LLFile::remove(const std::string& filename, int supress_error)
|
||||
// static
|
||||
int LLFile::remove(const std::string& filename, int suppress_error)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
std::string utf8filename = filename;
|
||||
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
|
||||
int rc = _wremove(utf16filename.c_str());
|
||||
// Posix remove() works on both files and directories although on Windows
|
||||
// remove() and its wide char variant _wremove() only removes files just
|
||||
// as its siblings unlink() and _wunlink().
|
||||
// If we really only want to support files we should instead use
|
||||
// unlink() in the non-Windows part below too
|
||||
int rc = -1;
|
||||
std::wstring utf16filename = utf8path_to_wstring(filename);
|
||||
unsigned short st_mode = get_fileattr(utf16filename);
|
||||
if (S_ISDIR(st_mode))
|
||||
{
|
||||
rc = _wrmdir(utf16filename.c_str());
|
||||
}
|
||||
else if (S_ISREG(st_mode))
|
||||
{
|
||||
rc = _wunlink(utf16filename.c_str());
|
||||
}
|
||||
else if (st_mode)
|
||||
{
|
||||
// it is something else than a file or directory
|
||||
// this should not really happen as long as we do not allow for symlink
|
||||
// detection in the optional parameter to get_fileattr()
|
||||
rc = set_errno_from_oserror(ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
else
|
||||
{
|
||||
// get_fileattr() failed and already set errno, preserve it for correct error reporting
|
||||
}
|
||||
#else
|
||||
int rc = ::remove(filename.c_str());
|
||||
#endif
|
||||
return warnif("remove", filename, rc, supress_error);
|
||||
return warnif("remove", filename, rc, suppress_error);
|
||||
}
|
||||
|
||||
int LLFile::rename(const std::string& filename, const std::string& newname, int supress_error)
|
||||
// static
|
||||
int LLFile::rename(const std::string& filename, const std::string& newname, int suppress_error)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
std::string utf8filename = filename;
|
||||
std::string utf8newname = newname;
|
||||
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
|
||||
llutf16string utf16newname = utf8str_to_utf16str(utf8newname);
|
||||
int rc = _wrename(utf16filename.c_str(),utf16newname.c_str());
|
||||
// Posix rename() will gladly overwrite a file at newname if it exists, the Windows
|
||||
// rename(), respectively _wrename(), will bark on that. Instead call directly the Windows
|
||||
// API MoveFileEx() and use its flags to specify that overwrite is allowed.
|
||||
std::wstring utf16filename = utf8path_to_wstring(filename);
|
||||
std::wstring utf16newname = utf8path_to_wstring(newname);
|
||||
int rc = 0;
|
||||
if (!MoveFileExW(utf16filename.c_str(), utf16newname.c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED))
|
||||
{
|
||||
rc = set_errno_from_oserror(GetLastError());
|
||||
}
|
||||
#else
|
||||
int rc = ::rename(filename.c_str(),newname.c_str());
|
||||
#endif
|
||||
return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, supress_error);
|
||||
return warnif(STRINGIZE("rename to '" << newname << "' from"), filename, rc, suppress_error);
|
||||
}
|
||||
|
||||
// Make this a define rather than using magic numbers multiple times in the code
|
||||
#define LLFILE_COPY_BUFFER_SIZE 16384
|
||||
|
||||
// static
|
||||
bool LLFile::copy(const std::string& from, const std::string& to)
|
||||
{
|
||||
bool copied = false;
|
||||
LLFILE* in = LLFile::fopen(from, "rb"); /* Flawfinder: ignore */
|
||||
LLFILE* in = LLFile::fopen(from, "rb");
|
||||
if (in)
|
||||
{
|
||||
LLFILE* out = LLFile::fopen(to, "wb"); /* Flawfinder: ignore */
|
||||
LLFILE* out = LLFile::fopen(to, "wb");
|
||||
if (out)
|
||||
{
|
||||
char buf[16384]; /* Flawfinder: ignore */
|
||||
char buf[LLFILE_COPY_BUFFER_SIZE];
|
||||
size_t readbytes;
|
||||
bool write_ok = true;
|
||||
while(write_ok && (readbytes = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
|
||||
while (write_ok && (readbytes = fread(buf, 1, LLFILE_COPY_BUFFER_SIZE, in)))
|
||||
{
|
||||
if (fwrite(buf, 1, readbytes, out) != readbytes)
|
||||
{
|
||||
@@ -324,34 +485,62 @@ bool LLFile::copy(const std::string& from, const std::string& to)
|
||||
return copied;
|
||||
}
|
||||
|
||||
int LLFile::stat(const std::string& filename, llstat* filestatus)
|
||||
// static
|
||||
int LLFile::stat(const std::string& filename, llstat* filestatus, int suppress_error)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
std::string utf8filename = filename;
|
||||
llutf16string utf16filename = utf8str_to_utf16str(utf8filename);
|
||||
int rc = _wstat(utf16filename.c_str(),filestatus);
|
||||
std::wstring utf16filename = utf8path_to_wstring(filename);
|
||||
int rc = _wstat64(utf16filename.c_str(), filestatus);
|
||||
#else
|
||||
int rc = ::stat(filename.c_str(),filestatus);
|
||||
int rc = ::stat(filename.c_str(), filestatus);
|
||||
#endif
|
||||
// We use stat() to determine existence (see isfile(), isdir()).
|
||||
// Don't spam the log if the subject pathname doesn't exist.
|
||||
return warnif("stat", filename, rc, ENOENT);
|
||||
return warnif("stat", filename, rc, suppress_error);
|
||||
}
|
||||
|
||||
// static
|
||||
unsigned short LLFile::getattr(const std::string& filename, bool dontFollowSymLink, int suppress_error)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
// _wstat64() is a bit heavyweight on Windows, use a more lightweight API
|
||||
// to just get the attributes
|
||||
int rc = -1;
|
||||
std::wstring utf16filename = utf8path_to_wstring(filename);
|
||||
unsigned short st_mode = get_fileattr(utf16filename, dontFollowSymLink);
|
||||
if (st_mode)
|
||||
{
|
||||
return st_mode;
|
||||
}
|
||||
#else
|
||||
llstat filestatus;
|
||||
int rc = dontFollowSymLink ? ::lstat(filename.c_str(), &filestatus) : ::stat(filename.c_str(), &filestatus);
|
||||
if (rc == 0)
|
||||
{
|
||||
return filestatus.st_mode;
|
||||
}
|
||||
#endif
|
||||
warnif("getattr", filename, rc, suppress_error);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLFile::isdir(const std::string& filename)
|
||||
{
|
||||
llstat st;
|
||||
|
||||
return stat(filename, &st) == 0 && S_ISDIR(st.st_mode);
|
||||
return S_ISDIR(getattr(filename));
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLFile::isfile(const std::string& filename)
|
||||
{
|
||||
llstat st;
|
||||
|
||||
return stat(filename, &st) == 0 && S_ISREG(st.st_mode);
|
||||
return S_ISREG(getattr(filename));
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLFile::islink(const std::string& filename)
|
||||
{
|
||||
return S_ISLNK(getattr(filename, true));
|
||||
}
|
||||
|
||||
// static
|
||||
const char *LLFile::tmpdir()
|
||||
{
|
||||
static std::string utf8path;
|
||||
@@ -378,89 +567,22 @@ const char *LLFile::tmpdir()
|
||||
return utf8path.c_str();
|
||||
}
|
||||
|
||||
|
||||
/***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
LLFILE * LLFile::_Fiopen(const std::string& filename,
|
||||
std::ios::openmode mode)
|
||||
{ // open a file
|
||||
static const char *mods[] =
|
||||
{ // fopen mode strings corresponding to valid[i]
|
||||
"r", "w", "w", "a", "rb", "wb", "wb", "ab",
|
||||
"r+", "w+", "a+", "r+b", "w+b", "a+b",
|
||||
0};
|
||||
static const int valid[] =
|
||||
{ // valid combinations of open flags
|
||||
ios_base::in,
|
||||
ios_base::out,
|
||||
ios_base::out | ios_base::trunc,
|
||||
ios_base::out | ios_base::app,
|
||||
ios_base::in | ios_base::binary,
|
||||
ios_base::out | ios_base::binary,
|
||||
ios_base::out | ios_base::trunc | ios_base::binary,
|
||||
ios_base::out | ios_base::app | ios_base::binary,
|
||||
ios_base::in | ios_base::out,
|
||||
ios_base::in | ios_base::out | ios_base::trunc,
|
||||
ios_base::in | ios_base::out | ios_base::app,
|
||||
ios_base::in | ios_base::out | ios_base::binary,
|
||||
ios_base::in | ios_base::out | ios_base::trunc
|
||||
| ios_base::binary,
|
||||
ios_base::in | ios_base::out | ios_base::app
|
||||
| ios_base::binary,
|
||||
0};
|
||||
|
||||
LLFILE *fp = 0;
|
||||
int n;
|
||||
ios_base::openmode atendflag = mode & ios_base::ate;
|
||||
ios_base::openmode norepflag = mode & ios_base::_Noreplace;
|
||||
|
||||
if (mode & ios_base::_Nocreate)
|
||||
mode |= ios_base::in; // file must exist
|
||||
mode &= ~(ios_base::ate | ios_base::_Nocreate | ios_base::_Noreplace);
|
||||
for (n = 0; valid[n] != 0 && valid[n] != mode; ++n)
|
||||
; // look for a valid mode
|
||||
|
||||
if (valid[n] == 0)
|
||||
return (0); // no valid mode
|
||||
else if (norepflag && mode & (ios_base::out | ios_base::app)
|
||||
&& (fp = LLFile::fopen(filename, "r")) != 0) /* Flawfinder: ignore */
|
||||
{ // file must not exist, close and fail
|
||||
fclose(fp);
|
||||
return (0);
|
||||
}
|
||||
else if (fp != 0 && fclose(fp) != 0)
|
||||
return (0); // can't close after test open
|
||||
// should open with protection here, if other than default
|
||||
else if ((fp = LLFile::fopen(filename, mods[n])) == 0) /* Flawfinder: ignore */
|
||||
return (0); // open failed
|
||||
|
||||
if (!atendflag || fseek(fp, 0, SEEK_END) == 0)
|
||||
return (fp); // no need to seek to end, or seek succeeded
|
||||
|
||||
fclose(fp); // can't position at end
|
||||
return (0);
|
||||
}
|
||||
|
||||
#endif /* LL_WINDOWS */
|
||||
|
||||
|
||||
#if LL_WINDOWS
|
||||
/************** input file stream ********************************/
|
||||
|
||||
llifstream::llifstream() {}
|
||||
|
||||
// explicit
|
||||
llifstream::llifstream(const std::string& _Filename, ios_base::openmode _Mode):
|
||||
std::ifstream(utf8str_to_utf16str( _Filename ).c_str(),
|
||||
std::ifstream(ll_convert<std::wstring>( _Filename ).c_str(),
|
||||
_Mode | ios_base::in)
|
||||
{
|
||||
}
|
||||
|
||||
void llifstream::open(const std::string& _Filename, ios_base::openmode _Mode)
|
||||
{
|
||||
std::ifstream::open(utf8str_to_utf16str(_Filename).c_str(),
|
||||
std::ifstream::open(ll_convert<std::wstring>(_Filename).c_str(),
|
||||
_Mode | ios_base::in);
|
||||
}
|
||||
|
||||
@@ -472,14 +594,14 @@ llofstream::llofstream() {}
|
||||
|
||||
// explicit
|
||||
llofstream::llofstream(const std::string& _Filename, ios_base::openmode _Mode):
|
||||
std::ofstream(utf8str_to_utf16str( _Filename ).c_str(),
|
||||
std::ofstream(ll_convert<std::wstring>( _Filename ).c_str(),
|
||||
_Mode | ios_base::out)
|
||||
{
|
||||
}
|
||||
|
||||
void llofstream::open(const std::string& _Filename, ios_base::openmode _Mode)
|
||||
{
|
||||
std::ofstream::open(utf8str_to_utf16str( _Filename ).c_str(),
|
||||
std::ofstream::open(ll_convert<std::wstring>( _Filename ).c_str(),
|
||||
_Mode | ios_base::out);
|
||||
}
|
||||
|
||||
|
||||
+92
-16
@@ -41,8 +41,9 @@ typedef FILE LLFILE;
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if LL_WINDOWS
|
||||
// windows version of stat function and stat data structure are called _stat
|
||||
typedef struct _stat llstat;
|
||||
// The Windows version of stat function and stat data structure are called _stat64
|
||||
// We use _stat64 here to support 64-bit st_size and time_t values
|
||||
typedef struct _stat64 llstat;
|
||||
#else
|
||||
typedef struct stat llstat;
|
||||
#include <sys/types.h>
|
||||
@@ -56,35 +57,110 @@ typedef struct stat llstat;
|
||||
# define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
// Windows C runtime library does not define this and does not support symlink detection in the
|
||||
// stat functions but we do in our getattr() function
|
||||
#ifndef S_IFLNK
|
||||
#define S_IFLNK 0xA000 /* symlink */
|
||||
#endif
|
||||
|
||||
#ifndef S_ISLNK
|
||||
#define S_ISLNK(x) (((x) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
|
||||
#include "llstring.h" // safe char* -> std::string conversion
|
||||
|
||||
/// LLFile is a class of static functions operating on paths
|
||||
/// All the functions with a path string input take UTF8 path/filenames
|
||||
class LL_COMMON_API LLFile
|
||||
{
|
||||
public:
|
||||
// All these functions take UTF8 path/filenames.
|
||||
static LLFILE* fopen(const std::string& filename,const char* accessmode); /* Flawfinder: ignore */
|
||||
static LLFILE* _fsopen(const std::string& filename,const char* accessmode,int sharingFlag);
|
||||
/// open a file with the specified access mode
|
||||
static LLFILE* fopen(const std::string& filename, const char* accessmode); /* Flawfinder: ignore */
|
||||
///< 'accessmode' follows the rules of the Posix fopen() mode parameter
|
||||
/// "r" open the file for reading only and positions the stream at the beginning
|
||||
/// "r+" open the file for reading and writing and positions the stream at the beginning
|
||||
/// "w" open the file for reading and writing and truncate it to zero length
|
||||
/// "w+" open or create the file for reading and writing and truncate to zero length if it existed
|
||||
/// "a" open the file for reading and writing and position the stream at the end of the file
|
||||
/// "a+" open or create the file for reading and writing and position the stream at the end of the file
|
||||
///
|
||||
/// in addition to these values, "b" can be appended to indicate binary stream access, but on Linux and Mac
|
||||
/// this is strictly for compatibility and has no effect. On Windows this makes the file functions not
|
||||
/// try to translate line endings. Windows also allows to append "t" to indicate text mode. If neither
|
||||
/// "b" or "t" is defined, Windows uses the value set by _fmode which by default is _O_TEXT.
|
||||
/// This means that it is always a good idea to append "b" specifically for binary file access to
|
||||
/// avoid corruption of the binary consistency of the data stream when reading or writing
|
||||
/// Other characters in 'accessmode' will usually cause an error as fopen will verify this parameter
|
||||
/// @returns a valid LLFILE* pointer on success or NULL on failure
|
||||
|
||||
static int close(LLFILE * file);
|
||||
|
||||
/// retrieve the content of a file into a string
|
||||
static std::string getContents(const std::string& filename);
|
||||
///< @returns the content of the file or an empty string on failure
|
||||
|
||||
// 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.
|
||||
/// create a directory
|
||||
static int mkdir(const std::string& filename, int perms = 0700);
|
||||
///< 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 not an error.
|
||||
/// @returns 0 on success and -1 on failure.
|
||||
|
||||
static int rmdir(const std::string& filename);
|
||||
static int remove(const std::string& filename, int supress_error = 0);
|
||||
static int rename(const std::string& filename,const std::string& newname, int supress_error = 0);
|
||||
//// remove a directory
|
||||
static int rmdir(const std::string& filename, int suppress_error = 0);
|
||||
///< pass ENOENT in the optional 'suppress_error' parameter
|
||||
/// if you don't want a warning in the log when the directory does not exist
|
||||
/// @returns 0 on success and -1 on failure.
|
||||
|
||||
/// remove a file or directory
|
||||
static int remove(const std::string& filename, int suppress_error = 0);
|
||||
///< pass ENOENT in the optional 'suppress_error' parameter
|
||||
/// if you don't want a warning in the log when the directory does not exist
|
||||
/// @returns 0 on success and -1 on failure.
|
||||
|
||||
/// rename a file
|
||||
static int rename(const std::string& filename, const std::string& newname, int suppress_error = 0);
|
||||
///< it will silently overwrite newname if it exists without returning an error
|
||||
/// Posix guarantees that if newname already exists, then there will be no moment
|
||||
/// in which for other processes newname does not exist. There is no such guarantee
|
||||
/// under Windows at this time. It may do it in the same way but the used Windows API
|
||||
/// does not make such guarantees.
|
||||
/// @returns 0 on success and -1 on failure.
|
||||
|
||||
|
||||
/// copy the contents of file from 'from' to 'to' filename
|
||||
static bool copy(const std::string& from, const std::string& to);
|
||||
///< @returns true on success and false on failure.
|
||||
|
||||
static int stat(const std::string& filename,llstat* file_status);
|
||||
static bool isdir(const std::string& filename);
|
||||
static bool isfile(const std::string& filename);
|
||||
static LLFILE * _Fiopen(const std::string& filename,
|
||||
std::ios::openmode mode);
|
||||
/// return the file stat structure for filename
|
||||
static int stat(const std::string& filename, llstat* file_status, int suppress_error = ENOENT);
|
||||
///< for compatibility with existing uses of LL_File::stat() we use ENOENT as default in the
|
||||
/// optional 'suppress_error' parameter to avoid spamming the log with warnings when the API
|
||||
/// is used to detect if a file exists
|
||||
/// @returns 0 on success and -1 on failure.
|
||||
|
||||
/// get the file or directory attributes for filename
|
||||
static unsigned short getattr(const std::string& filename, bool dontFollowSymLink = false, int suppress_error = ENOENT);
|
||||
///< a more lightweight function on Windows to stat, that just returns the file attribute flags
|
||||
/// dontFollowSymLinks set to true returns the attributes of the symlink if it is one, rather than resolving it
|
||||
/// we pass by default ENOENT in the optional 'suppress_error' parameter to not spam the log with
|
||||
/// warnings when the file or directory does not exist
|
||||
/// @returns 0 on failure and a st_mode value with either S_IFDIR or S_IFREG set otherwise
|
||||
/// together with the three access bits which under Windows only the write bit is relevant.
|
||||
|
||||
/// check if filename is an existing directory
|
||||
static bool isdir(const std::string& filename);
|
||||
///< @returns true if the path is for an existing directory
|
||||
|
||||
/// check if filename is an existing file
|
||||
static bool isfile(const std::string& filename);
|
||||
///< @returns true if the path is for an existing file
|
||||
|
||||
/// check if filename is a symlink
|
||||
static bool islink(const std::string& filename);
|
||||
///< @returns true if the path is pointing at a symlink
|
||||
|
||||
/// return a path to the temporary directory on the system
|
||||
static const char * tmpdir();
|
||||
};
|
||||
|
||||
|
||||
@@ -188,6 +188,17 @@ public:
|
||||
<< childout.peek(0, peeklen) << "..." << LL_ENDL;
|
||||
}
|
||||
|
||||
// Handle any remaining stderr data (partial lines) the same way as we do
|
||||
// for stdout: log it.
|
||||
LLProcess::ReadPipe& childerr(mChild->getReadPipe(LLProcess::STDERR));
|
||||
if (childerr.size())
|
||||
{
|
||||
LLProcess::ReadPipe::size_type
|
||||
peeklen((std::min)(LLProcess::ReadPipe::size_type(50), childerr.size()));
|
||||
LL_WARNS("LLLeap") << "Final stderr " << childerr.size() << " bytes: "
|
||||
<< childerr.peek(0, peeklen) << "..." << LL_ENDL;
|
||||
}
|
||||
|
||||
// Kill this instance. MUST BE LAST before return!
|
||||
delete this;
|
||||
return false;
|
||||
|
||||
@@ -255,6 +255,11 @@ void LLMD5::raw_digest(unsigned char* s) const
|
||||
memcpy(s, digest, 16); /* Flawfinder: ignore */
|
||||
}
|
||||
|
||||
#if LL_DARWIN
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#endif
|
||||
|
||||
void LLMD5::hex_digest(char* s) const
|
||||
{
|
||||
if (!finalized)
|
||||
@@ -273,6 +278,10 @@ void LLMD5::hex_digest(char* s) const
|
||||
s[32] = '\0';
|
||||
}
|
||||
|
||||
#if LL_DARWIN
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
std::ostream& operator<<(std::ostream& stream, const LLMD5& context)
|
||||
{
|
||||
char s[33]; /* Flawfinder: ignore */
|
||||
|
||||
+47
-10
@@ -71,7 +71,11 @@ LL_COMMON_API void ll_assert_aligned_func(uintptr_t ptr,U32 alignment);
|
||||
#define ll_assert_aligned(ptr,alignment)
|
||||
#endif
|
||||
|
||||
#if LL_ARM64
|
||||
#include "sse2neon.h"
|
||||
#else
|
||||
#include <xmmintrin.h>
|
||||
#endif
|
||||
|
||||
template <typename T> T* LL_NEXT_ALIGNED_ADDRESS(T* address)
|
||||
{
|
||||
@@ -231,8 +235,6 @@ inline void* ll_aligned_malloc_32(size_t size) // returned hunk MUST be freed wi
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
#if defined(LL_WINDOWS)
|
||||
void* ret = _aligned_malloc(size, 32);
|
||||
#elif defined(LL_DARWIN)
|
||||
void* ret = ll_aligned_malloc_fallback( size, 32 );
|
||||
#else
|
||||
void *ret;
|
||||
if (0 != posix_memalign(&ret, 32, size))
|
||||
@@ -248,8 +250,31 @@ inline void ll_aligned_free_32(void *p)
|
||||
LL_PROFILE_FREE(p);
|
||||
#if defined(LL_WINDOWS)
|
||||
_aligned_free(p);
|
||||
#elif defined(LL_DARWIN)
|
||||
ll_aligned_free_fallback( p );
|
||||
#else
|
||||
free(p); // posix_memalign() is compatible with heap deallocator
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void* ll_aligned_malloc_64(size_t size) // returned hunk MUST be freed with ll_aligned_free_32().
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
#if defined(LL_WINDOWS)
|
||||
void* ret = _aligned_malloc(size, 64);
|
||||
#else
|
||||
void *ret;
|
||||
if (0 != posix_memalign(&ret, 64, size))
|
||||
return nullptr;
|
||||
#endif
|
||||
LL_PROFILE_ALLOC(ret, size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void ll_aligned_free_64(void *p)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
LL_PROFILE_FREE(p);
|
||||
#if defined(LL_WINDOWS)
|
||||
_aligned_free(p);
|
||||
#else
|
||||
free(p); // posix_memalign() is compatible with heap deallocator
|
||||
#endif
|
||||
@@ -261,19 +286,23 @@ LL_FORCE_INLINE void* ll_aligned_malloc(size_t size)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
void* ret;
|
||||
if (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0)
|
||||
if constexpr (LL_DEFAULT_HEAP_ALIGN % ALIGNMENT == 0)
|
||||
{
|
||||
ret = malloc(size);
|
||||
LL_PROFILE_ALLOC(ret, size);
|
||||
}
|
||||
else if (ALIGNMENT == 16)
|
||||
else if constexpr (ALIGNMENT == 16)
|
||||
{
|
||||
ret = ll_aligned_malloc_16(size);
|
||||
}
|
||||
else if (ALIGNMENT == 32)
|
||||
else if constexpr (ALIGNMENT == 32)
|
||||
{
|
||||
ret = ll_aligned_malloc_32(size);
|
||||
}
|
||||
else if constexpr (ALIGNMENT == 64)
|
||||
{
|
||||
ret = ll_aligned_malloc_64(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ll_aligned_malloc_fallback(size, ALIGNMENT);
|
||||
@@ -285,16 +314,20 @@ template<size_t ALIGNMENT>
|
||||
LL_FORCE_INLINE void ll_aligned_free(void* ptr)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
if (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
|
||||
if constexpr (ALIGNMENT == LL_DEFAULT_HEAP_ALIGN)
|
||||
{
|
||||
LL_PROFILE_FREE(ptr);
|
||||
free(ptr);
|
||||
}
|
||||
else if (ALIGNMENT == 16)
|
||||
else if constexpr (ALIGNMENT == 16)
|
||||
{
|
||||
ll_aligned_free_16(ptr);
|
||||
}
|
||||
else if (ALIGNMENT == 32)
|
||||
else if constexpr (ALIGNMENT == 32)
|
||||
{
|
||||
return ll_aligned_free_32(ptr);
|
||||
}
|
||||
else if constexpr (ALIGNMENT == 64)
|
||||
{
|
||||
return ll_aligned_free_32(ptr);
|
||||
}
|
||||
@@ -310,6 +343,9 @@ LL_FORCE_INLINE void ll_aligned_free(void* ptr)
|
||||
inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __restrict src, size_t bytes)
|
||||
{
|
||||
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEMORY;
|
||||
#if defined(LL_ARM64)
|
||||
memcpy(dst, src, bytes);
|
||||
#else
|
||||
assert(src != NULL);
|
||||
assert(dst != NULL);
|
||||
assert(bytes > 0);
|
||||
@@ -375,6 +411,7 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __
|
||||
dst += 16;
|
||||
src += 16;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef __DEBUG_PRIVATE_MEM__
|
||||
|
||||
@@ -76,6 +76,23 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Set up CPU architecture defines
|
||||
#if LL_MSVC && defined(_M_ARM64)
|
||||
# define LL_ARM64 1
|
||||
#elif LL_GNUC && (defined(__arm64__) || defined(__aarch64__))
|
||||
# define LL_ARM64 1
|
||||
#elif LL_MSVC && _M_X64
|
||||
# define LL_X86_64 1
|
||||
# define LL_X86 1
|
||||
#elif LL_MSVC && _M_IX86
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) )
|
||||
# define LL_X86_64 1
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC && ( defined(__i386__) )
|
||||
# define LL_X86 1
|
||||
#endif
|
||||
|
||||
// Deal with minor differences on Unixy OSes.
|
||||
#if LL_DARWIN || LL_LINUX
|
||||
// Different name, same functionality.
|
||||
@@ -118,11 +135,8 @@
|
||||
#if LL_WINDOWS
|
||||
#define LL_DLLEXPORT __declspec(dllexport)
|
||||
#define LL_DLLIMPORT __declspec(dllimport)
|
||||
#elif LL_LINUX
|
||||
#define LL_DLLEXPORT __attribute__ ((visibility("default")))
|
||||
#define LL_DLLIMPORT
|
||||
#else
|
||||
#define LL_DLLEXPORT
|
||||
#define LL_DLLEXPORT __attribute__ ((visibility("default")))
|
||||
#define LL_DLLIMPORT
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
@@ -167,7 +181,7 @@
|
||||
|
||||
#define LL_TO_STRING_HELPER(x) #x
|
||||
#define LL_TO_STRING(x) LL_TO_STRING_HELPER(x)
|
||||
#define LL_TO_WSTRING_HELPER(x) L#x
|
||||
#define LL_TO_WSTRING_HELPER(x) L## #x
|
||||
#define LL_TO_WSTRING(x) LL_TO_WSTRING_HELPER(x)
|
||||
#define LL_FILE_LINENO_MSG(msg) __FILE__ "(" LL_TO_STRING(__LINE__) ") : " msg
|
||||
#define LL_GLUE_IMPL(x, y) x##y
|
||||
@@ -187,4 +201,16 @@
|
||||
#define LL_PRETTY_FUNCTION __PRETTY_FUNCTION__
|
||||
#endif
|
||||
|
||||
#if LL_ARM64
|
||||
#define GLM_FORCE_NEON 1
|
||||
#else
|
||||
#define GLM_FORCE_SSE2 1
|
||||
#endif
|
||||
|
||||
#if LL_ARM64
|
||||
#define KDU_NEON_INTRINSICS 1
|
||||
#else
|
||||
#define KDU_X86_INTRINSICS 1
|
||||
#endif
|
||||
|
||||
#endif // not LL_LINDEN_PREPROCESSOR_H
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user