Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support building on Windows with Clang MSVC target #14

Merged
merged 3 commits into from
Feb 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
2021-01-29 Frederik Seiffert <frederik@algoriddim.com>

* 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 <frederik@algoriddim.com>

* common.make:
* target.make:
Check $CLANG_CC instead of comparing $CC with "clang". Fixes checks
when $CC is set to something like /path/to/clang.

2021-01-29 Frederik Seiffert <frederik@algoriddim.com>

* Instance/rules.make:
* Instance/subproject.make:
* common.make:
Link subproject object files directly. Instead of merging all
subproject object files into subproject.o, we now create
subproject.txt containing a list of all object files, and use these
directly in SUBPROJECT_OBJ_FILES.
This enables building on platforms like Windows MSVC where `ld -r` is
not supported, and generally avoids issues with incremental linking
that have historically existed in some linker versions.

2021-01-18 Fred Kiefer <FredKiefer@gmx.de>

* Documentation/news.texi: Update for upcoming release.
Expand Down
31 changes: 27 additions & 4 deletions Instance/library.make
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion Instance/rules.make
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,9 @@ endif

ifneq ($($(GNUSTEP_INSTANCE)_SUBPROJECTS),)
SUBPROJECT_OBJ_FILES = $(foreach d, $($(GNUSTEP_INSTANCE)_SUBPROJECTS), \
$(addprefix $(GNUSTEP_BUILD_DIR)/$(d)/, $(GNUSTEP_OBJ_DIR_NAME)/$(SUBPROJECT_PRODUCT)))
$(foreach o, $(shell cat \
$(GNUSTEP_BUILD_DIR)/$(d)/$(GNUSTEP_OBJ_DIR_NAME)/$(SUBPROJECT_PRODUCT)), \
$(addprefix $(GNUSTEP_BUILD_DIR)/$(d)/, $(o))))
endif

OBJC_OBJS = $(patsubst %.m,%.m$(OEXT),$($(GNUSTEP_INSTANCE)_OBJC_FILES))
Expand Down
2 changes: 1 addition & 1 deletion Instance/subproject.make
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ $(GNUSTEP_OBJ_DIR)/$(SUBPROJECT_PRODUCT): $(OBJ_FILES_TO_LINK)
ifeq ($(OBJ_FILES_TO_LINK),)
$(WARNING_EMPTY_LINKING)
endif
$(ECHO_LINKING)$(OBJ_MERGE_CMD)$(END_ECHO)
@echo "$(OBJ_FILES_TO_LINK)" > $(GNUSTEP_OBJ_DIR)/$(SUBPROJECT_PRODUCT)

#
# Build-header target for framework subprojects
Expand Down
4 changes: 2 additions & 2 deletions common.make
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,7 @@ INTERNAL_OBJCFLAGS = -fno-strict-aliasing
# Linux CentOS 6.5 i386 clang...
# Clang inserts move aligned packed instructions (i.e. movaps,etc) assembly
# code however stack is not aligned causing fault crashes...
ifeq ($(CC),clang)
ifeq ($(CLANG_CC), yes)
ifneq ($(wildcard /etc/redhat-release),"")
RH_RELEASE := $(shell cat 2>/dev/null /etc/redhat-release)
ifeq ($(findstring CentOS,$(RH_RELEASE)),CentOS)
Expand Down Expand Up @@ -815,7 +815,7 @@ endif
#
# Common variables for subprojects
#
SUBPROJECT_PRODUCT = subproject$(OEXT)
SUBPROJECT_PRODUCT = subproject.txt

#
# Set JAVA_HOME if not set.
Expand Down
6 changes: 2 additions & 4 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 2 additions & 4 deletions m4/gs_cc_is_clang.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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}])
Expand Down
71 changes: 64 additions & 7 deletions target.make
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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 \
Expand Down Expand Up @@ -845,7 +852,7 @@ SHARED_LIBEXT = .dll.a
DLL_LIBEXT = .dll
#SHARED_CFLAGS +=

ifneq ($(CC),clang)
ifneq ($(CLANG_CC), yes)
OBJ_MERGE_CMD = \
$(LD) -nostdlib $(OBJ_MERGE_CMD_FLAG) $(CORE_LDFLAGS) -o $(GNUSTEP_OBJ_DIR)/$(SUBPROJECT_PRODUCT) $^ ;
else
Expand All @@ -856,7 +863,7 @@ endif
HAVE_BUNDLES = yes
BUNDLE_LD = $(LD)

ifeq ($(CC),clang)
ifeq ($(CLANG_CC), yes)
BUNDLE_LDFLAGS += -shared -Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--enable-auto-image-base \
Expand Down Expand Up @@ -907,7 +914,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 \
Expand Down Expand Up @@ -944,7 +951,7 @@ SHARED_LIBEXT = .dll.a
DLL_LIBEXT = .dll
#SHARED_CFLAGS +=

ifneq ($(CC),clang)
ifneq ($(CLANG_CC), yes)
OBJ_MERGE_CMD = \
$(LD) -nostdlib $(OBJ_MERGE_CMD_FLAG) $(CORE_LDFLAGS) -o $(GNUSTEP_OBJ_DIR)/$(SUBPROJECT_PRODUCT) $^ ;
else
Expand All @@ -955,7 +962,7 @@ endif
HAVE_BUNDLES = yes
BUNDLE_LD = $(LD)

ifeq ($(CC),clang)
ifeq ($(CLANG_CC), yes)
BUNDLE_LDFLAGS += -shared -Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--enable-auto-image-base \
Expand Down Expand Up @@ -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
#
####################################################

####################################################
#
Expand Down