The following is the Makefile output when compiling on MacOS.
~/Downloads/cnake-main โฏ make
gcc -c src/cheese.c -O2 -std=c11 -Wall -Wextra -Werror -pedantic -Wno-deprecated-declarations -o bin/cheese.o
gcc -c src/common.c -O2 -std=c11 -Wall -Wextra -Werror -pedantic -Wno-deprecated-declarations -o bin/common.o
gcc -c src/game.c -O2 -std=c11 -Wall -Wextra -Werror -pedantic -Wno-deprecated-declarations -o bin/game.o
In file included from src/game.c:1:
In file included from src/game.h:17:
src/snake.h:34:62: error: '_Static_assert' with no message is a C2x extension [-Werror,-Wc2x-extensions]
static_assert(SNAKE_TONGUE_MAX_DELAY > SNAKE_TONGUE_MIN_DELAY);
^
, ""
src/game.c:45:27: error: use of undeclared identifier 'buffer'
if (_NSGetExecutablePath(buffer, &size) != 0)
^
src/game.c:53:18: error: use of undeclared identifier 'len'
for (size_t i = len - 1; i > 0; -- i) {
^
3 errors generated.
make: *** [bin/game.o] Error 1
I'm not exactly sure how C/C++ extensions work, but for the error in src/snake.h
just add the empty description parameter. And in the other two errors, your identifiers are renamed. I've written some comments where changes need to be made.
// src/game.c:32
static char *get_exec_folder_path(void) {
char *buf = (char*)malloc(PATH_MAX);
if (buf == NULL)
UNREACHABLE("malloc() fail");
#if defined(PLATFORM_LINUX)
ssize_t len = readlink("/proc/self/exe", buf, PATH_MAX);
if (len != -1)
buf[len] = '\0';
else
strcpy(buf, argv[0]);
#elif defined(PLATFORM_APPLE)
uint32_t size = PATH_MAX;
if (_NSGetExecutablePath(buffer, &size) != 0)
// ^----- should be `buf`
strcpy(buf, argv[0]);
#elif defined(PLATFORM_WINDOWS)
GetModuleFileName(NULL, buf, PATH_MAX);
#elif defined(PLATFORM_UNIX) || defined(PLATFORM_UNKNOWN)
strcpy(buf, argv[0]);
#endif
// v----- type for `i` is different for every platform. Just use what is needed
for (size_t i = len - 1; i > 0; -- i) {
// ^--- is defined for linux, but not mac or windows
if (buf[i] == '/' || buf[i] == '\\') {
buf[i] = '\0';
break;
}
}
return buf;
}
Applied Changes
// src/snake.h:34
static_assert(SNAKE_TONGUE_MAX_DELAY > SNAKE_TONGUE_MIN_DELAY, "");
// src/game.c:32
static char *get_exec_folder_path(void) {
char *buf = (char*)malloc(PATH_MAX);
if (buf == NULL)
UNREACHABLE("malloc() fail");
#if defined(PLATFORM_LINUX)
ssize_t len = readlink("/proc/self/exe", buf, PATH_MAX);
if (len != -1)
buf[len] = '\0';
else
strcpy(buf, argv[0]);
#elif defined(PLATFORM_APPLE)
uint32_t len = PATH_MAX;
if (_NSGetExecutablePath(buf, &len) != 0)
strcpy(buf, argv[0]);
#elif defined(PLATFORM_WINDOWS)
GetModuleFileName(NULL, buf, PATH_MAX);
#else
strcpy(buf, argv[0]);
#endif
// Use the same type that was used store `len` for iterating
#if defined(PLATFORM_LINUX)
ssize_t i = len - 1;
#elif defined(PLATFORM_APPLE)
uint32_t i = len - 1;
#elif defined(PLATFORM_WINDOWS)
// Docs says 'The size of the lpFilename buffer, in TCHARs'.
// I have no idea what that means so I used size_t here.
size_t i = len - 1;
#else
#endif
for (; i > 0; -- i) {
if (buf[i] == '/' || buf[i] == '\\') {
buf[i] = '\0';
break;
}
}
return buf;
}
As a suggestion:
- For writing code for multiple platforms with native APIs, use function pointers. That'll help separate the platform specific code while being able to perform the same actions.
- SDL2 and SDL2_image are dependancies. You should probably say that in the README as a heads up or include it by using
git submodule
s so that interested ones don't have to find and download the packages manually before being able to compile your programs.