Skip to content

Commit

Permalink
CMake build now has support for non-relocatable builds
Browse files Browse the repository at this point in the history
Although the previous build was not defining ENABLE_RELOCATION, it was treating
the build as relocatable by default, setting an RPATH based on $ORIGIN and
never defining PKGLIBDIR, PKGDATADIR etc in the source code. Although this
works fine on Debian, the assumption that the libraries are ALWAYS available at
$ORIGIN/../lib/darkradiant might not be suitable for all systems.

We now expose an additional CMake option ENABLE_RELOCATION which defaults to
ON; by setting this to OFF the build becomes the more usual Unix-style build
with hard-coded absolute data and library paths. In addition, when making a
relocatable build the expected ENABLE_RELOCATION macro is also defined in
config.h.
  • Loading branch information
Matthew Mott committed Dec 11, 2020
1 parent b5308ac commit b3a1f56
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 28 deletions.
43 changes: 28 additions & 15 deletions CMakeLists.txt
Expand Up @@ -7,10 +7,30 @@ project(darkradiant VERSION 2.9.1)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# Expose some build options
option(SKIP_DM_PLUGINS "Don't build Dark Mod specific plugins" OFF)
option(ENABLE_RELOCATION
"Avoid hard-coded absolute paths to libraries or resources"
ON)

# Define GNU-style directory structure by default
include(GNUInstallDirs)

# Set up core build paths
set(CORE_MODULE_LIBRARY "libradiantcore")
set(PKGDATADIR "${CMAKE_INSTALL_FULL_DATADIR}/darkradiant")
if (NOT ${ENABLE_RELOCATION})
set(PKGLIBDIR "${CMAKE_INSTALL_FULL_LIBDIR}/darkradiant")
set(HTMLDIR "${CMAKE_INSTALL_FULL_DATADIR}/doc/darkradiant")
endif()

# Build shared libraries by default
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
option(SKIP_DM_PLUGINS "Don't build Dark Mod specific plugins" OFF)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib/darkradiant")
if (${ENABLE_RELOCATION})
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib/darkradiant")
else()
set(CMAKE_INSTALL_RPATH "${PKGLIBDIR}")
endif()

# Debug or release mode
if(NOT CMAKE_BUILD_TYPE)
Expand All @@ -21,10 +41,6 @@ add_compile_definitions(
$<$<CONFIG:Release>:NDEBUG>
)

# Define GNU-style directory structure by default, and pass directories to the
# code with defines
include(GNUInstallDirs)

# Locate system packages
include(FindPkgConfig)
pkg_check_modules(XML libxml-2.0 REQUIRED)
Expand Down Expand Up @@ -57,7 +73,6 @@ add_compile_definitions(POSIX
add_link_options(LINKER:-z,defs)

# Generate config.h
set(CORE_MODULE_LIBRARY "libradiantcore")
configure_file(config.h.in config.h)
add_compile_definitions(HAVE_CONFIG_H)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
Expand Down Expand Up @@ -107,21 +122,19 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/install/darkradiant.desktop
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)

# Install resources
set(PKG_DATA_DIR "${CMAKE_INSTALL_DATADIR}/darkradiant")

file(GLOB XML_FILES "${PROJECT_SOURCE_DIR}/install/*.xml")
install(FILES ${XML_FILES} DESTINATION ${PKG_DATA_DIR})
install(FILES ${XML_FILES} DESTINATION ${PKGDATADIR})

install(DIRECTORY install/games DESTINATION ${PKG_DATA_DIR})
install(DIRECTORY install/bitmaps DESTINATION ${PKG_DATA_DIR})
install(DIRECTORY install/gl DESTINATION ${PKG_DATA_DIR})
install(DIRECTORY install/ui DESTINATION ${PKG_DATA_DIR}
install(DIRECTORY install/games DESTINATION ${PKGDATADIR})
install(DIRECTORY install/bitmaps DESTINATION ${PKGDATADIR})
install(DIRECTORY install/gl DESTINATION ${PKGDATADIR})
install(DIRECTORY install/ui DESTINATION ${PKGDATADIR}
FILES_MATCHING PATTERN "*.ttf" PATTERN "*.xrc")

# Install locale data
install(DIRECTORY install/i18n/de TYPE LOCALE
FILES_MATCHING PATTERN "*.mo")

# Install scripts
install(DIRECTORY install/scripts DESTINATION ${PKG_DATA_DIR}
install(DIRECTORY install/scripts DESTINATION ${PKGDATADIR}
FILES_MATCHING PATTERN "*.py")
12 changes: 12 additions & 0 deletions config.h.in
Expand Up @@ -5,5 +5,17 @@
/* Project version */
#define PACKAGE_VERSION "@CMAKE_PROJECT_VERSION@"

/* Defined if this is a relocatable build */
#cmakedefine ENABLE_RELOCATION

/* Locale directory */
#define LOCALEDIR "@CMAKE_INSTALL_FULL_LOCALEDIR@"

/* Package library directory (e.g. /usr/lib/darkradiant) */
#cmakedefine PKGLIBDIR "@PKGLIBDIR@"

/* Package data directory (e.g. /usr/share/darkradiant) */
#cmakedefine PKGDATADIR "@PKGDATADIR@"

/* HTML directory (e.g. /usr/share/doc/darkradiant) */
#cmakedefine HTMLDIR "@HTMLDIR@"
32 changes: 19 additions & 13 deletions libs/module/ApplicationContextBase.cpp
Expand Up @@ -32,15 +32,15 @@ std::string ApplicationContextBase::getApplicationPath() const
std::vector<std::string> ApplicationContextBase::getLibraryPaths() const
{
auto libBasePath = os::standardPathWithSlash(getLibraryBasePath());

#if defined(__APPLE__) && defined(DR_MODULES_NEXT_TO_APP)
// Xcode output goes to the application folder right now
return { libBasePath };
#else
return
{
libBasePath + MODULES_DIR,
libBasePath + PLUGINS_DIR
return
{
libBasePath + MODULES_DIR,
libBasePath + PLUGINS_DIR
};
#endif
}
Expand All @@ -50,10 +50,12 @@ std::string ApplicationContextBase::getLibraryBasePath() const
#if defined(__APPLE__)
return _appPath;
#elif defined(POSIX)
# if defined(PKGLIBDIR) && !defined(ENABLE_RELOCATION)
# if defined(PKGLIBDIR)
return PKGLIBDIR;
# else
# elif defined(ENABLE_RELOCATION)
return _appPath + "../lib/darkradiant/";
# else
# error "Either PKGLIBDIR or ENABLE_RELOCATION must be defined"
# endif
#else // !defined(POSIX)
return _appPath;
Expand All @@ -66,20 +68,22 @@ std::string ApplicationContextBase::getRuntimeDataPath() const
// The Resources are in the Bundle folder Contents/Resources/, whereas the
// application binary is located in Contents/MacOS/
std::string path = getApplicationPath() + "../Resources/";

// When launching the app from Xcode, the Resources/ folder
// is next to the binary
if (!fs::exists(path))
{
path = getApplicationPath() + "Resources/";
}

return path;
#elif defined(POSIX)
# if defined(PKGDATADIR) && !defined(ENABLE_RELOCATION)
# if defined(PKGDATADIR)
return std::string(PKGDATADIR) + "/";
# else
# elif defined(ENABLE_RELOCATION)
return _appPath + "../share/darkradiant/";
# else
# error "Either PKGDATADIR or ENABLE_RELOCATION must be defined"
# endif
#else
return getApplicationPath();
Expand All @@ -89,10 +93,12 @@ std::string ApplicationContextBase::getRuntimeDataPath() const
std::string ApplicationContextBase::getHTMLPath() const
{
#if defined(POSIX)
#if defined(HTMLDIR) && !defined(ENABLE_RELOCATION)
#if defined(HTMLDIR)
return std::string(HTMLDIR) + "/";
#else
#elif defined(ENABLE_RELOCATION)
return _appPath + "../share/doc/darkradiant/";
#else
#error "Either HTMLDIR or ENABLE_RELOCATION must be defined"
#endif
#else
// TODO: implement correct path for macOS and Windows
Expand Down

0 comments on commit b3a1f56

Please sign in to comment.