Using Urho3D library

Project scaffolding

This section assumes you want to reuse Urho3D build system for your own downstream project. If, however, your project already has a different build system and that you just simply want to use the Urho3D library as an external library then you may want to skip to the next section Using pkg-config instead of CMake instead.

First of all, structure your project similar to Urho3D project as below. Although this is not mandatory, it should increase the chance the CMake modules designed for Urho3D project also works out of the box for your project too. CMake and our CMake modules are case-sensitive. It is recommended that your project adheres to the same naming convention as Urho3D project uses, even when the filesystem in your host system is not case-sensitive.

<PROJECT_ROOT>/
├ bin/
│ ├ Data/
│ └ CoreData/
├ CMake/
│ ├ Modules/
│ └ Toolchains/
├ CMakeLists.txt
├ *.cpp and *.h
└ *.bat or *.sh

The physical project root directory is also the logical project source tree in CMake terminology where your project main CMakeLists.txt should reside. The 'bin' directory should contain the 'Data' and 'CoreData' resource subdirs for your own assets. You must copy (or symlink) the 'CMake' subdir from Urho3D project root directory (or from Urho3D SDK installation, which can be found in the 'share/Urho3D/CMake') to your project root directory. You may also want to copy (or symlink) the build scripts from Urho3D project root directory (or from Urho3D SDK installation, which can be found in the 'share/Urho3D/Scripts') to your project root directory, unless you just want to use cmake-gui for your own project configuration and generation. Alternatively, you can add the Urho3D project root directory into the PATH environment variable in your host system in order to make the build scripts available everywhere. The build scripts work together with the Urho3D CMake modules and toolchains to configure and generate your initial project build tree. Both out-of-source build tree (recommended) and non out-of-source build tree are supported. Note that when you configure your project (either via one of the build script or via cmake-gui), you can only pass the Build options that are applicable to downstream projects. Be mindful that conflicting build options would be ignored.

In your own project root directory, create a main CMakeLists.txt file and add the following lines: (replace MyProjectName and MyExecutableName with the actual names you want)

# Set CMake minimum version
cmake_minimum_required (VERSION 3.10.2)
# Set project name
project (MyProjectName)
# Set CMake modules search path
set (CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/Modules)
# Include UrhoCommon.cmake module after setting project name
include (UrhoCommon)
# Define target name
set (TARGET_NAME MyExecutableName)
# Define source files
define_source_files ()
# Setup target with resource copying
setup_main_executable ()

The CMAKE_MODULE_PATH is setup so that CMake can find the Urho3D-specific CMake modules provided by Urho3D project inside your own project. The UrhoCommon.cmake is the module where all the reusable commands and macros are defined. It also gives your project cross-platform build capability similar to Urho3D project. It does this by automatically finding the required software library components specific for your target platform and configuring your project to use them together with the platform-specific compiler flags and definitions. It utilizes CMake-provided as well as Urho3D custom-made FindXXX modules to get the work done. So, it is important to get the CMAKE_MODULE_PATH setup correctly in your project early on.

Your own project naturally depends on Urho3D project, or to be more precise it depends on Urho3D library. The Urho3D library needs to be built first so that it can be found later by your own project. When using GCC/Clang or one of its derivatives, both Urho3D static and shared libraries could be potentially built/installed at a same location and coexist. In such cases the FindUrho3D.cmake module, the module responsible to find Urho3D software library component and is invoked automatically by the UrhoCommon.cmake module, has precedence to first find the static library type over over shared library type. However, you can use URHO3D_LIB_TYPE build option to override this precedence. When using MSVC compiler, both static and shared libraries could not be built/installed at a same location because both the static library and import library have a same file extension. However, for MSVC, it is possible to have both Release and Debug versions of either static or shared library type built/installed at a same location. In such cases the FindUrho3D.cmake module would automatically utilize both of Release and Debug versions as appropriate in your project for Release and Debug build configuration, respectively, without user intervention.

When you build Urho3D library, you have an option to install the library to a installation location in your file system as if Urho3D is an SDK or you can just leave the library where it is in its build tree. Thus, there are two approaches for your project to link against Urho3D library as external library. However, there is really no difference between the two approaches from your project's point of view. The FindUrho3D.cmake module is designed not only able to find Urho3D library from the Urho3D SDK installation, but also from any Urho3D project build tree directly. When searching in Urho3D SDK installed in a system-wide default location then no additional variable need to be set. When searching in a non-default SDK installation or when searching in any Urho3D project build tree then the actual location need to be provided via URHO3D_HOME environment variable (set in the host system) or URHO3D_HOME build option (set using -D at command line or in cmake-gui). That is, use the URHO3D_HOME to hint the build system to locate the library.

The define_source_files() and setup_main_executable() are Urho3D-specific macros. The define_source_files() macro is a shorthand to glob all the source files in the current directory. It is equivalent to these commands:

file (GLOB CPP_FILES *.cpp)
file (GLOB H_FILES *.h)
set (SOURCE_FILES ${CPP_FILES} ${H_FILES})

The setup_main_executable() macro then uses SOURCE_FILES and TARGET_NAME variables to setup a new CMake target that would work on ALL platforms supported by Urho3D. Make sure both your project name and target name are not called 'Urho3D', as this name is reserved for Urho3D project only.

If you have prepared your new project as outlined above then you can use the build instructions of Urho3D project to build your own project.

Sometimes you may want to have different resource directories to contain your assets than the one used by Urho3D project by convention. For example, you may have them arranged by scenes as follows:

<PROJECT_ROOT>/
├ bin/
│ ├ Scene1/
│ ├ Scene2/
│ └ Core/
├ ...

If that is the case then you have to tell both the build system and the Urho3D library (more specifically the Engine class) where the resource paths are. Using the above example, you have to tell the build system by calling the define_resource_dirs() macro explicitly and passing it the option to glob your resource directories. The define_resource_dirs() macro is actually being called internally with the default option which glob directory names based on Urho3D project convention, but your project can override that by making the call explicitly in your CMakeLists.txt.

...
# Define source files
define_source_files ()
define_resource_dirs (GLOB_PATTERNS ${CMAKE_SOURCE_DIR}/bin/Scene* ${CMAKE_SOURCE_DIR}/bin/Core)
...

You also need to inform the Urho3D library that you have non-conventional resource directory paths. You do that by setting the EP_RESOURCE_PATHS engine parameter, either programmatically during compile time or via '-p' command line option during runtime. In this case you would set it to "Scene1;Scene2;Core" instead of the default "Data;CoreData".

Your project may also want to store the resource directories in other location instead of the 'bin' directory where the executable binary resides. For example when creating macOS/iOS/tvOS bundle, all the assets are automatically bundled into another directory outside where the executable binary resides. In fact, you can have them in a few separate parent directories and not just one. That is where the EP_RESOURCE_PREFIX_PATHS engine parameter and '-pp' command line option come into picture. With this you can define an alternate resource prefix path where your resource path would be prepended before locating your assets.

Using pkg-config instead of CMake

If for some reason you could not use CMake in your project, you could configure your project to compile and link against Urho3D library from SDK installation using 'pkg-config' tool with the help of 'Urho3D.pc' configuration file (which is installed as part of the SDK installation). If the Urho3D SDK is being installed into a local location (such as /usr/local) or a non-default location, then most likely you would need to specify PKG_CONFIG_PATH environment variable to point to the location of the configuration file for this to work. The 'Urho3D.pc' file contains important information on how to configure your compiler and linker correctly. You can use that information as a reference to configure your own project even when you do not use 'pkg-config' tool.

Below are a few invocation examples on a 64-bit RedHat-based distro with local installation:

# To get installed Urho3D version
PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig pkg-config --modversion Urho3D
# To compile and link natively in one liner
c++ -o Urho3DPlayer Urho3DPlayer.cpp `PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig pkg-config --cflags --libs Urho3D`
# To compile and link natively but in separate steps
export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig
c++ -c Urho3DPlayer.cpp `pkg-config --cflags Urho3D`
c++ -o Urho3DPlayer Urho3DPlayer.o `pkg-config --libs Urho3D`
# To cross-compile and link for Raspberry Pi platform
export CC=${RPI_PREFIX}-c++
export PKG_CONFIG_SYSROOT_DIR=${RPI_SYSROOT}
export PKG_CONFIG_PATH=${RPI_SYSROOT}/usr/local/lib/pkgconfig
$CC -o Urho3DPlayer Urho3DPlayer.cpp `pkg-config --cflags --libs Urho3D`
# To cross-compile and link for Windows platform using MinGW cross-compiler (in Debug configuration)
export CC=${MINGW_PREFIX}-c++
export PKG_CONFIG_SYSROOT_DIR=${MINGW_SYSROOT}
export PKG_CONFIG_PATH=${MINGW_SYSROOT}/usr/local/lib/pkgconfig
$CC -o Urho3DPlayer_d.exe Urho3DPlayer.cpp `pkg-config --variable CFLAGS_DEBUG Urho3D` `pkg-config --cflags --libs Urho3D`

Using rake tasks for project scaffolding and building

With Rake ruby gem installed, you can quickly setup all the above by simply using the 'scaffolding' rake task.

rake scaffolding dir=/path/to/new/project/root [project=Scaffolding] [target=Main]

As its name implies, this task just creates a basic project structure for your new project. You may also pass optional "project" and "target" parameters besides the "dir" parameter. Otherwise, you will get the default project name (Scaffolding) and target name (Main) in the main CMakeLists.txt. This task copies the Urho3DPlayer.cpp and Urho3DPlayer.h as placeholders for the source files. Normally, you should replace these two files with your own project source files before invoking one of the build scripts.

On Windows host system, this task requires privilege to create symlinks by using mklink command. The task would fail when the Windows user account does not have that privilege. We strongly advise you not to use "Administrator" account just for this purpose. Instead, grant your "normal" user account to have the privilege correctly.

WARNING: As of this writing, this rake scaffolding task does not yet create a complete new project suitable for Android platform. In future a custom Gradle scaffolding task will be added to perform this job. You need to supply the missing bits manually yourself for now.

The Ruby and Rake are not prerequisite software components for building Urho3D and your projects. However, if you are reading this section this far and that your host system actually already has them installed then you can take advantage of them by utilising the 'rake cmake' and 'rake make' tasks. The former configures and generates the build tree (by invoking one of our build scripts under the hood) and the latter builds the project in the generated build tree (by invoking 'cmake –build' command which in turns calls the respective build tools, such as 'make' or 'xcodebuild', or 'MSBuild.exe') at the convenient of your finger tips in a command line interface.

To configure and generate:

rake cmake [<generator>] [<platform>] [<option>=<value> [<option>=<value>]] [[<platform>_]build_tree=/path/to/build-tree] [fix_scm]

To build:

rake make [<platform>] [<option>=<value> [<option>=<value>]] [[<platform>_]build_tree=/path/to/build-tree] [numjobs=n] [clean_first] [unfilter]

The default <generator> when not specified is 'generic', which let CMake to detect and choose what generator is available in the host to use. The possible values are: 'codeblocks', 'eclipse', 'ninja', 'vs2015', 'vs2017', 'vs2019', 'xcode'.

The default <platform> when not specified is 'native'. The possible values are: 'android', 'web', 'ios', 'tvos', 'mingw', 'rpi'. Naturally this influences the compiler toolchain being used in the generated build tree.

When using the 'rake cmake' task, the <option>=<value> pairs are optional build options supported by our build scripts as usual. However, the format here does not expect a leading '-D' for each pair. When using the 'rake make' task, the <option>=<value> pairs are optional build options supported by the respective build tools. For example on iOS/tvOS platform using 'xcodebuild' build tool, one could pass the '-sdk' option as follows: 'rake make ios sdk=iphonesimulator'. Note the absence of leading '-' character in the example. To build a specific built-in target in the project, use the 'target' option, e.g. 'rake make target=install'. In a multi-config project, such as Xcode project or VS solution, use the 'config' option to choose which build configuration to use, e.g. 'rake make config=Release'. For Xcode project building using 'rake make' task, you may optional install the 'xcpretty' filter to address the verbosity of the 'xcodebuild' tool from its standard output stream. On the other hand, pass the 'unfilter' option to get the output from 'xcodebuild' tool unfiltered regardless the 'xcpretty' is installed or not. You can pass the 'clean_first' option to perform a clean build. By default this task invokes the respective build tool to use all the logical CPU cores available, but you can use the 'numjobs' option to override this default.

Use the 'build_tree' option to set the path to the desired build tree location. When not specified then the build tree location would be defaulted to '../<platform>-Build', relative to the project root. To avoid repeating the customized build tree locations for each platform, you can set and export them as environment variables. The '<platform_>build_tree' option takes precedence over normal 'build_tree' option. For example with these commands below, the native and RPI build tree will be generated in the ~/custom-native-Build and ~/custom-rpi-Build, respectively, and then build from there.

export native_build_tree=~/custom-native-Build rpi_build_tree=~/custom-rpi-Build
rake cmake URHO3D_LUAJIT=1 && rake make
rake cmake rpi URHO3D_LUAJIT=1 && rake make rpi

You can in fact set and export any other key/value pair build options as environment variables to avoid repeating yourself when invoking any of our Rake tasks.