Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DEFAULT_ADDITIONAL_DIRS CMake option #659

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
23 changes: 12 additions & 11 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,14 +179,15 @@ cmake --preset linux -DENABLE_LOGGER=ON

**NOTE:** CMake variables, or more technically _CMake cache entries_, will persist in their values until they are explicitly cleared. So, if you set a variable and then run another CMake command _without_ that variable specified, the variable will still be set. Variables must be explicitly unset, or the `builds/` directory cleaned, in order to be cleared.

| Option | Description | Default |
|--------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|
| `CMAKE_BUILD_TYPE` | `Debug` builds are generally larger, slower and contain extra correctness checks that will validate game data and interrupt gameplay when problems are detected.<br>`Release` builds are optimized for size and speed and do not include debugging information, which makes it harder to find problems. | `Debug` |
| `BUILD_EDITOR` | _(Windows-only)_ Build internal editor. | `OFF` |
| `BUILD_TESTING` | Enable testing. Requires GTest. | `OFF` |
| `ENABLE_LOGGER` | Enable logging to the terminal. | `OFF` |
| `ENABLE_MEM_RTL` | Enable Real-time library memory management functions (disable to verbose memory allocations). | `ON` |
| `FORCE_COLORED_OUTPUT` | Always produce ANSI-colored compiler warnings/errors (GCC/Clang only; esp. useful with Ninja). | `OFF` |
| `FORCE_PORTABLE_INSTALL` | Install all files into local directory defined by `CMAKE_INSTALL_PREFIX`. | `ON` |
| `USE_EXTERNAL_PLOG` | Use system plog library. | `OFF` |
| `USE_VCPKG` | Explicitly control whether or not to use vcpkg for dependency resolution. `ON` requires the environment variable `VCPKG_ROOT` to be set. | Determined by the existence of `VCPKG_ROOT` in the environment: If it exists, vcpkg is used. |
| Option | Description | Default |
|---------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------|
| `CMAKE_BUILD_TYPE` | `Debug` builds are generally larger, slower and contain extra correctness checks that will validate game data and interrupt gameplay when problems are detected.<br>`Release` builds are optimized for size and speed and do not include debugging information, which makes it harder to find problems. | `Debug` |
| `BUILD_EDITOR` | _(Windows-only)_ Build internal editor. | `OFF` |
| `BUILD_TESTING` | Enable testing. Requires GTest. | `OFF` |
| `DEFAULT_ADDITIONAL_DIRS` | A list of directories that Descent 3 will use as read-only base directories (see [USAGE.md’s Base directories section](./USAGE.md#base-directories)). This value gets interpreted as a C++ expression, so you’ll need to use C++’s syntax. Here’s an example of a valid value: <pre lang=cpp>`{"C:\\Games\\Descent3\\", "D:\\"}`</pre> | `{}` |
| `ENABLE_LOGGER` | Enable logging to the terminal. | `OFF` |
| `ENABLE_MEM_RTL` | Enable Real-time library memory management functions (disable to verbose memory allocations). | `ON` |
| `FORCE_COLORED_OUTPUT` | Always produce ANSI-colored compiler warnings/errors (GCC/Clang only; esp. useful with Ninja). | `OFF` |
| `FORCE_PORTABLE_INSTALL` | Install all files into local directory defined by `CMAKE_INSTALL_PREFIX`. | `ON` |
| `USE_EXTERNAL_PLOG` | Use system plog library. | `OFF` |
| `USE_VCPKG` | Explicitly control whether or not to use vcpkg for dependency resolution. `ON` requires the environment variable `VCPKG_ROOT` to be set. | Determined by the existence of `VCPKG_ROOT` in the environment: If it exists, vcpkg is used. |
3 changes: 3 additions & 0 deletions Descent3/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1414,6 +1414,9 @@ void InitIOSystems(bool editor) {
ddio_SetWorkingDir(writable_base_directory.u8string().c_str());
cf_AddBaseDirectory(writable_base_directory);

// Set the default base directories
cf_AddDefaultBaseDirectories();

// Set any additional base directories
auto additionaldirarg = 0;
while (0 != (additionaldirarg = FindArg("-additionaldir", additionaldirarg))) {
Expand Down
8 changes: 5 additions & 3 deletions USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,18 +92,19 @@ Descent 3 has two types of base directories:
- The writable base directory can contain both read-write files and read-only files. There is only one writeable base directory. By default, the writable base directory gets set to the current working directory.
- The read-only base directories can only contain read-only files. There can be any number of read-only base directories. By default, Descent 3 uses zero read-only base directories.

You can set the writable base directory and the list of read-only base directories using the `-setdir`, `-useexedir` and `-additionaldir` command-line options (see [the next section](#command-line-options)).
You can set the writable base directory and the list of read-only base directories using the `-setdir`, `-useexedir` and `-additionaldir` command-line options (see [the next section](#command-line-options)). Descent 3 also has a list of default read-only base directories. Normally, the list of default read-only base directories is empty, but you can change it by using the `DEFAULT_ADDITIONAL_DIRS` CMake option when compiling Descent 3 (see [BUILD.md’s Build Options section](./BUILD.md#build-options)).

When Descent 3 tries to find a read-only file, then it will look through the list of base directories in this order:

- the last read-only base directory that was specified on the command-line,
- the second-to-last read-only base directory that was specified on the command-line,
- the third-to-last read-only base directory that was specified on the command-line,
- …
- the first read-only base directory that was specified on the command-line and, finally,
- the first read-only base directory that was specified on the command-line,
- all of the items on the `DEFAULT_ADDITIONAL_DIRS` list in reverse order, and, finally,
- the writable base directory.

Files that are in base directories that are higher on that list will override files that are in base directories that are lower on that list. For example, lets say that you run Descent 3 like this:
Files that are in base directories that are higher on that list will override files that are in base directories that are lower on that list. For example, lets say that the `DEFAULT_ADDITIONAL_DIRS` list is empty and that you run Descent 3 like this:

```
Descent3 -setdir /home/user/my-writable-base-directory -additionaldir /home/user/my-read-only-base-directory
Expand Down Expand Up @@ -527,6 +528,7 @@ The following command-line options are available in Descent 3. You can set comma

**Description:** Tells Descent 3 to use the directory in which the executable is located as the writable base directory.


### Other Options

- `-logfile`
Expand Down
11 changes: 10 additions & 1 deletion cfile/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
set(HEADERS
cfile.h
default_base_directories.h
hogfile.h
inffile.h)
set(CPPS
Expand All @@ -8,7 +9,15 @@ set(CPPS
inffile.cpp
)

add_library(cfile STATIC ${HEADERS} ${CPPS})
set(DEFAULT_ADDITIONAL_DIRS "{}" CACHE STRING "A list of directories that Descent 3 will use as read-only base directories.")
set(DBD_CPP ${CMAKE_CURRENT_BINARY_DIR}/default_base_directories.cpp)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/default_base_directories.cpp.in
${DBD_CPP}
@ONLY
)

add_library(cfile STATIC ${HEADERS} ${CPPS} ${DBD_CPP})
target_link_libraries(cfile PRIVATE
ddebug
ddio
Expand Down
12 changes: 12 additions & 0 deletions cfile/cfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "byteswap.h"
#include "crossplat.h"
#include "cfile.h"
#include "default_base_directories.h"
#include "ddio.h"
#include "hogfile.h" //info about library file
#include "log.h"
Expand Down Expand Up @@ -78,6 +79,17 @@
// The message for unexpected end of file
const char *eof_error = "Unexpected end of file";

/* The user can specify a list of default read-only base directories by setting
* the -DDEFAULT_ADDITIONAL_DIRS CMake option. This function adds those base
* directories to the list of base directories that the game is currently
* using.
*/
void cf_AddDefaultBaseDirectories() {
for (const auto &base_directory : Default_read_only_base_directories) {
cf_AddBaseDirectory(base_directory);
}
}

/* This function should be called at least once before you use anything else
* from this module.
*/
Expand Down Expand Up @@ -126,7 +138,7 @@
// Search component in search_path
auto const &it = std::filesystem::directory_iterator(search_path);

auto found = std::find_if(it, end(it), [&search_file, &search_path, &result](const auto& dir_entry) {

Check warning on line 141 in cfile/cfile.cpp

View workflow job for this annotation

GitHub Actions / macOS-Intel, Debug

lambda capture 'search_path' is not used [-Wunused-lambda-capture]

Check warning on line 141 in cfile/cfile.cpp

View workflow job for this annotation

GitHub Actions / macOS-Intel, Debug

lambda capture 'result' is not used [-Wunused-lambda-capture]

Check warning on line 141 in cfile/cfile.cpp

View workflow job for this annotation

GitHub Actions / macOS-Intel, Release

lambda capture 'search_path' is not used [-Wunused-lambda-capture]

Check warning on line 141 in cfile/cfile.cpp

View workflow job for this annotation

GitHub Actions / macOS-Intel, Release

lambda capture 'result' is not used [-Wunused-lambda-capture]
return stricmp(dir_entry.path().filename().u8string().c_str(), search_file.u8string().c_str()) == 0;
});

Expand All @@ -145,7 +157,7 @@

std::vector<std::filesystem::path> cf_LocatePathMultiplePathsHelper(const std::filesystem::path &relative_path,
bool stop_after_first_result) {
ASSERT(("realative_path should be a relative path.", relative_path.is_relative()));

Check warning on line 160 in cfile/cfile.cpp

View workflow job for this annotation

GitHub Actions / macOS-Intel, Debug

left operand of comma operator has no effect [-Wunused-value]
std::vector<std::filesystem::path> return_value = { };
for (auto base_directories_iterator = Base_directories.rbegin();
base_directories_iterator != Base_directories.rend();
Expand Down Expand Up @@ -386,7 +398,7 @@

// open the file for reading
FILE *fp;
int r;

Check warning on line 401 in cfile/cfile.cpp

View workflow job for this annotation

GitHub Actions / macOS-Intel, Release

variable 'r' set but not used [-Wunused-but-set-variable]
// See if there's an available FILE
if (lib->file) {
fp = lib->file;
Expand Down
7 changes: 7 additions & 0 deletions cfile/cfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ extern std::vector<std::filesystem::path> Base_directories;
*/
void cf_AddBaseDirectory(const std::filesystem::path &base_directory);

/* The user can specify a list of default read-only base directories by setting
* the -DDEFAULT_ADDITIONAL_DIRS CMake option. This function adds those base
* directories to the list of base directories that the game is currently
* using.
*/
void cf_AddDefaultBaseDirectories();

/* After you call this function, you must call cf_AddBaseDirectory() at least
* once before you use anything else from this module.
*/
Expand Down
23 changes: 23 additions & 0 deletions cfile/default_base_directories.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Descent 3
* Copyright (C) 2024 Descent Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <filesystem>
#include <initializer_list>

#include "default_base_directories.h"

const std::initializer_list<std::filesystem::path> Default_read_only_base_directories = @DEFAULT_ADDITIONAL_DIRS@;
26 changes: 26 additions & 0 deletions cfile/default_base_directories.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Descent 3
* Copyright (C) 2024 Descent Developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DEFAULT_ADDITIONAL_DIRECTORIES_H
#define DEFAULT_ADDITIONAL_DIRECTORIES_H

#include <filesystem>
#include <initializer_list>

extern const std::initializer_list<std::filesystem::path> Default_read_only_base_directories;

#endif
Loading