Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 132 additions & 0 deletions BUILD_FREEBSD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<!--
Copyright 2013-2019 High Fidelity, Inc.
Copyright 2019-2022 Vircadia contributors
Copyright 2021-2026 Overte e.V.
SPDX-License-Identifier: Apache-2.0
-->

# Build FreeBSD

*Last Updated on 2026-03-19*

Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only FreeBSD specific instructions are found in this file.

## Install build tools:

First update the system packages:
```sh
pkg upgrade
```

Install dependencies
```sh
pkg install git gmake cmake conan
```

## Extra dependencies to compile Interface on a server
Install the following:
```sh
pkg install qt5-core qt5-network qt5-testlib qt5-websockets qt5-gui qt5-widgets qt5-concurrent qt5-quickcontrols2 qt5-multimedia qt5-webchannel qt5-webengine qt5-xml qt5-xmlpatterns qt5-svg
```

Install Python 3:
```sh
pkg install python3
```

Install Node.js as it is required to build the jsdoc documentation:
```sh
pkg install node
```

## Get code and checkout the branch you need

Clone this repository:
```sh
git clone https://github.com/overte-org/overte.git
```

Then checkout the master branch with:
```sh
git checkout master
```

If you need a different branch, you can get a list of all tags with:
```sh
git fetch --tags
git tag
```

## Prepare conan

The next step is setting up conan

First, create a conan profile
```sh
conan profile detect --force
```

Next, add the overte remote to conan
```sh
conan remote add overte https://artifactory.overte.org/artifactory/api/conan/overte -f
```

## Compiling

Install the dependencies with conan
```sh
cd overte
conan install . -s build_type=Release -b missing -pr:a=tools/conan-profiles/freebsd -of build
```

If you want to build Debug or RelWithDebInfo versions, change the `build_type` to `Debug` or `RelWithDebInfo` and run the command again. E.g.:
```sh
conan install . -s build_type=Debug -b missing -pr:a=tools/conan-profiles/freebsd -of build
```

Prepare makefiles:
```sh
cmake --preset conan-release
```

### Server

To compile the Domain server:
```sh
cmake --build --preset conan-release domain-server assignment-client
```

*Note: For a server, it is not necessary to compile the Interface.*

### Interface

To compile the Interface client:
```sh
cmake --build --preset conan-release interface
```

## Running the software

### Domain server

Running Domain server:
```sh
./domain-server/domain-server
```

### Assignment clients

Running assignment client:
```sh
./assignment-client/assignment-client -n 6
```

### Interface

Running Interface:
```sh
./interface/interface
```

Go to "localhost" in the running Interface to visit your newly launched Domain server.

18 changes: 13 additions & 5 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,20 +65,22 @@ def requirements(self):
self.requires("gli/cci.20210515") # NOTE: not maintained for 4 years
self.requires("glslang/1.3.268.0")
self.requires("liblo/0.30@overte/stable")
self.requires("libnode/22.22.0@overte/stable#1f75a2b0272c5e3ad9d4ddb432a467f8")
self.requires("libnode/22.22.0@overte/stable#593f688551e3a5a7a115bca8074a43fc")
self.requires("nlohmann_json/3.11.2")
self.requires("nvidia-texture-tools/2023.01@overte/stable#f4eff53a38bd2c26eb6fa1206ffd22f6")
self.requires("onetbb/2021.10.0")
self.requires("openexr/3.1.9")
self.requires("openvr/2.2.3@overte/stable")
self.requires("openxr/1.1.46@overte/stable")
if self.settings.os != "FreeBSD":
self.requires("openvr/2.2.3@overte/stable")
self.requires("openxr/1.1.46@overte/stable")
self.requires("opus/1.5.2")
self.requires("quazip/1.4")
self.requires("scribe/2019.02@overte/stable")
self.requires("sdl/2.32.10")
self.requires("spirv-cross/1.3.268.0")
self.requires("spirv-tools/1.3.268.0")
self.requires("steamworks/158a@overte/prebuild")
if self.settings.os != "FreeBSD":
self.requires("steamworks/158a@overte/prebuild")
self.requires("v-hacd/4.1.0")
self.requires("vulkan-memory-allocator/3.0.1")
self.requires("webrtc-audio-processing/2.1@overte/stable")
Expand All @@ -89,7 +91,7 @@ def requirements(self):

if self.options.qt_source == "system":
self.requires("qt/5.15.2@overte/system", force=True)
if self.settings.os == "Linux":
if self.settings.os in ["Linux", "FreeBSD"]:
openssl = "openssl/system@anotherfoxguy/stable"
elif self.options.qt_source == "aqt":
self.requires("qt/5.15.2@overte/aqt", force=True)
Expand Down Expand Up @@ -169,6 +171,12 @@ def generate(self):
"CMAKE_COMPILE_WARNING_AS_ERROR": "OFF",
})

if self.settings.os == "FreeBSD":
# Steam is not a thing on FreeBSD (yet)
tc.cache_variables.update({
"USE_STEAMWORKS": "OFF",
})

tc.generate()
deps = CMakeDeps(self)
deps.generate()
Expand Down
4 changes: 4 additions & 0 deletions interface/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,10 @@ if (UNIX AND NOT ANDROID AND NOT OVERTE_THREAD_DEBUGGING)
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
# Linux
target_link_libraries(${TARGET_NAME} pthread atomic)
elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
# FreeBSD
find_package(Threads REQUIRED)
target_link_libraries(${TARGET_NAME} Threads::Threads)
else ()
# OSX
target_link_libraries(${TARGET_NAME} pthread)
Expand Down
2 changes: 1 addition & 1 deletion interface/src/Application_Graphics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,7 @@ void Application::initializeUi() {

setIsInterstitialMode(true);

#if defined(DISABLE_QML) && defined(Q_OS_LINUX)
#if defined(DISABLE_QML) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD))
resumeAfterLoginDialogActionTaken();
#endif
}
Expand Down
6 changes: 3 additions & 3 deletions interface/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ int main(int argc, const char* argv[]) {

PROFILE_SYNC_BEGIN(startup, "main startup", "");

#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar);
#endif

Expand Down Expand Up @@ -779,7 +779,7 @@ int main(int argc, const char* argv[]) {
app.initialize(parser);
PROFILE_SYNC_END(startup, "app full ctor", "");

#if defined(Q_OS_LINUX)
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
app.setWindowIcon(QIcon(PathUtils::resourcesPath() + "images/brand-logo.svg"));
#endif
ch.startMonitor(&app);
Expand Down Expand Up @@ -859,7 +859,7 @@ int main(int argc, const char* argv[]) {
Application::shutdownPlugins();

qCDebug(interfaceapp, "Normal exit.");
#if !defined(DEBUG) && !defined(Q_OS_LINUX)
#if !defined(DEBUG) && !defined(Q_OS_LINUX) && !defined(Q_OS_FREEBSD)
// HACK: exit immediately (don't handle shutdown callbacks) for Release build
_exit(exitCode);
#endif
Expand Down
4 changes: 2 additions & 2 deletions libraries/audio-client/src/AudioClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,7 @@ QString defaultAudioDeviceName(QAudio::Mode mode) {

#endif

#ifdef Q_OS_LINUX
#if defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
if ( mode == QAudio::AudioInput ) {
deviceName = QAudioDeviceInfo::defaultInputDevice().deviceName();
} else {
Expand Down Expand Up @@ -2308,7 +2308,7 @@ const float AudioClient::CALLBACK_ACCELERATOR_RATIO = 2.0f;

#ifdef Q_OS_ANDROID
const float AudioClient::CALLBACK_ACCELERATOR_RATIO = 0.5f;
#elif defined(Q_OS_LINUX)
#elif defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)
const float AudioClient::CALLBACK_ACCELERATOR_RATIO = 2.0f;
#endif

Expand Down
2 changes: 2 additions & 0 deletions libraries/auto-updater/src/AutoUpdater.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ AutoUpdater::AutoUpdater() :
_operatingSystem = "mac";
#elif defined Q_OS_LINUX
_operatingSystem = "ubuntu";
#elif defined Q_OS_FREEBSD
_operatingSystem = "freebsd";
#endif

connect(this, SIGNAL(latestVersionDataParsed()), this, SLOT(checkVersionAndNotify()));
Expand Down
25 changes: 24 additions & 1 deletion libraries/gl/src/gl/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include <EGL/egl.h>
#include <GL/glx.h>
#include <dlfcn.h>
#elif defined(Q_OS_FREEBSD)
#include <GL/glx.h>
#include <dlfcn.h>
#endif


Expand Down Expand Up @@ -74,7 +77,7 @@ static void* getGlProcessAddress(const char *namez) {
return dlsym(GL_LIB, namez);
}

#elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDORID)
#elif (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)) && !defined(Q_OS_ANDORID)

typedef Bool (*PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) (int attribute, unsigned int *value);
typedef int (*PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval);
Expand All @@ -94,9 +97,11 @@ PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC QueryCurrentRendererIntegerMESA;
PFNGLXSWAPINTERVALMESAPROC SwapIntervalMESA;
PFNGLXGETSWAPINTERVALMESAPROC GetSwapIntervalMESA;

#if !defined(Q_OS_FREEBSD)
// EGL has its own swap interval functions, so the MESA ones aren't needed there
static bool contextIsEGL = false;
static int previousSwapInterval = 1;
#endif

// the real GetProcAddress functions return a placeholder function
// pointer type (void (*)(void)), but glad expects one returning void*
Expand All @@ -117,6 +122,8 @@ void gl::initModuleGl() {
} else {
getGlProcessAddress = reinterpret_cast<decltype(getGlProcessAddress)>(glXGetProcAddressARB);
}
#elif defined(Q_OS_FREEBSD)
getGlProcessAddress = reinterpret_cast<decltype(getGlProcessAddress)>(glXGetProcAddressARB);
#endif

#if defined(Q_OS_WIN)
Expand All @@ -132,6 +139,10 @@ void gl::initModuleGl() {
SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)getGlProcessAddress("glXSwapIntervalMESA");
GetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC)getGlProcessAddress("glXGetSwapIntervalMESA");
}
#elif defined(Q_OS_FREEBSD)
QueryCurrentRendererIntegerMESA = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)getGlProcessAddress("glXQueryCurrentRendererIntegerMESA");
SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)getGlProcessAddress("glXSwapIntervalMESA");
GetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC)getGlProcessAddress("glXGetSwapIntervalMESA");
#endif

#if defined(USE_GLES)
Expand Down Expand Up @@ -159,6 +170,12 @@ int gl::getSwapInterval() {
} else {
return 1;
}
#elif defined(Q_OS_FREEBSD)
if (GetSwapIntervalMESA) {
return GetSwapIntervalMESA();
} else {
return 1;
}
#else
return 1;
#endif
Expand All @@ -180,6 +197,8 @@ void gl::setSwapInterval(int interval) {
} else if (SwapIntervalMESA) {
SwapIntervalMESA(interval);
}
#elif defined(Q_OS_FREEBSD)
SwapIntervalMESA(interval);
#else
Q_UNUSED(interval);
#endif
Expand All @@ -190,6 +209,10 @@ bool gl::queryCurrentRendererIntegerMESA(int attr, unsigned int *value) {
if (!contextIsEGL && QueryCurrentRendererIntegerMESA) {
return QueryCurrentRendererIntegerMESA(attr, value);
}
#elif defined(Q_OS_FREEBSD)
if (QueryCurrentRendererIntegerMESA) {
return QueryCurrentRendererIntegerMESA(attr, value);
}
#endif

*value = 0;
Expand Down
4 changes: 4 additions & 0 deletions libraries/image/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ if (UNIX AND NOT APPLE)
target_link_libraries(image Threads::Threads)
endif()

if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
target_link_libraries(image execinfo)
endif()

if (WIN32)
add_compile_definitions(_USE_MATH_DEFINES)
endif()
4 changes: 2 additions & 2 deletions libraries/image/src/image/OpenEXRReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#include <QIODevice>
#include <QDebug>

#if !defined(Q_OS_ANDROID)
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_FREEBSD)

#include <OpenEXR/ImfIO.h>
#include <OpenEXR/ImfRgbaFile.h>
Expand Down Expand Up @@ -60,7 +60,7 @@ class QIODeviceImfStream : public Imf::IStream {
#endif

image::Image image::readOpenEXR(QIODevice& content, const std::string& filename) {
#if !defined(Q_OS_ANDROID)
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_FREEBSD)
QIODeviceImfStream device(content, filename);

if (Imf::isOpenExrFile(device)) {
Expand Down
Loading
Loading