From 002535e0a91ac6e67466eac9049974090c765984 Mon Sep 17 00:00:00 2001 From: kazu Date: Wed, 8 May 2024 02:11:15 +0000 Subject: [PATCH] better build script for windows git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@121 0f02c867-ac3d-714e-8a88-971ba1f6efcf --- GNUmakefile | 3 +- Makefile | 3 +- README | 2 + Serenade/Makefile | 2 +- Serenade/interpreter.c | 2 + Tool/config.c | 2 + WinBuild/build.bat | 7 + WinBuild/dirent.h | 584 +++++++++++++++++++++++++++++++++++++++++ WinBuild/winbuild.c | 111 ++++++++ build.bat | 1 + 10 files changed, 714 insertions(+), 3 deletions(-) create mode 100644 WinBuild/build.bat create mode 100644 WinBuild/dirent.h create mode 100644 WinBuild/winbuild.c diff --git a/GNUmakefile b/GNUmakefile index 47386fd..f02e5ac 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -14,6 +14,7 @@ CFLAGS = -std=c99 -fPIC -g `./Tool/config cflags $(TARGET)` LDFLAGS = LIBS = `./Tool/config libs $(TARGET)` EXTRA_OBJS = `./Tool/config objs $(TARGET)` +OBJS = `./Tool/config reqobjs $(TARGET)` SUFFIX = SUFFIX_SO = .so PREFIX_SO = lib @@ -35,7 +36,7 @@ all: ./Tool ./config.h ./Tool/config ./Serenade $(MAKE) -C ./Tool CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" SUFFIX="$(SUFFIX)" config ./Serenade:: - $(MAKE) -C ./Serenade CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" SUFFIX="$(SUFFIX)" EXTRA_OBJS="$(EXTRA_OBJS)" SUFFIX_SO="$(SUFFIX_SO)" PREFIX_SO="$(PREFIX_SO)" + $(MAKE) -C ./Serenade CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" SUFFIX="$(SUFFIX)" EXTRA_OBJS="$(EXTRA_OBJS)" OBJS="$(OBJS)" SUFFIX_SO="$(SUFFIX_SO)" PREFIX_SO="$(PREFIX_SO)" clean: $(MAKE) -C ./Tool clean diff --git a/Makefile b/Makefile index 66697eb..f2791ed 100644 --- a/Makefile +++ b/Makefile @@ -8,6 +8,7 @@ CFLAGS = -std=c99 -fPIC -g `./Tool/config cflags $(TARGET)` LDFLAGS = LIBS = `./Tool/config libs $(TARGET)` EXTRA_OBJS = `./Tool/config objs $(TARGET)` +OBJS = `./Tool/config reqobjs $(TARGET)` SUFFIX = SUFFIX_SO = .so PREFIX_SO = lib @@ -31,7 +32,7 @@ all: ./Tool ./config.h ./Tool/config ./Serenade ./Tool/configgen $@ ./Serenade:: - $(MAKE) -C ./Serenade CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" SUFFIX="$(SUFFIX)" EXTRA_OBJS="$(EXTRA_OBJS)" SUFFIX_SO="$(SUFFIX_SO)" PREFIX_SO="$(PREFIX_SO)" + $(MAKE) -C ./Serenade CC="$(CC)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" LIBS="$(LIBS)" SUFFIX="$(SUFFIX)" EXTRA_OBJS="$(EXTRA_OBJS)" OBJS="$(OBJS)" SUFFIX_SO="$(SUFFIX_SO)" PREFIX_SO="$(PREFIX_SO)" clean: $(MAKE) -C ./Tool clean diff --git a/README b/README index 7f5064d..f0da6e5 100644 --- a/README +++ b/README @@ -1,5 +1,7 @@ LISP Dialect +Thanks for WinBuild\dirent.h, https://github.com/win32ports/dirent_h + ____________ | | | | diff --git a/Serenade/Makefile b/Serenade/Makefile index 867d9bd..c10144d 100644 --- a/Serenade/Makefile +++ b/Serenade/Makefile @@ -1,6 +1,6 @@ # $Id$ -SERENADE_OBJS = parser.o util.o run.o interpreter.o $(EXTRA_OBJS) +SERENADE_OBJS = $(OBJS) $(EXTRA_OBJS) .PHONY: all clean .SUFFIXES: .o .c diff --git a/Serenade/interpreter.c b/Serenade/interpreter.c index 643e41c..ef8d8c6 100644 --- a/Serenade/interpreter.c +++ b/Serenade/interpreter.c @@ -357,6 +357,7 @@ struct sn_interpreter_kv* sn_set_variable(struct sn_interpreter* sn, const char* sn->variables[i + 1] = NULL; return sn->variables[i]; } + return NULL; } struct sn_interpreter_kv* sn_set_handler(struct sn_interpreter* sn, const char* name, struct sn_generic* (*handler)(struct sn_interpreter* sn, int, struct sn_generic**)) { @@ -374,6 +375,7 @@ struct sn_interpreter_kv* sn_set_handler(struct sn_interpreter* sn, const char* set->handler = handler; return set; } + return NULL; } int sn_eval(struct sn_interpreter* sn, char* data, unsigned long long len) { diff --git a/Tool/config.c b/Tool/config.c index 4dc3077..489dcdf 100644 --- a/Tool/config.c +++ b/Tool/config.c @@ -35,6 +35,8 @@ int main(int argc, char** argv) { } #endif printf("\n"); + } else if(strcmp(argv[1], "reqobjs") == 0){ + printf("interpreter.o main.o parser.o run.o util.o\n"); } else if(strcmp(argv[1], "objs") == 0) { #ifdef HAS_FFI_SUPPORT printf("ffi_binding.o "); diff --git a/WinBuild/build.bat b/WinBuild/build.bat new file mode 100644 index 0000000..c20509f --- /dev/null +++ b/WinBuild/build.bat @@ -0,0 +1,7 @@ +@echo off +REM $Id$ +del winbuild.exe +REM Change as you want +call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat" +cl /Fe:winbuild.exe winbuild.c +winbuild.exe \ No newline at end of file diff --git a/WinBuild/dirent.h b/WinBuild/dirent.h new file mode 100644 index 0000000..de75def --- /dev/null +++ b/WinBuild/dirent.h @@ -0,0 +1,584 @@ +/* +MIT License +Copyright (c) 2019 win32ports +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#pragma once + +#ifndef __DIRENT_H_9DE6B42C_8D0C_4D31_A8EF_8E4C30E6C46A__ +#define __DIRENT_H_9DE6B42C_8D0C_4D31_A8EF_8E4C30E6C46A__ + +#ifndef _WIN32 + +#pragma message("this dirent.h implementation is for Windows only!") + +#else /* _WIN32 */ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#include +#include +#include + +#include + +#include + +#ifdef _MSC_VER +#pragma comment(lib, "Shlwapi.lib") +#endif + +#ifndef NAME_MAX +#define NAME_MAX 260 +#endif /* NAME_MAX */ + +#ifndef DT_UNKNOWN +#define DT_UNKNOWN 0 +#endif /* DT_UNKNOWN */ + +#ifndef DT_FIFO +#define DT_FIFO 1 +#endif /* DT_FIFO */ + +#ifndef DT_CHR +#define DT_CHR 2 +#endif /* DT_CHR */ + +#ifndef DT_DIR +#define DT_DIR 4 +#endif /* DT_DIR */ + +#ifndef DT_BLK +#define DT_BLK 6 +#endif /* DT_BLK */ + +#ifndef DT_REG +#define DT_REG 8 +#endif /* DT_REF */ + +#ifndef DT_LNK +#define DT_LNK 10 +#endif /* DT_LNK */ + +#ifndef DT_SOCK +#define DT_SOCK 12 +#endif /* DT_SOCK */ + +#ifndef DT_WHT +#define DT_WHT 14 +#endif /* DT_WHT */ + +#ifndef _DIRENT_HAVE_D_NAMLEN +#define _DIRENT_HAVE_D_NAMLEN 1 +#endif /* _DIRENT_HAVE_D_NAMLEN */ + +#ifndef _DIRENT_HAVE_D_RECLEN +#define _DIRENT_HAVE_D_RECLEN 1 +#endif /* _DIRENT_HAVE_D_RECLEN */ + +#ifndef _DIRENT_HAVE_D_OFF +#define _DIRENT_HAVE_D_OFF 1 +#endif /* _DIRENT_HAVE_D_OFF */ + +#ifndef _DIRENT_HAVE_D_TYPE +#define _DIRENT_HAVE_D_TYPE 1 +#endif /* _DIRENT_HAVE_D_TYPE */ + +#ifndef NTFS_MAX_PATH +#define NTFS_MAX_PATH 32768 +#endif /* NTFS_MAX_PATH */ + +#ifndef FSCTL_GET_REPARSE_POINT +#define FSCTL_GET_REPARSE_POINT 0x900a8 +#endif /* FSCTL_GET_REPARSE_POINT */ + +#ifndef FILE_NAME_NORMALIZED +#define FILE_NAME_NORMALIZED 0 +#endif /* FILE_NAME_NORMALIZED */ + +typedef void* DIR; + +typedef struct ino_t +{ + unsigned long long serial; + unsigned char fileid[16]; +} __ino_t; + +struct dirent +{ + __ino_t d_ino; + off_t d_off; + unsigned short d_reclen; + unsigned char d_namelen; + unsigned char d_type; + char d_name[NAME_MAX]; +}; + +struct __dir +{ + struct dirent* entries; + intptr_t fd; + long int count; + long int index; +}; + +static int closedir(DIR* dirp) +{ + struct __dir* data = NULL; + if (!dirp) { + errno = EBADF; + return -1; + } + data = (struct __dir*) dirp; + CloseHandle((HANDLE)data->fd); + free(data->entries); + free(data); + return 0; +} + +static void __seterrno(int value) +{ +#ifdef _MSC_VER + _set_errno(value); +#else /* _MSC_VER */ + errno = value; +#endif /* _MSC_VER */ +} + +static int __islink(const wchar_t * name, char * buffer) +{ + DWORD io_result = 0; + DWORD bytes_returned = 0; + HANDLE hFile = CreateFileW(name, 0, 0, NULL, OPEN_EXISTING, + FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, 0); + if (hFile == INVALID_HANDLE_VALUE) + return 0; + + io_result = DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, + buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytes_returned, NULL); + + CloseHandle(hFile); + + if (io_result == 0) + return 0; + + return ((REPARSE_GUID_DATA_BUFFER*)buffer)->ReparseTag == IO_REPARSE_TAG_SYMLINK; +} + +#pragma pack(push, 1) + +typedef struct dirent_FILE_ID_128 +{ + BYTE Identifier[16]; +} +dirent_FILE_ID_128; + +typedef struct _dirent_FILE_ID_INFO +{ + ULONGLONG VolumeSerialNumber; + dirent_FILE_ID_128 FileId; +} +dirent_FILE_ID_INFO; + +#pragma pack(pop) + +typedef enum dirent_FILE_INFO_BY_HANDLE_CLASS +{ dirent_FileIdInfo = 18 } +dirent_FILE_INFO_BY_HANDLE_CLASS; + +static __ino_t __inode(const wchar_t* name) +{ + __ino_t value = { 0 }; + BOOL result; + dirent_FILE_ID_INFO fileid; + BY_HANDLE_FILE_INFORMATION info; + typedef BOOL (__stdcall* pfnGetFileInformationByHandleEx)(HANDLE hFile, + dirent_FILE_INFO_BY_HANDLE_CLASS FileInformationClass, + LPVOID lpFileInformation, DWORD dwBufferSize); + + HANDLE hKernel32 = GetModuleHandleW(L"kernel32.dll"); + if (!hKernel32) + return value; + + pfnGetFileInformationByHandleEx fnGetFileInformationByHandleEx = (pfnGetFileInformationByHandleEx) GetProcAddress(hKernel32, "GetFileInformationByHandleEx"); + if (!fnGetFileInformationByHandleEx) + return value; + + HANDLE hFile = CreateFileW(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + if (hFile == INVALID_HANDLE_VALUE) + return value; + + result = fnGetFileInformationByHandleEx(hFile, dirent_FileIdInfo, &fileid, sizeof(fileid)); + if (result) + { + value.serial = fileid.VolumeSerialNumber; + memcpy(value.fileid, fileid.FileId.Identifier, 16); + } + else + { + result = GetFileInformationByHandle(hFile, &info); + if(result) + { + value.serial = info.dwVolumeSerialNumber; + memcpy(value.fileid + 8, &info.nFileIndexHigh, 4); + memcpy(value.fileid + 12, &info.nFileIndexLow, 4); + } + } + CloseHandle(hFile); + return value; +} + +static DIR* __internal_opendir(wchar_t* wname, int size) +{ + struct __dir* data = NULL; + struct dirent *tmp_entries = NULL; + static char default_char = '?'; + static wchar_t* prefix = L"\\\\?\\"; + static wchar_t* suffix = L"\\*.*"; + static int extra_prefix = 4; /* use prefix "\\?\" to handle long file names */ + static int extra_suffix = 4; /* use suffix "\*.*" to find everything */ + WIN32_FIND_DATAW w32fd = { 0 }; + HANDLE hFindFile = INVALID_HANDLE_VALUE; + static int grow_factor = 2; + char* buffer = NULL; + + BOOL relative = PathIsRelativeW(wname + extra_prefix); + + memcpy(wname + size - 1, suffix, sizeof(wchar_t) * extra_suffix); + wname[size + extra_suffix - 1] = 0; + + if (relative) { + wname += extra_prefix; + size -= extra_prefix; + } + hFindFile = FindFirstFileW(wname, &w32fd); + if (INVALID_HANDLE_VALUE == hFindFile) + { + __seterrno(ENOENT); + return NULL; + } + + data = (struct __dir*) malloc(sizeof(struct __dir)); + if (!data) + goto out_of_memory; + wname[size - 1] = 0; + data->fd = (intptr_t)CreateFileW(wname, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0); + wname[size - 1] = L'\\'; + data->count = 16; + data->index = 0; + data->entries = (struct dirent*) malloc(sizeof(struct dirent) * data->count); + if (!data->entries) + goto out_of_memory; + buffer = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE); + if (!buffer) + goto out_of_memory; + do + { + WideCharToMultiByte(CP_UTF8, 0, w32fd.cFileName, -1, data->entries[data->index].d_name, NAME_MAX, &default_char, NULL); + + memcpy(wname + size, w32fd.cFileName, sizeof(wchar_t) * NAME_MAX); + + if (((w32fd.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT) && __islink(wname, buffer)) + data->entries[data->index].d_type = DT_LNK; + else if ((w32fd.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) == FILE_ATTRIBUTE_DEVICE) + data->entries[data->index].d_type = DT_CHR; + else if ((w32fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) + data->entries[data->index].d_type = DT_DIR; + else + data->entries[data->index].d_type = DT_REG; + + data->entries[data->index].d_ino = __inode(wname); + data->entries[data->index].d_reclen = sizeof(struct dirent); + data->entries[data->index].d_namelen = (unsigned char)wcslen(w32fd.cFileName); + data->entries[data->index].d_off = 0; + + if (++data->index == data->count) { + tmp_entries = (struct dirent*) realloc(data->entries, sizeof(struct dirent) * data->count * grow_factor); + if (!tmp_entries) + goto out_of_memory; + data->entries = tmp_entries; + data->count *= grow_factor; + } + } + while (FindNextFileW(hFindFile, &w32fd) != 0); + + free(buffer); + FindClose(hFindFile); + + data->count = data->index; + data->index = 0; + return (DIR*)data; +out_of_memory: + if (data) + { + if (INVALID_HANDLE_VALUE != (HANDLE)data->fd) + CloseHandle((HANDLE)data->fd); + free(data->entries); + } + free(buffer); + free(data); + if (INVALID_HANDLE_VALUE != hFindFile) + FindClose(hFindFile); + __seterrno(ENOMEM); + return NULL; +} + +static wchar_t* __get_buffer() +{ + wchar_t* name = malloc(sizeof(wchar_t) * (NTFS_MAX_PATH + NAME_MAX + 8)); + if (name) + memcpy(name, L"\\\\?\\", sizeof(wchar_t) * 4); + return name; +} + +static DIR* opendir(const char* name) +{ + DIR* dirp = NULL; + wchar_t* wname = __get_buffer(); + int size = 0; + if (!wname) + { + errno = ENOMEM; + return NULL; + } + size = MultiByteToWideChar(CP_UTF8, 0, name, -1, wname + 4, NTFS_MAX_PATH); + if (0 == size) + { + free(wname); + return NULL; + } + dirp = __internal_opendir(wname, size + 4); + free(wname); + return dirp; +} + +static DIR* _wopendir(const wchar_t* name) +{ + DIR* dirp = NULL; + wchar_t* wname = __get_buffer(); + int size = 0; + if (!wname) + { + errno = ENOMEM; + return NULL; + } + size = (int)wcslen(name); + if (size > NTFS_MAX_PATH) + { + free(wname); + return NULL; + } + memcpy(wname + 4, name, sizeof(wchar_t) * (size + 1)); + dirp = __internal_opendir(wname, size + 5); + free(wname); + return dirp; +} + +static DIR* fdopendir(intptr_t fd) +{ + DIR* dirp = NULL; + wchar_t* wname = __get_buffer(); + typedef DWORD (__stdcall * pfnGetFinalPathNameByHandleW)( + HANDLE hFile, LPWSTR lpszFilePath, DWORD cchFilePath, DWORD dwFlags); + + HANDLE hKernel32 = GetModuleHandleW(L"kernel32.dll"); + if (!hKernel32) + { + errno = EINVAL; + return NULL; + } + + pfnGetFinalPathNameByHandleW fnGetFinalPathNameByHandleW = (pfnGetFinalPathNameByHandleW) GetProcAddress(hKernel32, "GetFinalPathNameByHandleW"); + if (!fnGetFinalPathNameByHandleW) + { + errno = EINVAL; + return NULL; + } + + int size = 0; + if (!wname) + { + errno = ENOMEM; + return NULL; + } + size = fnGetFinalPathNameByHandleW((HANDLE) fd, wname + 4, NTFS_MAX_PATH, FILE_NAME_NORMALIZED); + if (0 == size) + { + free(wname); + errno = ENOTDIR; + return NULL; + } + dirp = __internal_opendir(wname, size + 5); + free(wname); + return dirp; +} + +static struct dirent* readdir(DIR* dirp) +{ + struct __dir* data = (struct __dir*) dirp; + if (!data) { + errno = EBADF; + return NULL; + } + if (data->index < data->count) + { + return &data->entries[data->index++]; + } + return NULL; +} + +static int readdir_r(DIR* dirp, struct dirent* entry, struct dirent**result) +{ + struct __dir* data = (struct __dir*) dirp; + if (!data) { + return EBADF; + } + if (data->index < data->count) + { + if (entry) + memcpy(entry, &data->entries[data->index++], sizeof(struct dirent)); + if (result) + *result = entry; + } + else if (result) + *result = NULL; + return 0; +} + +static void seekdir(DIR* dirp, long int offset) +{ + if (dirp) + { + struct __dir* data = (struct __dir*) dirp; + data->index = (offset < data->count) ? offset : data->index; + } +} + +static void rewinddir(DIR* dirp) +{ + seekdir(dirp, 0); +} + +static long int telldir(DIR* dirp) +{ + if (!dirp) { + errno = EBADF; + return -1; + } + return ((struct __dir*)dirp)->count; +} + +static intptr_t dirfd(DIR * dirp) +{ + if (!dirp) { + errno = EINVAL; + return -1; + } + return ((struct __dir*)dirp)->fd; +} + +static int scandir(const char* dirp, struct dirent*** namelist, + int (*filter)(const struct dirent*), + int (*compar)(const struct dirent**, const struct dirent**)) +{ + struct dirent ** entries = NULL, ** tmp_entries = NULL; + long int i = 0, index = 0, count = 16; + DIR * d = opendir(dirp); + struct __dir* data = (struct __dir*) d; + if (!data) { + closedir(d); + __seterrno(ENOENT); + return -1; + } + entries = (struct dirent**) malloc(sizeof(struct dirent*) * count); + if (!entries) + { + closedir(d); + __seterrno(ENOMEM); + return -1; + } + for (i = 0; i < data->count; ++i) + { + if (!filter || filter(&data->entries[i])) + { + entries[index] = (struct dirent*) malloc(sizeof(struct dirent)); + if (!entries[index]) + { + closedir(d); + for (i = 0; i < index; ++i) + free(entries[index]); + free(entries); + __seterrno(ENOMEM); + return -1; + } + memcpy(entries[index], &data->entries[i], sizeof(struct dirent)); + if (++index == count) + { + tmp_entries = (struct dirent**)realloc(entries, sizeof(struct dirent*) * count * 2); + if (!tmp_entries) + { + closedir(d); + for (i = 0; i < index; ++i) + free(entries[index - 1]); + free(entries); + __seterrno(ENOMEM); + return -1; + } + entries = tmp_entries; + count *= 2; + } + } + } + qsort(entries, index, sizeof(struct dirent*), compar); + entries[index] = NULL; + if (namelist) + *namelist = entries; + closedir(d); + return 0; +} + +int alphasort(const void* a, const void* b) +{ + struct dirent** dira = (struct dirent**)a, **dirb = (struct dirent**)b; + if (!dira || !dirb) + return 0; + return strcoll((*dira)->d_name, (*dirb)->d_name); +} + +static int __strverscmp(const char* s1, const char* s2) +{ + return alphasort(s1, s2); +} + +int versionsort(const void* a, const void* b) +{ + struct dirent** dira = (struct dirent**)a, ** dirb = (struct dirent**)b; + if (!dira || !dirb) + return 0; + return __strverscmp((*dira)->d_name, (*dirb)->d_name); +} + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _WIN32 */ + +#endif /* __DIRENT_H_9DE6B42C_8D0C_4D31_A8EF_8E4C30E6C46A__ */ diff --git a/WinBuild/winbuild.c b/WinBuild/winbuild.c new file mode 100644 index 0000000..2a339e0 --- /dev/null +++ b/WinBuild/winbuild.c @@ -0,0 +1,111 @@ +/* $Id$ */ +#include +#include +#include +#include "dirent.h" + +#ifdef _MSC_VER +#include +#define access _access +#else +#include +#endif + +char* dynstrdup(const char* str1) { + char* str = malloc(strlen(str1) + 1); + memcpy(str, str1, strlen(str1)); + str[strlen(str1)] = 0; + return str; +} + +char* dynstrcat(const char* str1, const char* str2) { + char* str = malloc(strlen(str1) + strlen(str2) + 1); + memcpy(str, str1, strlen(str1)); + memcpy(str + strlen(str1), str2, strlen(str2)); + str[strlen(str1) + strlen(str2)] = 0; + return str; +} + +char* dynstrcat3(const char* str1, const char* str2, const char* str3){ + char* tmp = dynstrcat(str1, str2); + char* str = dynstrcat(tmp, str3); + free(tmp); + return str; +} + +int main(){ +#ifdef _MSC_VER + if(access("..\\Tool", 0) != 0){ +#else + if(access("..\\Tool", F_OK) != 0){ +#endif + fprintf(stderr, "Run me from the WinBuild directory\n"); + return 1; + } +#ifdef _MSC_VER + if(access("..\\Serenade", 0) != 0){ +#else + if(access("..\\Serenade", F_OK) != 0){ +#endif + fprintf(stderr, "Run me from the WinBuild directory\n"); + return 1; + } + system("cl /Fe:..\\Tool\\configgen.exe ..\\Tool\\configgen.c"); + FILE* f = fopen("..\\config.h", "r"); + if(f != NULL){ + printf("config.h already exists, remove it to generate it again.\n"); + fclose(f); + }else{ + system("..\\Tool\\configgen.exe ..\\config.h"); + } + system("cl /Fe:..\\Tool\\config.exe ..\\Tool\\config.c"); + system("..\\Tool\\config.exe reqobjs Windows >buildobjs"); + system("..\\Tool\\config.exe objs Windows >>buildobjs"); + f = fopen("buildobjs", "r"); + if(f != NULL){ + chdir("..\\Serenade"); + char* cbuf = malloc(2); + cbuf[1] = 0; + char* buf = malloc(1); + char* objs = malloc(1); + objs[0] = 0; + buf[0] = 0; + while(1){ + fread(cbuf, 1, 1, f); + if(feof(f)) break; + if(cbuf[0] == '\n' || cbuf[0] == '\r' || cbuf[0] == ' '){ + if(strlen(buf) > 0){ + char* objstmp = objs; + objs = dynstrcat3(objstmp, " ", buf); + char* cfile = dynstrdup(buf); + cfile[strlen(cfile) - 1] = 'c'; + char* argtmp1 = dynstrcat("cl /c /D _AMD64_ /Fo:", buf); + char* argtmp2 = dynstrcat(argtmp1, " "); + char* arg = dynstrcat(argtmp2, cfile); + system(arg); + free(arg); + free(argtmp1); + free(argtmp2); + free(cfile); + } + free(buf); + buf = malloc(1); + buf[0] = 0; + }else{ + char* tmp = buf; + buf = dynstrcat(tmp, cbuf); + free(tmp); + } + } + free(buf); + + char* cmd = dynstrcat("cl /Fe:serenade.exe ", objs); + system(cmd); + free(cmd); + + free(objs); + + chdir("WinBuild"); + } + fclose(f); +} \ No newline at end of file diff --git a/build.bat b/build.bat index 99a58f1..e94051e 100644 --- a/build.bat +++ b/build.bat @@ -1,5 +1,6 @@ @echo off REM $Id$ +REM THIS IS LEGACY SCRIPT; CONSIDER USING WinBuild\build.bat REM Change this as you want call "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat" -- 2.43.0