From 7ae51e55040533b5f45af8838cfc53b327fa3abb Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Sat, 5 Jan 2013 21:04:11 +0200 Subject: [PATCH] MSVC support * Antimake extension 'msvc' * Hardcoded config * More guarded headers Usage: 1. Install coreutils and make from gnuwin32 2. Make sure VC env variables are loaded (PATH) 3. Copy build_msvc.mk to build.mk It would be nice to make it work with MSYS/MINGW32 + VC, but their filename mangling makes it messy. --- Makefile | 1 + build_msvc.mk | 7 ++++ m4/usual.m4 | 1 + mk/amext-msvc.mk | 38 ++++++++++++++++++ test/Makefile | 8 ++-- test/test_base.c | 6 ++- test/test_bits.c | 2 +- test/test_cfparser.c | 2 +- test/test_cxalloc.c | 10 ++--- test/test_fnmatch.c | 5 ++- test/test_string.c | 2 + usual/base.h | 20 +++++++++- usual/base_win32.h | 23 +++++++++++ usual/config_msvc.h | 95 ++++++++++++++++++++++++++++++++++++++++++++ usual/event.h | 2 + usual/socket_win32.h | 27 +++++++++++-- usual/time.h | 7 ++++ 17 files changed, 238 insertions(+), 18 deletions(-) create mode 100644 build_msvc.mk create mode 100644 mk/amext-msvc.mk create mode 100644 usual/config_msvc.h diff --git a/Makefile b/Makefile index 944c208..2f7745e 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,7 @@ libusual_a_SOURCES = usual/config.h.in \ usual/bits.h \ usual/cbtree.h usual/cbtree.c \ usual/cfparser.h usual/cfparser.c \ + usual/config_msvc.h \ usual/crypto/digest.h usual/crypto/digest.c \ usual/crypto/hmac.h usual/crypto/hmac.c \ usual/crypto/keccak.h usual/crypto/keccak.c \ diff --git a/build_msvc.mk b/build_msvc.mk new file mode 100644 index 0000000..8d5fdc5 --- /dev/null +++ b/build_msvc.mk @@ -0,0 +1,7 @@ + +AM_FEATURES = msvc + +abs_top_srcdir = $(dir $(filter %/build.mk, $(MAKEFILE_LIST))) + +include $(abs_top_srcdir)/mk/antimake.mk + diff --git a/m4/usual.m4 b/m4/usual.m4 index 7ae5de7..35ad396 100644 --- a/m4/usual.m4 +++ b/m4/usual.m4 @@ -165,6 +165,7 @@ dnl dnl AC_USUAL_HEADER_CHECK: Basic headers dnl AC_DEFUN([AC_USUAL_HEADER_CHECK], [ +AC_CHECK_HEADERS([inttypes.h stdbool.h unistd.h sys/time.h]) AC_CHECK_HEADERS([sys/socket.h poll.h sys/poll.h sys/un.h]) AC_CHECK_HEADERS([arpa/inet.h netinet/in.h netinet/tcp.h]) AC_CHECK_HEADERS([sys/param.h sys/uio.h pwd.h grp.h]) diff --git a/mk/amext-msvc.mk b/mk/amext-msvc.mk new file mode 100644 index 0000000..0148fe5 --- /dev/null +++ b/mk/amext-msvc.mk @@ -0,0 +1,38 @@ + +Printf = printf $(subst %,%%,$(1)) $(2) + +SHELL = cmd.exe + +EXEEXT = .exe +LIBEXT = .lib +OBJEXT = .obj + +CC = cl -nologo +CFLAGS = -O2 +WFLAGS = +WFLAGS = -W2 -WX +CPP = $(CC) -E + +AR = lib +ARFLAGS = -nologo -out:$(call vcFixPath,$@) + +LDFLAGS = + +MKDIR_P = mkdir + +MkDir = $(if $(wildcard $(1)),,md $(call vcFixPath,$(1))) + +LIBS = -lws2_32 -ladvapi32 + +vcFixPath = $(subst /,\,$(1)) +vcFixLibs = $(patsubst %.a,%.lib,$(patsubst -l%,%.lib,$(1))) +vcFixAll = $(call vcFixPath,$(call vcFixLibs,$(1))) + +AM_LANG_C_COMPILE = $(COMPILE) -c -Fo$(call vcFixPath,$@) $< + +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -Fe$(call vcFixPath,$@) + +ar_lib = lib -nologo -out:$(call vcFixAll,$@) $^ +AM_LANG_C_LINK = $(LINK) $(call vcFixAll,$^ $(AM_LIBS) $(LIBS)) $(AM_LT_RPATH) + + diff --git a/test/Makefile b/test/Makefile index c232ec7..ed9dd50 100644 --- a/test/Makefile +++ b/test/Makefile @@ -20,14 +20,14 @@ regtest_compat_SOURCES := $(regtest_system_SOURCES) nodist_regtest_compat_SOURCES = test_config.h regtest_compat_EMBED_LIBUSUAL = 1 -regtest_system_EMBED_LIBUSUAL = 1 +#regtest_system_EMBED_LIBUSUAL = 1 -regtest_system_LDADD = -lanl -regtest_system_LDFLAGS = -pthread +regtest_system_LDADD = ../libusual.a +regtest_system_LDFLAGS = #-pthread regtest_system_CPPFLAGS = -I.. -I. regtest_compat_CPPFLAGS := $(regtest_system_CPPFLAGS) -DUSUAL_TEST_CONFIG -regtest_compat_LDFLAGS = -pthread +regtest_compat_LDFLAGS = #-pthread EXTRA_DIST = Makefile tinytest_demo.c force_compat.sed test_cfparser.ini diff --git a/test/test_base.c b/test/test_base.c index 06023b7..3d9a440 100644 --- a/test/test_base.c +++ b/test/test_base.c @@ -45,12 +45,14 @@ static void test_ptr(void *p) end:; } +#ifdef _PACKED struct packed { char a; int b; char c; short d; } _PACKED; +#endif static void test_misc(void *_p) { @@ -65,8 +67,10 @@ static void test_misc(void *_p) int_check(ARRAY_NELEM(s_2), 2); int_check(strcmp(__func__, "test_misc"), 0); - +#ifdef _PACKED int_check(sizeof(struct packed), 8); +#endif + end:; } diff --git a/test/test_bits.c b/test/test_bits.c index 1fb5ba2..0ba2b23 100644 --- a/test/test_bits.c +++ b/test/test_bits.c @@ -33,7 +33,7 @@ static void test_rol(void *p) /* rol64 */ ull_check(rol64(1, 1), 2); - ull_check(rol64(1, 63), 0x8000000000000000); + ull_check(rol64(1, 63), 0x8000000000000000ULL); end:; } diff --git a/test/test_cfparser.c b/test/test_cfparser.c index ca68b24..2409c83 100644 --- a/test/test_cfparser.c +++ b/test/test_cfparser.c @@ -108,7 +108,7 @@ static void *get_two(void *top_arg, const char *sect_name) static const struct CfSect rsects [] = { { "one", rkeys1 }, - { "two", rkeys2, .base_lookup = get_two, }, + { "two", rkeys2, get_two, }, { NULL }, }; diff --git a/test/test_cxalloc.c b/test/test_cxalloc.c index 294c33b..cd33325 100644 --- a/test/test_cxalloc.c +++ b/test/test_cxalloc.c @@ -57,14 +57,14 @@ static void log_free(void *ctx, const void *ptr) } static const struct CxOps log_ops = { - .c_alloc = log_alloc, - .c_realloc = log_realloc, - .c_free = log_free, + log_alloc, + log_realloc, + log_free, }; static const struct CxMem log_libc = { - .ops = &log_ops, - .ctx = (void*)&cx_libc_allocator, + &log_ops, + (void*)&cx_libc_allocator, }; #define log_check(x) str_check(logbuf, x); reset(); diff --git a/test/test_fnmatch.c b/test/test_fnmatch.c index 25d26dc..e41677b 100644 --- a/test/test_fnmatch.c +++ b/test/test_fnmatch.c @@ -2,6 +2,7 @@ #include #include +#include #include "test_common.h" /* @@ -52,12 +53,14 @@ static void test_fnmatch_posix(void *p) int_check(0, fnmatch("[*?[][*?[][*?[]", "*?[", 0)); int_check(0, fnmatch("[[:alpha:]][![:alpha:]]", "a9", 0)); int_check(0, fnmatch("[[:alnum:]][![:alnum:]]", "9-", 0)); +#ifdef iswblank int_check(0, fnmatch("[[:blank:]][![:blank:]]", " -", 0)); +#endif int_check(0, fnmatch("[[:cntrl:]][![:cntrl:]]", "\tx", 0)); int_check(0, fnmatch("[[:digit:]][![:digit:]]", "9a", 0)); int_check(0, fnmatch("[[:graph:]][![:graph:]]", "a\t", 0)); int_check(0, fnmatch("[[:lower:]][![:lower:]]", "aA", 0)); - int_check(0, fnmatch("[[:print:]][![:print:]]", "a\t", 0)); + int_check(0, fnmatch("[[:print:]][![:print:]]", "a\n", 0)); int_check(0, fnmatch("[[:punct:]][![:punct:]]", ".x", 0)); int_check(0, fnmatch("[[:space:]][![:space:]]", " x", 0)); int_check(0, fnmatch("[[:upper:]][![:upper:]]", "Ff", 0)); diff --git a/test/test_string.c b/test/test_string.c index 1013213..ee90d99 100644 --- a/test/test_string.c +++ b/test/test_string.c @@ -1,7 +1,9 @@ #include #include +#ifdef HAVE_LIBGEN_H #include +#endif #undef basename #undef dirname diff --git a/usual/base.h b/usual/base.h index 9f4d065..6cf4bf9 100644 --- a/usual/base.h +++ b/usual/base.h @@ -23,6 +23,8 @@ #ifdef USUAL_TEST_CONFIG #include "test_config.h" +#elif defined(_MSC_VER) +#include #else #include #endif @@ -34,16 +36,28 @@ #endif #include +#ifdef HAVE_SYS_PARAM_H #include +#endif #include #include +#ifdef HAVE_INTTYPES_H #include -#include +#endif #include #include #include -#include #include +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_STDBOOL_H +#include +#else +/* we really want bool type */ +typedef enum { true=1, false=0 } bool; +#endif #ifdef WIN32 #include @@ -120,7 +134,9 @@ #define _COMPILER_ICC(ver) (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= (ver))) /** Disable padding for structure */ +#ifndef _MSC_VER #define _PACKED __attribute__((packed)) +#endif /* * Make sure __func__ works. diff --git a/usual/base_win32.h b/usual/base_win32.h index 8bf3757..c1489ab 100644 --- a/usual/base_win32.h +++ b/usual/base_win32.h @@ -21,9 +21,15 @@ #include +#ifndef ECONNABORTED #define ECONNABORTED WSAECONNABORTED +#endif +#ifndef EMSGSIZE #define EMSGSIZE WSAEMSGSIZE +#endif +#ifndef EINPROGRESS #define EINPROGRESS WSAEWOULDBLOCK /* WSAEINPROGRESS */ +#endif #undef EAGAIN #define EAGAIN WSAEWOULDBLOCK /* WSAEAGAIN */ @@ -46,6 +52,23 @@ #define srandom(s) srand(s) #define random() rand() +#ifdef _MSC_VER + +#define snprintf(fmt, ...) _snprintf(fmt, __VA_ARGS__) + +static inline int strcasecmp(const char *a, const char *b) +{ + return _stricmp(a, b); +} + +static inline int strncasecmp(const char *a, const char *b, size_t cnt) +{ + return _strnicmp(a, b, cnt); +} + +typedef int ssize_t; + +#endif /* getrlimit() */ #define RLIMIT_NOFILE -1 diff --git a/usual/config_msvc.h b/usual/config_msvc.h new file mode 100644 index 0000000..32f74c4 --- /dev/null +++ b/usual/config_msvc.h @@ -0,0 +1,95 @@ + +/* Define to 1 if you have the `event_base_new' function. */ +#define HAVE_EVENT_BASE_NEW 1 + +/* Define to 1 if you have the `event_loopbreak' function. */ +#define HAVE_EVENT_LOOPBREAK 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "https://libusual.github.com" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libusual" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libusual 0.1" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libusual" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "0.1" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to request cleaner win32 headers. */ +#define WIN32_LEAN_AND_MEAN 1 + +/* Define to max win32 API version (0x0501=XP). */ +//#define WINVER 0x0501 +#define WINVER 0x0600 + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +/* # undef WORDS_BIGENDIAN */ +# endif +#endif + +/* Define to `int' if doesn't define. */ +#define gid_t int + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#define inline __inline +#endif + +/* Define to `int' if does not define. */ +#define pid_t int + +/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported directly. */ +#ifndef restrict +#define restrict +#endif + +/* Define to `int' if doesn't define. */ +#define uid_t int + +#define _CRT_SECURE_NO_WARNINGS 1 + +#ifndef WIN32 +#define WIN32 1 +#endif diff --git a/usual/event.h b/usual/event.h index f7f4e31..28356a0 100644 --- a/usual/event.h +++ b/usual/event.h @@ -28,7 +28,9 @@ #include +#ifdef HAVE_SYS_TIME_H #include +#endif #ifdef HAVE_LIBEVENT diff --git a/usual/socket_win32.h b/usual/socket_win32.h index 80690f4..a910918 100644 --- a/usual/socket_win32.h +++ b/usual/socket_win32.h @@ -42,15 +42,18 @@ struct msghdr { int msg_flags; }; +#ifndef SCM_RIGHTS +#define SCM_RIGHTS 1 +#endif + +#ifndef CMSG_FIRSTHDR + struct cmsghdr { int cmsg_len; int cmsg_level; int cmsg_type; }; - -#define SCM_RIGHTS 1 - #define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1)) #define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \ & ~(sizeof (size_t) - 1)) @@ -68,6 +71,8 @@ struct cmsghdr { (struct cmsghdr *)((u_char *)(cmsg) + CMSG_ALIGN((cmsg)->cmsg_len)))) #define CMSG_SPACE(len) (CMSG_ALIGN(sizeof(struct cmsghdr))+CMSG_ALIGN(len)) +#endif + /* * unify WSAGetLastError() with errno. * @@ -212,4 +217,20 @@ struct tcp_keepalive { }; #endif +/* + * Use native poll() if available + */ + +#if !defined(HAVE_POLL) && defined(POLLIN) + +#define HAVE_POLL +#define poll(a,b,c) usual_poll(a,b,c) + +static inline int poll(struct pollfd *fds, int nfds, int timeout) +{ + return WSAPoll(fds, nfds, timeout); +} + +#endif + #endif diff --git a/usual/time.h b/usual/time.h index 0911b4a..c43c171 100644 --- a/usual/time.h +++ b/usual/time.h @@ -26,7 +26,14 @@ #include +#ifdef HAVE_SYS_TIME_H #include +#endif + +#ifdef _WIN32 +#include +#endif + #include /** Type to hold microseconds. */ -- 2.39.5