* gputils: Set language standard to gnu17
The latest version of GCC in the mingw tool-chain is configured to build
using C23 by default, however, gputils is not yet compatible with this
language standard.
gputils has the following issues:
- It declares a function prototype for getenv() without arguments. In
previous C language standards, this meant that the argument list was
unspecified, and so calling getenv with a string argument was valid.
This is no longer the case in C23.
- It declares and enum: "gp_boolean", containing two values: "true"
and "false". These names are now reserved words in C23.
This patch corrects these issues by setting the "-std=gnu17" in the
CFLAGS.
* gputils: Allow default search paths
By default, gputils disables the default search paths for includes and
libraries on Windows on the assumption that a portable build is
required.
As a result, gpasm fails to assemble simple files, for example:
include "p18lf8723.inc"
The error can be avoided by adding a "-I" option to the gpasm command
line or with the GPUTILS_HEADER_PATH environment variable, however this
is inconvenient for users. The lack of default include path also breaks
the configure script of sdcc, which probes for device support by
attempting to assemble a file similar to the example for every device.
This patch solves the issue by adding a patch to gputils, which deduces
the installation prefix based on the executable path, and uses this to
construct HEADER_PATH (as well as LKR_PATH and LIB_PATH).
The fix can be seen by running "gpasm -h". With the fix applied, text
similar to the following will be printed:
Default header file path C:\msys64\mingw64\share\gputils\header
179 lines
4.2 KiB
Diff
179 lines
4.2 KiB
Diff
diff -urN a/libgputils/gpsystem.c b/libgputils/gpsystem.c
|
|
--- a/libgputils/gpsystem.c 2017-05-07 02:45:29.000000000 -0700
|
|
+++ b/libgputils/gpsystem.c 2025-12-01 09:21:33.786109600 -0800
|
|
@@ -42,6 +42,117 @@
|
|
|
|
/* initialize the library */
|
|
|
|
+#ifdef HAVE_WINDOWS_H
|
|
+static WCHAR*
|
|
+win32_get_exe_path(int *len) {
|
|
+ int buffer_size = MAX_PATH;
|
|
+ WCHAR *path = NULL;
|
|
+
|
|
+ while (buffer_size < 32868) {
|
|
+ path = malloc(buffer_size * sizeof(WCHAR));
|
|
+
|
|
+ const DWORD ret = GetModuleFileNameW(NULL, path, buffer_size);
|
|
+ if (ret) {
|
|
+ *len = ret;
|
|
+ return path;
|
|
+ }
|
|
+
|
|
+ free(path);
|
|
+
|
|
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ buffer_size *= 2;
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
+static int
|
|
+win32_dirname(const WCHAR *path, int *len) {
|
|
+ int off = *len;
|
|
+
|
|
+ if (path[off] == L'\\' && --off < 0) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ for (; off >= 0; off--) {
|
|
+ if (path[off] == L'\\') {
|
|
+ *len = off;
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+static WCHAR*
|
|
+win32_get_prefix(int *len) {
|
|
+ int path_len;
|
|
+ WCHAR *const path = win32_get_exe_path(&path_len);
|
|
+ if (!path) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (win32_dirname(path, &path_len) != 0 ||
|
|
+ win32_dirname(path, &path_len) != 0) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ *len = path_len;
|
|
+
|
|
+ return path;
|
|
+}
|
|
+
|
|
+static const WCHAR*
|
|
+win32_join_path_w(const WCHAR *base, int base_len, const WCHAR *append,
|
|
+ int append_len, int *path_len) {
|
|
+ const int len = base_len + 1 + append_len;
|
|
+ WCHAR *const buf = malloc((len + 1) * sizeof(WCHAR));
|
|
+ if (!buf) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ memcpy(buf, base, base_len * sizeof(WCHAR));
|
|
+ buf[base_len] = L'\\';
|
|
+ memcpy(buf + 1 + base_len, append, append_len * sizeof(WCHAR));
|
|
+ buf[len] = 0;
|
|
+
|
|
+ *path_len = len;
|
|
+
|
|
+ return buf;
|
|
+}
|
|
+
|
|
+static const char*
|
|
+win32_get_default_path(const WCHAR *prefix, int prefix_len,
|
|
+ const WCHAR *append, int append_len) {
|
|
+ int path_len;
|
|
+ const WCHAR *const w_path =
|
|
+ win32_join_path_w(prefix, prefix_len, append, append_len, &path_len);
|
|
+ if (!w_path) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ const int buf_len =
|
|
+ WideCharToMultiByte(CP_UTF8, 0, w_path, path_len + 1, NULL, 0, NULL, NULL);
|
|
+
|
|
+ char *const buf = malloc(buf_len);
|
|
+ if (!buf) {
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ if (WideCharToMultiByte(CP_UTF8, 0, w_path, path_len + 1, buf, buf_len, NULL,
|
|
+ NULL) == 0) {
|
|
+ free(buf);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ return buf;
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
void
|
|
gp_init(void)
|
|
{
|
|
@@ -52,18 +163,47 @@
|
|
gp_lkr_path = getenv("GPUTILS_LKR_PATH");
|
|
gp_lib_path = getenv("GPUTILS_LIB_PATH");
|
|
|
|
- #ifndef HAVE_DOS_BASED_FILE_SYSTEM
|
|
- if (gp_header_path == NULL) {
|
|
- gp_header_path = GP_Strdup(HEADER_PATH);
|
|
- }
|
|
- if (gp_lkr_path == NULL) {
|
|
- gp_lkr_path = GP_Strdup(LKR_PATH);
|
|
- }
|
|
- if (gp_lib_path == NULL) {
|
|
- gp_lib_path = GP_Strdup(LIB_PATH);
|
|
+ #ifdef HAVE_WINDOWS_H
|
|
+ if (gp_header_path == NULL ||
|
|
+ gp_lkr_path == NULL ||
|
|
+ gp_lib_path == NULL) {
|
|
+ int prefix_len;
|
|
+ WCHAR *const prefix = win32_get_prefix(&prefix_len);
|
|
+
|
|
+ if (prefix) {
|
|
+ static const WCHAR header_dir[] = L"share\\gputils\\header";
|
|
+ static const int header_dir_len =
|
|
+ sizeof(header_dir) / sizeof(header_dir[0]) - 1;
|
|
+ gp_header_path = win32_get_default_path(
|
|
+ prefix, prefix_len, header_dir, header_dir_len);
|
|
+
|
|
+ static const WCHAR lkr_dir[] = L"share\\gputils\\lkr";
|
|
+ static const int lkr_dir_len =
|
|
+ sizeof(lkr_dir) / sizeof(lkr_dir[0]) - 1;
|
|
+ gp_lkr_path = win32_get_default_path(
|
|
+ prefix, prefix_len, lkr_dir, lkr_dir_len);
|
|
+
|
|
+ static const WCHAR lib_dir[] = L"share\\gputils\\lib";
|
|
+ static const int lib_dir_len =
|
|
+ sizeof(lib_dir) / sizeof(lib_dir[0]) - 1;
|
|
+ gp_lib_path = win32_get_default_path(
|
|
+ prefix, prefix_len, lib_dir, lib_dir_len);
|
|
+
|
|
+ free(prefix);
|
|
+ }
|
|
}
|
|
#endif
|
|
|
|
+ if (gp_header_path == NULL) {
|
|
+ gp_header_path = GP_Strdup(HEADER_PATH);
|
|
+ }
|
|
+ if (gp_lkr_path == NULL) {
|
|
+ gp_lkr_path = GP_Strdup(LKR_PATH);
|
|
+ }
|
|
+ if (gp_lib_path == NULL) {
|
|
+ gp_lib_path = GP_Strdup(LIB_PATH);
|
|
+ }
|
|
+
|
|
#else
|
|
gp_header_path = NULL;
|
|
gp_lkr_path = NULL;
|