Build libpakrd with cmake instead of using it as prebuilt library

This commit is contained in:
abdelrahman committed 2023-11-05 19:15:56 +00:00
1 parent c5dd826c66
commit 2de3e9b4df
12 files changed
+442 -15

No files matched your search

+1 -9
View File
@@ -52,10 +52,6 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
SDL2_ttf SDL2_ttf
) )
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/intern/pakrd/libpakrd.so ${OUTPUT_BASE_DIR}/${CMAKE_BUILD_TYPE}/lib
)
install(FILES install(FILES
include/aliases.h include/aliases.h
include/constants.h include/constants.h
@@ -71,11 +67,6 @@ install(FILES
CONFIGURATIONS Release CONFIGURATIONS Release
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
) )
install(FILES
${CMAKE_CURRENT_SOURCE_DIR}/intern/pakrd/libpakrd.so
CONFIGURATIONS Release
DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(TARGETS ${PROJECT_NAME} install(TARGETS ${PROJECT_NAME}
CONFIGURATIONS Release CONFIGURATIONS Release
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
@@ -85,3 +76,4 @@ install(TARGETS ${PROJECT_NAME}
# SUB-DIRECTORIES # SUB-DIRECTORIES
add_subdirectory(extern) add_subdirectory(extern)
add_subdirectory(intern)
+3
View File
@@ -0,0 +1,3 @@
cmake_minimum_required(VERSION 3.10)
add_subdirectory(pakrd)
+46
View File
@@ -0,0 +1,46 @@
cmake_minimum_required(VERSION 3.17)
project(pakrd)
# VARIABLES
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(BUILD_SHARED_LIBS ON)
if(CMAKE_HOST_WIN32)
# Export both *.lib and *.dll on Windows
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()
set(CMAKE_INSTALL_RPATH "$ORIGIN;$ORIGIN/../lib")
# TARGETS
add_library(${PROJECT_NAME} SHARED
src/cpath.c
src/darr.c
src/io.c
src/pak.c
)
target_include_directories(${PROJECT_NAME} PUBLIC
${CMAKE_CURRENT_BINARY_DIR}
include
../../include/
)
target_link_libraries(${PROJECT_NAME} PUBLIC SDL2)
install(FILES
include/cpath.h
include/darr.h
include/io.h
include/pak.h
CONFIGURATIONS Release
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(TARGETS ${PROJECT_NAME}
CONFIGURATIONS Release
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
+18
View File
@@ -0,0 +1,18 @@
#ifndef PATH_UTILS_H
#define PATH_UTILS_H
#include "aliases.h"
#define NUMPARTS(...) \
(sizeof((const char *[]){"", __VA_ARGS__}) / sizeof(const char *) - 1)
#define JOIN_PATH(DST, ...) join_path(DST, NUMPARTS(__VA_ARGS__), __VA_ARGS__)
void join_path(char *dst, u64 count, ...);
#define DIRNAME(DST, PATH) dirup(DST, 1, PATH)
#define DIRUP(DST, COUNT, PATH) dirup(DST, COUNT, PATH)
void dirup(char *dst, u64 levels, const char *path);
#endif // !PATH_UTILS_H
+24
View File
@@ -0,0 +1,24 @@
#ifndef D_ARR_H
#define D_ARR_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "aliases.h"
#include <stdbool.h>
#define INVALID_IDX -1
typedef struct darr darr_t;
bool darr_init(darr_t **darr);
i64 darr_add(darr_t **darr, void *item);
void **darr_get_items(darr_t *darr);
void darr_free(darr_t **darr);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !D_ARR_H
+25
View File
@@ -0,0 +1,25 @@
#ifndef IO_H
#define IO_H
#include "SDL_rwops.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include "aliases.h"
#include <linux/limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#define STREQ(S1, S2) (strcmp(S1, S2) == 0)
#define STRNEQ(S1, S2, COUNT) (strncmp(S1, S2, COUNT) == 0)
u64 get_file_length(SDL_RWops *io);
void read_entire_file(void *dst, SDL_RWops *io);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !IO_H
@@ -30,11 +30,6 @@ typedef struct {
u64 patch; u64 patch;
} pak_ver_t; } pak_ver_t;
typedef struct {
u64 size;
u8 data[];
} pak_entry_t;
typedef struct { typedef struct {
u64 magic; u64 magic;
pak_ver_t version; pak_ver_t version;
@@ -43,7 +38,6 @@ typedef struct {
typedef struct asset_pack asset_pack_t; typedef struct asset_pack asset_pack_t;
bool create_asset_pack(const char *dirpath, const char *output);
asset_pack_t *load_asset_pack(const char *filepath); asset_pack_t *load_asset_pack(const char *filepath);
buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename); buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename);
void close_pack_file(buf_t **buf); void close_pack_file(buf_t **buf);
Binary file not shown.
+78
View File
@@ -0,0 +1,78 @@
#include "cpath.h"
#include "aliases.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#if defined(__unix__) || defined(__APPLE__) || defined(__ANDROID__)
INTERNAL char path_sep = '/';
#elif defined(_WIN32) || defined(_WIN64)
INTERNAL char path_sep = '\\';
#endif
void join_root_and_leaf(const char *root, const char *leaf, char *dst);
void join_path(char *dst, u64 count, ...) {
va_list args;
va_start(args, count);
for (u64 i = 0; i < count; ++i) {
join_root_and_leaf(dst, va_arg(args, const char *), dst);
}
va_end(args);
}
void dirup(char *dst, u64 levels, const char *path) {
if (levels < 1) {
return;
}
u64 end_index = 0;
u64 sep_count = 0;
u64 length = strlen(path);
if (path[length - 1] == path_sep) {
--length;
}
for (u64 i = length - 1; i >= 0; --i) {
if (path[i] == path_sep) {
++sep_count;
end_index = i;
if (sep_count == levels) {
break;
}
}
}
if (sep_count < levels) {
end_index = 0;
}
strncpy(dst, path, end_index);
}
void join_root_and_leaf(const char *root, const char *leaf, char *dst) {
u64 root_length = strlen(root);
u64 root_end = root_length - 1;
u64 leaf_length = strlen(leaf);
u64 leaf_start = 0;
if (root[root_end] == path_sep) {
--root_end;
}
if (leaf[leaf_start] == path_sep) {
++leaf_start;
}
memcpy(dst, root, ++root_end);
dst[root_end] = path_sep;
memcpy(&(dst[++root_end]), &(leaf[leaf_start]), leaf_length - leaf_start);
}
+62
View File
@@ -0,0 +1,62 @@
#include "darr.h"
#include "aliases.h"
#include <stdlib.h>
#include <string.h>
#define BASE_CAPACITY 2048
struct darr {
u64 count;
u64 capacity;
void *items[];
};
bool darr_init(darr_t **darr) {
u64 size = sizeof(darr_t) + sizeof(void *) * BASE_CAPACITY;
*darr = malloc(size);
if (!(*darr)) {
return false;
}
memset((void *)(*darr), 0, size);
(*darr)->capacity = BASE_CAPACITY;
return true;
}
i64 darr_add(darr_t **darr, void *item) {
if ((*darr)->count == (*darr)->capacity) {
u64 new_size =
sizeof(darr_t) + sizeof(void *) * ((*darr)->capacity + BASE_CAPACITY);
darr_t *orig = *darr;
*darr = realloc(*darr, new_size);
if (!(*darr)) {
*darr = orig;
return INVALID_IDX;
}
(*darr)->capacity += BASE_CAPACITY;
}
u64 index = (*darr)->count;
(*darr)->items[((*darr)->count)++] = item;
return index;
}
void **darr_get_items(darr_t *darr) { return darr->items; }
void darr_free(darr_t **darr) {
if (!(*darr)) {
return;
}
free(*darr);
*darr = NULL;
}
+37
View File
@@ -0,0 +1,37 @@
#include "io.h"
#include "SDL_rwops.h"
#include "aliases.h"
#include "cpath.h"
#include <dirent.h>
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#define MAX_DIR_DEPTH PATH_MAX
u64 get_file_length(SDL_RWops *io) {
u64 current = SDL_RWtell(io);
SDL_RWseek(io, 0, SEEK_END);
u64 length = SDL_RWtell(io);
// Restore the cursor position to where it was
SDL_RWseek(io, current, SEEK_SET);
return length;
}
void read_entire_file(void *dst, SDL_RWops *io) {
u64 length = get_file_length(io);
u64 current = SDL_RWtell(io);
SDL_RWseek(io, 0, SEEK_SET);
SDL_RWread(io, dst, length, 1);
SDL_RWseek(io, current, SEEK_SET);
}
+148
View File
@@ -0,0 +1,148 @@
#include "pak.h"
#include "SDL_rwops.h"
#include "aliases.h"
#include "darr.h"
#include "io.h"
#include <linux/limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PAK_MAGIC 0x4B41502054535341
#define PAK_MAJOR 1
#define PAK_MINOR 0
#define PAK_PATCH 0
#define PAK_EXT ".pak"
struct asset_pack {
pak_t header;
SDL_RWops *io;
u8 *toc;
toc_entry_t **toc_entries;
u64 assets_length;
u64 assets_offset;
};
asset_pack_t *load_asset_pack(const char *filepath) {
char full_path[PATH_MAX] = {0};
#ifdef __ANDROID__
strcpy(full_path, filepath);
#else
realpath(filepath, full_path);
#endif /* ifdef __ANDROID__ */
asset_pack_t *pack = (asset_pack_t *)malloc(sizeof(asset_pack_t));
if (!pack) {
return NULL;
}
memset((void *)pack, 0, sizeof(asset_pack_t));
pack->io = SDL_RWFromFile(full_path, "rb");
if (!(pack->io)) {
close_asset_pack(&pack);
return NULL;
}
u64 file_size = get_file_length(pack->io);
SDL_RWread(pack->io, (void *)(&(pack->header)), sizeof(pak_t), 1);
u64 toc_size = pack->header.toc.size;
pack->toc = (u8 *)malloc(toc_size);
if (!(pack->toc)) {
close_asset_pack(&pack);
return NULL;
}
SDL_RWread(pack->io, (void *)(pack->toc), toc_size, 1);
u64 entries_size = sizeof(toc_entry_t *) * pack->header.toc.count;
pack->toc_entries = (toc_entry_t **)malloc(entries_size);
if (!(pack->toc_entries)) {
close_asset_pack(&pack);
return NULL;
}
toc_entry_t *next = (toc_entry_t *)pack->toc;
for (u64 i = 0; i < pack->header.toc.count; ++i) {
pack->toc_entries[i] = next;
next = (toc_entry_t *)((u8 *)next + sizeof(toc_entry_t) + next->length);
}
pack->assets_offset = SDL_RWtell(pack->io);
pack->assets_length = file_size - pack->assets_offset;
return pack;
}
buf_t *read_file_from_pack(asset_pack_t *pack, const char *filename) {
toc_entry_t *entry = NULL;
buf_t *output = NULL;
for (u64 i = 0; i < pack->header.toc.count; ++i) {
entry = pack->toc_entries[i];
if (STRNEQ(filename, entry->name, entry->length)) {
SDL_RWseek(pack->io, pack->assets_offset + entry->offset, SEEK_SET);
u64 size = 0;
SDL_RWread(pack->io, &size, sizeof(u64), 1);
output = (buf_t *)malloc(sizeof(buf_t) + size);
if (!output) {
break;
}
output->size = size;
SDL_RWread(pack->io, &(output->data), size, 1);
break;
}
}
return output;
}
void close_pack_file(buf_t **buf) {
buf_t *b = *buf;
if (!b || b->size == 0) {
return;
}
free(*buf);
*buf = NULL;
}
void close_asset_pack(asset_pack_t **pack) {
if (!(*pack)) {
return;
}
if ((*pack)->toc_entries) {
free((*pack)->toc_entries);
}
if ((*pack)->toc) {
free((*pack)->toc);
}
if ((*pack)->io) {
SDL_RWclose((*pack)->io);
}
free(*pack);
*pack = NULL;
}