From 31af41c3c6ab66935ce91296aa1a8cab0be1216d Mon Sep 17 00:00:00 2001 From: Frederik Seiffert Date: Fri, 29 Jan 2021 12:52:42 +0100 Subject: [PATCH] Support building on Windows with Clang MSVC target --- ChangeLog | 11 ++++++++ Instance/library.make | 31 +++++++++++++++++++--- configure | 6 ++--- m4/gs_cc_is_clang.m4 | 6 ++--- target.make | 61 +++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 101 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index e78a5392c..c9998f747 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2021-01-29 Frederik Seiffert + + * common.make: + * configure: + * m4/gs_cc_is_clang.m4: + * target.make: + Added support for building on Windows with Clang MSVC target. + Requires passing a host like --host=x86_64-pc-windows. + Removes the check for $GCC in gs_cc_is_clang.m4 as it will be false + when using the MSVC ABI due to __GNUC__ not being defined. + 2021-01-29 Frederik Seiffert * common.make: diff --git a/Instance/library.make b/Instance/library.make index 685e0cebc..46433f942 100644 --- a/Instance/library.make +++ b/Instance/library.make @@ -200,9 +200,15 @@ endif else # BUILD_DLL # When you build a DLL, you have to install it in a directory which is -# in your PATH. +# in your PATH. On Windows MSVC we use the library directory that will +# also contain other libraries like objc.dll. Otherwise (i.e. on MinGW) +# we use the tools directory. ifeq ($(DLL_INSTALLATION_DIR),) - DLL_INSTALLATION_DIR = $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR) + ifeq ($(GNUSTEP_TARGET_OS), windows) + DLL_INSTALLATION_DIR = $(FINAL_LIBRARY_INSTALL_DIR) + else + DLL_INSTALLATION_DIR = $(GNUSTEP_TOOLS)/$(GNUSTEP_TARGET_LDIR) + endif endif # When we build a DLL, we also pass -DBUILD_lib{library_name}_DLL=1 to @@ -219,8 +225,13 @@ endif CLEAN_library_NAME = $(subst -,_,$(LIBRARY_NAME_WITH_LIB)) SHARED_CFLAGS += -DBUILD_$(CLEAN_library_NAME)_DLL=1 -# LIBRARY_FILE is the import library, libgnustep-base.dll.a -LIBRARY_FILE = $(LIBRARY_NAME_WITH_LIB)$(DLL_LIBEXT)$(LIBEXT) +# LIBRARY_FILE is the import library, i.e. gnustep-base.lib for Windows +# MSVC, or libgnustep-base.dll.a for MinGW. +ifeq ($(GNUSTEP_TARGET_OS), windows) + LIBRARY_FILE = $(LIBRARY_NAME_WITHOUT_LIB)$(LIBEXT) +else + LIBRARY_FILE = $(LIBRARY_NAME_WITH_LIB)$(DLL_LIBEXT)$(LIBEXT) +endif VERSION_LIBRARY_FILE = $(LIBRARY_FILE) SONAME_LIBRARY_FILE = $(LIBRARY_FILE) @@ -230,6 +241,9 @@ SONAME_LIBRARY_FILE = $(LIBRARY_FILE) # INTERFACE_VERSION of the library; this works exactly in the same way # as under Unix. LIB_LINK_DLL_FILE = $(DLL_PREFIX)$(LIBRARY_NAME_WITHOUT_LIB)-$(subst .,_,$(INTERFACE_VERSION))$(DLL_LIBEXT) +ifeq ($(GNUSTEP_TARGET_OS), windows) + LIB_LINK_PDB_FILE = $(DLL_PREFIX)$(LIBRARY_NAME_WITHOUT_LIB)-$(subst .,_,$(INTERFACE_VERSION))$(DLL_PDBEXT) +endif endif # BUILD_DLL else # following code for static libs @@ -326,6 +340,15 @@ internal-install-lib:: $(INSTALL_PROGRAM) $(GNUSTEP_OBJ_DIR)/$(LIB_LINK_DLL_FILE) \ $(DLL_INSTALLATION_DIR) ; \ fi$(END_ECHO) + +ifeq ($(GNUSTEP_TARGET_OS), windows) +# On Windows MSVC, also install the PDB file. +internal-install-lib:: + $(ECHO_INSTALLING)if [ -f $(GNUSTEP_OBJ_DIR)/$(LIB_LINK_PDB_FILE) ]; then \ + $(INSTALL_PROGRAM) $(GNUSTEP_OBJ_DIR)/$(LIB_LINK_PDB_FILE) \ + $(DLL_INSTALLATION_DIR) ; \ + fi$(END_ECHO) +endif endif internal-library-uninstall_:: shared-instance-headers-uninstall shared-instance-pkgconfig-uninstall diff --git a/configure b/configure index 86ba09423..692003ca8 100755 --- a/configure +++ b/configure @@ -4474,10 +4474,8 @@ if ${_gs_cv_cc_is_clang+:} false; then : $as_echo_n "(cached) " >&6 else _gs_cv_cc_is_clang="no" - if test x"${GCC}" = x"yes" ; then - if "${CC}" -v 2>&1 | grep -q 'clang version'; then - _gs_cv_cc_is_clang="yes"; - fi + if "${CC}" -v 2>&1 | grep -q 'clang version'; then + _gs_cv_cc_is_clang="yes"; fi fi diff --git a/m4/gs_cc_is_clang.m4 b/m4/gs_cc_is_clang.m4 index a76e265bb..bd361824e 100644 --- a/m4/gs_cc_is_clang.m4 +++ b/m4/gs_cc_is_clang.m4 @@ -14,10 +14,8 @@ AC_DEFUN([GS_CHECK_CC_IS_CLANG],dnl [AC_REQUIRE([AC_PROG_CC]) AC_CACHE_CHECK([whether the compiler is clang],[_gs_cv_cc_is_clang], [dnl _gs_cv_cc_is_clang="no" - if test x"${GCC}" = x"yes" ; then - if "${CC}" -v 2>&1 | grep -q 'clang version'; then - _gs_cv_cc_is_clang="yes"; - fi + if "${CC}" -v 2>&1 | grep -q 'clang version'; then + _gs_cv_cc_is_clang="yes"; fi ]) AS_VAR_SET([gs_cv_cc_is_clang], [${_gs_cv_cc_is_clang}]) diff --git a/target.make b/target.make index beeb8e74f..e8993a6fd 100644 --- a/target.make +++ b/target.make @@ -34,7 +34,10 @@ endif # # Target specific libraries # -TARGET_SYSTEM_LIBS = $(CONFIG_SYSTEM_LIBS) -lm +TARGET_SYSTEM_LIBS = $(CONFIG_SYSTEM_LIBS) +ifneq ($(GNUSTEP_TARGET_OS), windows) + TARGET_SYSTEM_LIBS += -lm +endif # All code we build needs to be thread-safe nowadays INTERNAL_CFLAGS = -pthread @@ -60,6 +63,10 @@ else ifeq ($(findstring mingw64, $(GNUSTEP_TARGET_OS)), mingw64) TARGET_SYSTEM_LIBS = $(CONFIG_SYSTEM_LIBS) \ -lws2_32 -ladvapi32 -lcomctl32 -luser32 -lcomdlg32 \ -lmpr -lnetapi32 -lm -I. # the -I is a dummy to avoid -lm^M +else ifeq ($(GNUSTEP_TARGET_OS), windows) + TARGET_SYSTEM_LIBS = $(CONFIG_SYSTEM_LIBS) \ + -lws2_32 -ladvapi32 -lcomctl32 -luser32 -lcomdlg32 \ + -lmpr -lnetapi32 -lkernel32 -lshell32 endif ifeq ($(findstring solaris, $(GNUSTEP_TARGET_OS)), solaris) @@ -808,7 +815,7 @@ SHARED_CFLAGS = # while it is the default, it might silently get disabled if a symbol # gets manually exported (eg, because a header of a library we include # exports a symbol by mistake). -ifneq ($(CC),clang) +ifneq ($(CLANG_CC), yes) SHARED_LIB_LINK_CMD = \ $(LD) $(SHARED_LD_PREFLAGS) -shared \ -Wl,--enable-auto-image-base \ @@ -1045,6 +1052,56 @@ endif # #################################################### +#################################################### +# +# Windows MSVC +# +ifeq ($(GNUSTEP_TARGET_OS), windows) +shared = yes +HAVE_SHARED_LIBS = yes + +# This command links the library, generates the list of symbols to export from +# the dllexport annotations, creates the DLL (eg, obj/gnustep-base-1_13.dll), +# a PDB file (eg, obj/gnustep-base-1_13.pdb, requires -g flag), and the import +# library (eg, obj/gnustep-base.lib). +SHARED_LIB_LINK_CMD = \ + $(LD) $(SHARED_LD_PREFLAGS) -g -Wl,-dll \ + -Wl,-implib:$(LIB_LINK_OBJ_DIR)/$(LIB_LINK_VERSION_FILE) \ + -Wl,-pdb:$(LIB_LINK_OBJ_DIR)/$(LIB_LINK_PDB_FILE) \ + $(ALL_LDFLAGS) -o $(LIB_LINK_OBJ_DIR)/$(LIB_LINK_DLL_FILE) $^ \ + $(INTERNAL_LIBRARIES_DEPEND_UPON) \ + $(SHARED_LD_POSTFLAGS) + +AFTER_INSTALL_SHARED_LIB_CMD = +AFTER_INSTALL_SHARED_LIB_CHOWN = + +BUILD_DLL = yes +LIBEXT = .lib +SHARED_LIBEXT = .lib +DLL_LIBEXT = .dll +DLL_PDBEXT = .pdb +#SHARED_CFLAGS += + +OBJ_MERGE_CMD = ar cr $(GNUSTEP_OBJ_DIR)/$(SUBPROJECT_PRODUCT) $^ ; + +HAVE_BUNDLES = yes +BUNDLE_LD = $(LD) + +BUNDLE_LDFLAGS += -Wl,-dll +BUNDLE_LINK_CMD = \ + $(BUNDLE_LD) $(BUNDLE_LDFLAGS) $(ALL_LDFLAGS) \ + -o $(LDOUT)$(BUNDLE_FILE) \ + $(OBJ_FILES_TO_LINK) \ + $(BUNDLE_LIBFLAGS) $(ALL_LIB_DIRS) $(BUNDLE_LIBS) + +# On Windows MSVC, class name symbols start with '__' +EXTRACT_CLASS_NAMES_COMMAND = $(NM) -Pg $$object_file | sed -n -e '/^._OBJC_CLASS_[A-Za-z0-9_.]* [^U]/ {s/^._OBJC_CLASS_\([A-Za-z0-9_.]*\) [^U].*/\1/p;}' -e '/^__objc_class_name_[A-Za-z0-9_.]* [^U]/ {s/^__objc_class_name_\([A-Za-z0-9_.]*\) [^U].*/\1/p;}' + +endif + +# end Windows MSVC +# +#################################################### #################################################### #