[RFC] [PATCH] GNU make based build system for Winelib applications
Kirill Smelkov
kirr at mns.spb.ru
Sun Sep 2 07:05:35 CDT 2007
Hello Wine developers, Francois!
I am going to port some Win32 applications to GNU/Linux and though it would be
useful to improve the build system for Winelib applications.
Current status and Motivation
=============================
1. Wine in-tree Makefiles for programs & dlls are pretty much good and
maintainable, but they lack C++ support.
2. Initial approach taken by winemaker (I used it in 2003-2004) was to adapt
Wine's make rules to support C++ .
3. At present winemaker dropped supplying above mentioned rules and generates
very simple makefiles. To me this approach have several problems:
- lack of dependency tracking
- hard to maintain Makefiles.
The rules generated are substituted in each Makefile instead of being in one
place.
- good as a starting point, but not a complete solution.
Winemaker already relies on GNU toolchain (in form of gcc and g++), and I
though::
Why not use GNU make with all available extensions when necessary, and
deploy a simple full-featured build system for Winelib based applications
The result is presented here for public review.
Comments, suggestions?
Features
========
* support C, C++ and resource files.
* automatic dependency tracking for C and C++.
* beautified build output (to increase SNR and concentrate on errors and
warnings).
* winemaker patches provided (although I don't know Perl -- help needed,
Francois?).
* Tested with GNU make 3.81. This version of GNU make was released in 2006 and
is present in all recent Linux distributions.
Usage example
=============
I attach winelib-gnu-make.tar.gz where an interested reader can see Winemake
build system usage.
For usage example see directory clock+wow32/ . There I provide example of how
to build 1 program and 2 dlls.
Original clock.exe & wow32.dll processed by winemaker are located in misc/ for
comparison.
-------------- next part --------------
>From 0d19d4bd95a97dc7d582872f22f4b393521709f8 Mon Sep 17 00:00:00 2001
From: Kirill Smelkov <kirr at mns.spb.ru>
Date: Sun, 2 Sep 2007 15:51:21 +0400
Subject: [PATCH] winemake: GNU make based build system for Winelib applications
---
include/Makefile.in | 4 +
include/wine/Winemake.include | 265 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 269 insertions(+), 0 deletions(-)
diff --git a/include/Makefile.in b/include/Makefile.in
index 4607006..80fcb6a 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -64,9 +64,13 @@ IDL_H_SRCS = \
IDL_TLB_SRCS = \
stdole2.idl
+WINEMAKE_SRCS = \
+ wine/Winemake.include
+
SRCDIR_INCLUDES = \
$(IDL_TLB_SRCS) \
$(IDL_H_SRCS) \
+ $(WINEMAKE_SRCS) \
accctrl.h \
aclapi.h \
adshlp.h \
diff --git a/include/wine/Winemake.include b/include/wine/Winemake.include
new file mode 100644
index 0000000..f9d9f0d
--- /dev/null
+++ b/include/wine/Winemake.include
@@ -0,0 +1,265 @@
+# =============================================================================
+# GNU make based build system for Winelib applications
+# Some of ideas taken from Kbuild, Wine build system & Automake
+#
+# Started: 2007 Kirill Smelkov <kirr at mns.spb.ru>
+
+
+# Do not:
+# o use make's built-in rules and variables
+# (this increases performance and avoid hard-to-debug behavour);
+# o print "Entering directory ...";
+# XXX As it is, MAKEFLAGS affects only the next-level invocations of make.
+# XXX At least .SUFFIXES: clear built-in rules for top-level.
+MAKEFLAGS += -rR --no-print-directory
+
+# Do not use built-in rules
+.SUFFIXES:
+
+# =============================================================================
+# Config
+CC := winegcc
+CXX := wineg++
+RC := wrc
+
+RM := rm -f
+LN_S := ln -sf
+
+DEPDIR := .deps
+
+ifeq ($(MAKELEVEL),0)
+export TOP := $(CURDIR)
+
+# hook winemake into make's path, so Makefiles in subdirectories can just do
+# 'include Winemake.include'
+winemake_root:= $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+MAKEFLAGS += -I $(winemake_root)
+endif
+
+# load build configuration
+-include $(TOP)/.config
+
+
+# =============================================================================
+# Build internals
+
+# quiet/verbose
+V ?= 0
+ifneq ($(V),0)
+ quiet :=
+ Q :=
+else
+ quiet := quiet_
+ Q := @
+endif
+
+
+# Main goal
+.PHONY : all $(SUBDIRS)
+all : $(SUBDIRS) $(MODULES)
+
+$(SUBDIRS):
+ $(Q)$(MAKE) -C $@
+
+# Rules for cleaning
+CLEAN_FILES = y.tab.c y.tab.h lex.yy.c core *.orig *.rej \
+ \\\#*\\\# *~ *% .\\\#*
+
+clean:: $(SUBDIRS:%=%/__clean__) $(EXTRASUBDIRS:%=%/__clean__)
+ $(call qpretty,CLEAN $(if $(curdir),$(curdir),.))
+ $(Q)$(RM) $(CLEAN_FILES)
+ $(Q)$(RM) -R $(DEPDIR)
+
+$(SUBDIRS:%=%/__clean__): FORCE
+ $(Q)$(MAKE) -C $(dir $@) clean
+
+
+.PHONY : FORCE
+
+# =============================================================================
+
+# canonicalize a name
+# UC: $(call canonicalize, foo-xxx.exe) -> foo_xxx_exe
+canonicalize = $(subst -,_,$(subst .,_,$1))
+
+# handy canonical arguments
+1C = $(call canonicalize,$1)
+*C = $(call canonicalize,$*)
+ at C = $(call canonicalize,$@)
+
+# handy variables
+1C_SRC = $($(1C)_SRC)
+ at C_LINK = $($(@C)_LINK)
+
+# $! == eye-candy $@ , $(1!) == eye-candy $1
+curdir := $(patsubst $(TOP)%,%,$(CURDIR))
+curdir := $(patsubst /%,%,$(curdir))
+curdir := $(curdir)$(if $(curdir),/)
+! = $(curdir)$@
+1! = $(curdir)$1
+
+
+# Utils
+
+# filter list items by extension
+# UC: $(call __filter-ext,.cxx,hello.c abc.C arm.cxx) -> arm.cxx
+__filter-ext= $(filter %$1,$2)
+
+# filter list items by extension, then substiture extension for filtered items
+# UC: $(call __subst-ext,.c,.o,hello.c abc.cpp) -> hello.o
+__subst-ext= $(patsubst %$1,%$2,$(call __filter-ext,$1,$3))
+
+# C++ has so many extensions ...
+c++-ext := cpp cxx cc C c++
+
+# extract X-sources from sources list
+# UC: $(call __src-c, hello.c hi.cpp ...) -> hello.c
+__src-c = $(filter %.c,$1)
+__src-cxx = $(strip $(foreach ext,$(c++-ext),$(filter %.$(ext),$1)))
+__src-rc = $(filter %.rc,$1)
+__src-spec= $(filter %.spec,$1)
+
+# extract X-sources from a module
+# UC: $(call src-c,foo.exe)
+src-c = $(call __src-c,$(1C_SRC))
+src-cxx = $(call __src-cxx,$(1C_SRC))
+src-rc = $(call __src-rc,$(1C_SRC))
+src-spec= $(call __src-spec,$(1C_SRC))
+
+# list of unknown sources for a module
+# it is an error when this list is not empty
+src-unknown = $(filter-out $(foreach srctype,c cxx rc spec,$(call src-$(srctype),$1)), $(1C_SRC))
+
+
+# extract X-objects from source list
+# UC: $(call objs-c, hello.c hi.cpp ...) -> hello.o
+__objs-c = $(call __subst-ext,.c,.o,$1)
+__objs-cxx= $(foreach ext,$(c++-ext),$(call __subst-ext,.$(ext),.o,$1))
+__objs-rc = $(call __subst-ext,.rc,.res,$1)
+
+# extract X-objects from a module
+# UC: objs = $(call objs-c, foo)
+objs-c = $(call __objs-c,$(1C_SRC))
+objs-cxx= $(call __objs-cxx,$(1C_SRC))
+objs-rc = $(call __objs-rc,$(1C_SRC))
+
+
+# Autogen modules templates
+__SRC_UNKNOWN :=
+
+define MODULE_template
+$(1C)_SRC_C := $$(call src-c,$1)
+$(1C)_SRC_CXX := $$(call src-cxx,$1)
+$(1C)_SRC_RC := $$(call src-rc,$1)
+$(1C)_SRC_SPEC := $$(call src-spec,$1)
+
+$(1C)_OBJS := $(foreach lang,c cxx rc,$$(call objs-$(lang),$1))
+
+# link command (C++ programs have to be linked by C++ compiler)
+$(1C)_LINK := $$(if $$($(1C)_SRC_CXX),$(CXX),$(CC))
+
+# explicit dependencies (to keep objects precious)
+$1 : $$($(1C)_OBJS)
+
+# objects want $(DEPDIR)
+$$($(1C)_OBJS) : | $(DEPDIR)
+
+# include auto-generated dependencies
+-include $$(foreach obj,$$(basename $$($(1C)_OBJS)),$(DEPDIR)/$$(obj).d)
+
+$(1C)_SRC_UNKNOWN:=$$(call src-unknown,$1)
+__SRC_UNKNOWN += $$($(1C)_SRC_UNKNOWN)
+clean::
+ $$(call qpretty,CLEAN $(1!))
+ $(Q)$(RM) $$($(1C)_OBJS) $1.so $1
+endef
+
+$(foreach module,$(MODULES),$(eval $(call MODULE_template,$(module))))
+
+# Verify whether all sources provided are of known type
+__SRC_UNKNOWN := $(strip $(__SRC_UNKNOWN))
+ifneq "$(__SRC_UNKNOWN)" ""
+$(error E: Source(s) of unknown type: [ $(__SRC_UNKNOWN) ] )
+endif
+
+
+# =============================================================================
+# Common
+
+# Convenient variables
+comma := ,
+squote := '
+empty :=
+space := $(empty) $(empty)
+
+###
+# Escape single quote for use in echo statements
+escsq = $(subst $(squote),'\$(squote)',$1)
+
+# echo command.
+# Short version is used, if $(quiet) equals `quiet_', otherwise full one.
+echo-cmd = $(if $($(quiet)cmd_$(1)),\
+ echo ' $(call escsq,$($(quiet)cmd_$(1)))';)
+
+# echo pretty string [only in quiet mode]
+qpretty = $(if $(Q), at echo ' $1')
+
+# printing commands
+cmd = @$(echo-cmd) $(cmd_$(1))
+
+# =============================================================================
+# Rules
+
+quiet_cmd_mkdir = MKDIR $!
+ cmd_mkdir = mkdir -p $@
+
+# XXX do we need '-MT $@ -MP' here?
+cc_dep_opts = -MD -MF $(@:%.o=$(DEPDIR)/%.d)
+
+quiet_cmd_c_c = CC $!
+ cmd_c_c = $(CC) -c $(CFLAGS) $(CEXTRA) $(DEFINCL) -o $@ $< $(cc_dep_opts)
+
+quiet_cmd_cxx_c = C++ $!
+ cmd_cxx_c = $(CXX) -c $(CXXFLAGS) $(CXXEXTRA) $(DEFINCL) -o $@ $< $(cc_dep_opts)
+
+# TODO add dependency generation for RC command
+quiet_cmd_rc_x = RC $!
+ cmd_rc_x = $(RC) $(RCFLAGS) $(RCEXTRA) $(DEFINCL) -fo$@ $<
+
+
+$(DEPDIR):
+ $(call cmd,mkdir)
+
+%.o : %.c
+ $(call cmd,c_c)
+
+define rule_cxx_ext
+%.o : %.$1
+ $$(call cmd,cxx_c)
+endef
+$(foreach ext,$(c++-ext),$(eval $(call rule_cxx_ext,$(ext))))
+
+%.res : %.rc
+ $(call cmd,rc_x)
+
+
+DEFLIB := $(LIBRARY_PATH) $(LIBRARIES) $(DLL_PATH)
+
+quiet_cmd_link_exe = EXE $!
+ cmd_link_exe = $(@C_LINK) $(LDFLAGS) $(LDEXTRA) -o [email protected] $+ $(DEFLIB) $(DLLS:%=-l%) $(LIBS:%=-l%)
+ cmd_exe_fixup= echo -e '\#!/bin/sh\n\nexec wine $$0.so\n' > $@ && chmod a+x $@
+
+quiet_cmd_link_dll = DLL $!
+ cmd_link_dll = $(@C_LINK) $(LDFLAGS) $(LDEXTRA) -shared -o [email protected] $+ $(DEFLIB) $(DLLS:%=-l%) $(LIBS:%=-l%)
+ cmd_dll_fixup= $(LN_S) $(@F).so $(@D)/$(@F:.so=)
+
+.SECONDEXPANSION:
+%.exe :
+ $(call cmd,link_exe)
+ $(call cmd,exe_fixup)
+
+%.dll : $$($$(@C)_SRC_SPEC)
+ $(call cmd,link_dll)
+ $(call cmd,dll_fixup)
+
+
--
1.4.4.4
-------------- next part --------------
>From b32468fe4a97cff58b2dc4b947d01cd319b82834 Mon Sep 17 00:00:00 2001
From: Kirill Smelkov <kirr at mns.spb.ru>
Date: Sun, 2 Sep 2007 15:52:39 +0400
Subject: [PATCH] winemaker: adapt to using Winemake.include
As I don't know Perl,
This patch requires help from winemaker maintainer.
---
tools/winemaker | 163 +++++++++++++++----------------------------------------
1 files changed, 44 insertions(+), 119 deletions(-)
diff --git a/tools/winemaker b/tools/winemaker
index 960804d..4bde7e4 100755
--- a/tools/winemaker
+++ b/tools/winemaker
@@ -19,7 +19,7 @@ use strict;
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#
-my $version="0.6.0";
+my $version="0.7.0";
use Cwd;
use File::Basename;
@@ -204,6 +204,9 @@ my $T_LIBRARIES=16;
# The list of dependencies between targets
my $T_DEPENDS=17;
+##
+# List of linker options
+my $T_LDEXTRA = 18;
# The following constants define the recognized types of target
@@ -270,6 +273,7 @@ sub target_init($)
@$target[$T_DLLS]=[];
@$target[$T_LIBRARY_PATH]=[];
@$target[$T_LIBRARIES]=[];
+ @$target[$T_LDEXTRA]=[];
}
@@ -799,7 +803,6 @@ sub source_scan_directory($$$$)
push @local_depends,"$target_name.so";
push @local_dlls,$target_name;
my $canon=canonize($target_name);
- push @{@$target[$T_LDFLAGS]},("-shared","\$(${canon}_MODULE:%=%.spec)");
} else {
@$target[$T_TYPE]=$opt_target_type;
push @exe_list,$target;
@@ -912,6 +915,7 @@ sub source_scan_directory($$$$)
if ((@$project_settings[$T_FLAGS] & $TF_NOMSVCRT) == 0) {
push @{@$project_settings[$T_CEXTRA]},"-mno-cygwin";
push @{@$project_settings[$T_CXXEXTRA]},"-mno-cygwin";
+ push @{@$project_settings[$T_LDEXTRA]},"-mno-cygwin";
}
if (@$project_settings[$T_FLAGS] & $TF_MFC) {
@@ -1527,7 +1531,7 @@ sub generate_list($$$;$)
my $first=$name;
if ($name) {
- printf FILEO "%-22s=",$name;
+ printf FILEO "%-21s:=",$name;
}
if (defined $list) {
foreach my $item (@$list) {
@@ -1560,6 +1564,7 @@ sub generate_project_files($)
my $project_settings=@$project[$P_SETTINGS];
my @dll_list=();
my @exe_list=();
+ my @all_list=();
# Then sort the targets and separate the libraries from the programs
foreach my $target (sort { @$a[$T_NAME] cmp @$b[$T_NAME] } @{@$project[$P_TARGETS]}) {
@@ -1569,6 +1574,9 @@ sub generate_project_files($)
push @exe_list,$target;
}
}
+
+ push @all_list, @exe_list, @dll_list;
+
@$project[$P_TARGETS]=[];
push @{@$project[$P_TARGETS]}, @dll_list;
push @{@$project[$P_TARGETS]}, @exe_list;
@@ -1582,7 +1590,7 @@ sub generate_project_files($)
print FILEO "### Generated by Winemaker\n";
print FILEO "\n\n";
- generate_list("SRCDIR",1,[ "." ]);
+ #generate_list("SRCDIR",1,[ "." ]);
if (@$project[$P_PATH] eq "") {
# This is the main project. It is also responsible for recursively
# calling the other projects
@@ -1597,20 +1605,18 @@ sub generate_project_files($)
});
}
if (@{@$project[$P_TARGETS]} > 0) {
- generate_list("DLLS",1,\@dll_list,sub
+ generate_list("MODULES",1,\@all_list,sub
{
return @{$_[0]}[$T_NAME];
});
- generate_list("EXES",1,\@exe_list,sub
- {
- return "@{$_[0]}[$T_NAME]";
- });
+
print FILEO "\n\n\n";
print FILEO "### Common settings\n\n";
# Make it so that the project-wide settings override the global settings
generate_list("CEXTRA",1,@$project_settings[$T_CEXTRA]);
generate_list("CXXEXTRA",1,@$project_settings[$T_CXXEXTRA]);
+ generate_list("LDEXTRA",1,@$project_settings[$T_LDEXTRA]);
generate_list("RCEXTRA",1,@$project_settings[$T_RCEXTRA]);
generate_list("INCLUDE_PATH",1,@$project_settings[$T_INCLUDE_PATH]);
generate_list("DLL_PATH",1,@$project_settings[$T_DLL_PATH]);
@@ -1622,6 +1628,7 @@ sub generate_project_files($)
@{@$project_settings[$T_SOURCES_CXX]}+
@{@$project_settings[$T_SOURCES_RC]};
my $no_extra=($extra_source_count == 0);
+ # XXX what to do with extra src ???
if (!$no_extra) {
print FILEO "### Extra source lists\n\n";
generate_list("EXTRA_C_SRCS",1,@$project_settings[$T_SOURCES_C]);
@@ -1638,121 +1645,39 @@ sub generate_project_files($)
my $canon=canonize("@$target[$T_NAME]");
$canon =~ s+_so$++;
- generate_list("${canon}_MODULE",1,[@$target[$T_NAME]]);
- generate_list("${canon}_C_SRCS",1,@$target[$T_SOURCES_C]);
- generate_list("${canon}_CXX_SRCS",1,@$target[$T_SOURCES_CXX]);
- generate_list("${canon}_RC_SRCS",1,@$target[$T_SOURCES_RC]);
- generate_list("${canon}_LDFLAGS",1,@$target[$T_LDFLAGS]);
- generate_list("${canon}_DLL_PATH",1,@$target[$T_DLL_PATH]);
- generate_list("${canon}_DLLS",1,@$target[$T_DLLS]);
- generate_list("${canon}_LIBRARY_PATH",1,@$target[$T_LIBRARY_PATH]);
- generate_list("${canon}_LIBRARIES",1,@$target[$T_LIBRARIES]);
- print FILEO "\n";
- generate_list("${canon}_OBJS",1,["\$(${canon}_C_SRCS:.c=.o)","\$(${canon}_CXX_SRCS:.cpp=.o)","\$(${canon}_RC_SRCS:.rc=.res)"]);
- print FILEO "\n\n\n";
- }
- print FILEO "### Global source lists\n\n";
- generate_list("C_SRCS",$no_extra,@$project[$P_TARGETS],sub
- {
- my $canon=canonize(@{$_[0]}[$T_NAME]);
- $canon =~ s+_so$++;
- return "\$(${canon}_C_SRCS)";
- });
- if (!$no_extra) {
- generate_list("",1,[ "\$(EXTRA_C_SRCS)" ]);
- }
- generate_list("CXX_SRCS",$no_extra,@$project[$P_TARGETS],sub
- {
- my $canon=canonize(@{$_[0]}[$T_NAME]);
- $canon =~ s+_so$++;
- return "\$(${canon}_CXX_SRCS)";
- });
- if (!$no_extra) {
- generate_list("",1,[ "\$(EXTRA_CXX_SRCS)" ]);
- }
- generate_list("RC_SRCS",$no_extra,@$project[$P_TARGETS],sub
- {
- my $canon=canonize(@{$_[0]}[$T_NAME]);
- $canon =~ s+_so$++;
- return "\$(${canon}_RC_SRCS)";
- });
- if (!$no_extra) {
- generate_list("",1,[ "\$(EXTRA_RC_SRCS)" ]);
- }
- }
- print FILEO "\n\n";
- print FILEO "### Tools\n\n";
- print FILEO "CC = winegcc\n";
- print FILEO "CXX = wineg++\n";
- print FILEO "RC = wrc\n";
- print FILEO "\n\n";
+ my $all_src=[@{@$target[$T_SOURCES_C]}, @{@$target[$T_SOURCES_CXX]}, @{@$target[$T_SOURCES_RC]}];
- print FILEO "### Generic targets\n\n";
- print FILEO "all:";
- if (@$project[$P_PATH] eq "") {
- print FILEO " \$(SUBDIRS)";
- }
- if (@{@$project[$P_TARGETS]} > 0) {
- print FILEO " \$(DLLS:%=%.so) \$(EXES:%=%.so)";
- }
- print FILEO "\n\n";
- print FILEO "### Build rules\n";
- print FILEO "\n";
- print FILEO ".PHONY: all clean dummy\n";
- print FILEO "\n";
- print FILEO "\$(SUBDIRS): dummy\n";
- print FILEO "\t\@cd \$\@ && \$(MAKE)\n";
- print FILEO "\n";
- print FILEO "# Implicit rules\n";
- print FILEO "\n";
- print FILEO ".SUFFIXES: .cpp .rc .res\n";
- print FILEO "DEFINCL = \$(INCLUDE_PATH) \$(DEFINES) \$(OPTIONS)\n";
- print FILEO "\n";
- print FILEO ".c.o:\n";
- print FILEO "\t\$(CC) -c \$(CFLAGS) \$(CEXTRA) \$(DEFINCL) -o \$\@ \$<\n";
- print FILEO "\n";
- print FILEO ".cpp.o:\n";
- print FILEO "\t\$(CXX) -c \$(CXXFLAGS) \$(CXXEXTRA) \$(DEFINCL) -o \$\@ \$<\n";
- print FILEO "\n";
- print FILEO ".cxx.o:\n";
- print FILEO "\t\$(CXX) -c \$(CXXFLAGS) \$(CXXEXTRA) \$(DEFINCL) -o \$\@ \$<\n";
- print FILEO "\n";
- print FILEO ".rc.res:\n";
- print FILEO "\t\$(RC) \$(RCFLAGS) \$(RCEXTRA) \$(DEFINCL) -fo\$@ \$<\n";
- print FILEO "\n";
- print FILEO "# Rules for cleaning\n";
- print FILEO "\n";
- print FILEO "CLEAN_FILES = y.tab.c y.tab.h lex.yy.c core *.orig *.rej \\\n";
- print FILEO " \\\\\\#*\\\\\\# *~ *% .\\\\\\#*\n";
- print FILEO "\n";
- print FILEO "clean:: \$(SUBDIRS:%=%/__clean__) \$(EXTRASUBDIRS:%=%/__clean__)\n";
- print FILEO "\t\$(RM) \$(CLEAN_FILES) \$(RC_SRCS:.rc=.res) \$(C_SRCS:.c=.o) \$(CXX_SRCS:.cpp=.o)\n";
- print FILEO "\t\$(RM) \$(DLLS:%=%.so) \$(EXES:%=%.so) \$(EXES:%.exe=%)\n";
- print FILEO "\n";
- print FILEO "\$(SUBDIRS:%=%/__clean__): dummy\n";
- print FILEO "\tcd `dirname \$\@` && \$(MAKE) clean\n";
- print FILEO "\n";
- print FILEO "\$(EXTRASUBDIRS:%=%/__clean__): dummy\n";
- print FILEO "\t-cd `dirname \$\@` && \$(RM) \$(CLEAN_FILES)\n";
- print FILEO "\n";
+ # insert spec file for .dll targets
+ if (@$target[$T_TYPE] == $TT_DLL) {
+ my $basename=@$target[$T_NAME];
+ $basename=~ s/\.(dll|exe)$//i;
+ push @$all_src, "$basename.spec";
+ }
- if (@{@$project[$P_TARGETS]} > 0) {
- print FILEO "### Target specific build rules\n";
- print FILEO "DEFLIB = \$(LIBRARY_PATH) \$(LIBRARIES) \$(DLL_PATH)\n\n";
- foreach my $target (@{@$project[$P_TARGETS]}) {
- my $canon=canonize("@$target[$T_NAME]");
- $canon =~ s/_so$//;
+ generate_list("${canon}_SRC",1,[@$all_src]);
+ print FILEO "\n";
- print FILEO "\$(${canon}_MODULE).so: \$(${canon}_OBJS)\n";
- if (@{@$target[$T_SOURCES_CXX]} > 0 or @{@$project_settings[$T_SOURCES_CXX]} > 0) {
- print FILEO "\t\$(CXX)";
- } else {
- print FILEO "\t\$(CC)";
- }
- print FILEO " \$(${canon}_LDFLAGS) -o \$\@ \$(${canon}_OBJS) \$(${canon}_LIBRARY_PATH) \$(DEFLIB) \$(${canon}_DLLS:%=-l%) \$(${canon}_LIBRARIES:%=-l%)\n";
- print FILEO "\n\n";
+ generate_list("@$target[$T_NAME]:\tLDFLAGS",1,@$target[$T_LDFLAGS]);
+ generate_list("@$target[$T_NAME]:\tDLL_PATH",1,@$target[$T_DLL_PATH]);
+ generate_list("@$target[$T_NAME]:\tDLLS",1,@$target[$T_DLLS]);
+ generate_list("@$target[$T_NAME]:\tLIBRARY_PATH",1,@$target[$T_LIBRARY_PATH]);
+ generate_list("@$target[$T_NAME]:\tLIBS",1,@$target[$T_LIBRARIES]);
+
+ print FILEO "\n\n\n";
}
}
+ print FILEO "\n\n";
+ print FILEO "# Include rules\n";
+ print FILEO "#\n";
+ print FILEO "# if located in non-std place, set in your environment\n";
+ print FILEO '# MAKEFLAGS="-I /path/to/winemake-include-dir/"',"\n";
+ print FILEO "#\n";
+ print FILEO "# or put Winemake.include at the root of your project.\n";
+ print FILEO "# or include Winemake.include in the top-level Makefile with explicit path.\n";
+ print FILEO "#\n";
+ print FILEO "# NB: std-places (as stated in GNU make manual):\n";
+ print FILEO "# /usr/include /usr/local/include ...\n";
+ print FILEO "include Winemake.include";
close(FILEO);
}
--
1.4.4.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: winelib-gnu-make.tar.gz
Type: application/x-tgz
Size: 21289 bytes
Desc: not available
Url : http://www.winehq.org/pipermail/wine-devel/attachments/20070902/4f06e34d/winelib-gnu-make.tar-0001.bin
More information about the wine-devel
mailing list