help-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: common.mk


From: Harvey Chapman
Subject: Re: common.mk
Date: Mon, 23 Mar 2009 00:20:38 -0400
User-agent: Postbox 1.0b9 (Macintosh/2009030821)

Ok, I got it to work. After the first attempt using a common .cpp.o: target, I thought I should try to keep the spirit of common make and do it with separate .cpp.o: targets. That also got me to thinking "what if the same source is compiled twice, but differently for different programs/libraries?"

I'm not sure if this list accepts attachments, but I'm going to try attaching all of my files. I'm also going to inline include common.mk for discussion purposes.

My changes were limited to the .cpp.o: targets as well as the *_OBJS definitions. I prefixed all of the object files with $(1)_ or $(2)_ as appropriate. This also required modifying the .d and .P filenames. Oops. I just noticed a bug. I forgot to modify the dependency include lines. Heh, there was a bug in yours, too. You used $(1)_SRCS instead of $(2)... in the library template. On that note, it would be better to swap those two arguments so your library template could be closer to the program one. Ok, fixed. Changes have been made below and to the included file.

BTW Did you mean to override LD_FLAGS and CXXFLAGS in common.mk (right before the foreach statements)? Or were trying to ensure some default values? Perhaps wrap them in "ifndef CXXFLAGS ... endif".

#colours
RESETC=\033[0;37m
COMPILING=\033[1;32m
COMPILERC=\033[0;32m
LINKING=\033[1;33;44m
LINKERC=\033[0;33m
ERRORC=\033[1;31m
SUCCESSC=\033[1;32;44m

.PHONY: all clean $(subdirs)
all: $(subdirs) $(libraries) $(programs)
    @echo "$(SUCCESSC)All targets done!$(RESETC)"

##
## Subdir template
##
define subdir_template
$(1):
    @cd $(1) && $$(MAKE)
endef

##
## Program template
##
define program_template
$(1)_OBJS = $$(addprefix $(1)_, $$($(1)_SRCS:.cpp=.o))

$(1): $$($(1)_OBJS)
    @echo "$$(LINKING)Linking address@hidden(RESETC)"
@echo "$$(LINKERC)$$(CXX) $$^ $$(LDFLAGS) $$($(1)_LDFLAGS) $$($(1)_LIBS:%=-l%) -o address@hidden(RESETC)" @if ! $$(CXX) $$^ $$(LDFLAGS) $$($(1)_LDFLAGS) $$($(1)_LIBS:%=-l%) -o $$@; then \
    echo "$$(ERRORC)Linking failed for $$@ $$(RESETC)"; \
    exit 1; \
    fi

$(1)_%.o: %.cpp
@echo "$$(COMPILERC)$(CXX) $$(CXXFLAGS) $$($(1)_CXXFLAGS) -MMD -c $$< -o address@hidden(RESETC)";
    @if $(CXX) $$(CXXFLAGS) $$($(1)_CXXFLAGS) -MMD -c $$< -o $$@; then \
     cp $(1)_$$*.d $(1)_$$*.P; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$$$//' -e '/^$$$$/ d' -e 's/$$$$/ :/' < $(1)_$$*.d >> $(1)_$$*.P; \
     rm -f $(1)_$$*.d; \
    else \
     echo "$$(ERRORC)Compilation failed for $$@ $$(RESETC)"; \
     rm -f $(1)_$$*.d; \
     exit 1; \
    fi

-include $$(addprefix $(1)_, $$($(1)_SRCS:.cpp=.P))
endef

##
## Library template
##
define library_template
$(2)_OBJS = $$(addprefix $(2)_, $$($(2)_SRCS:.cpp=.o))

$(1): $$($(2)_OBJS)
    @echo "$$(LINKING)Archiving address@hidden(RESETC)"
    ar crus $$@ $$^

$(2)_%.o: %.cpp
@echo "$$(COMPILERC)$(CXX) $$(CXXFLAGS) $$($(2)_CXXFLAGS) -MMD -c $$< -o address@hidden(RESETC)";
    @if $(CXX) $$(CXXFLAGS) $$($(2)_CXXFLAGS) -MMD -c $$< -o $$@; then \
     cp $(2)_$$*.d $(2)_$$*.P; \
sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$$$//' -e '/^$$$$/ d' -e 's/$$$$/ :/' < $(2)_$$*.d >> $(2)_$$*.P; \
     rm -f $(2)_$$*.d; \
    else \
     echo "$$(ERRORC)Compilation failed for $$@ $$(RESETC)"; \
     rm -f $(2)_$$*.d; \
     exit 1; \
    fi

-include $$(addprefix $(2)_, $$($(2)_SRCS:.cpp=.P))
endef

CXXFLAGS=-g -Wall
LIBS=-g -Wall

$(foreach subdir,$(subdirs),$(eval $(call subdir_template,$(subdir))))

$(foreach prog,$(programs),$(eval $(call program_template,$(prog))))

$(foreach lib,$(libraries),$(eval $(call library_template,$(lib),$(subst .,_,$(lib)))))

clean:
    @echo "$(ERRORC)Cleaning...$(RESETC)"
    rm -f *.[aodP] $(programs)
    @if [ "x$(subdirs)" != "x" ]; then \
     for d in $(subdirs); do \
      (cd $$d && $(MAKE) clean); \
     done; \
    fi

#include <stdio.h>

#include "glt.h"
#include "common.h"

int main(int argc, char *argv[])
{
  printf("This really is test2.cpp.\n");
  printf("Calling common, should print 2.\n");
  common();
  printf("%s: %d\n", argv[0], glt());
  return(0);
} // main()
#include <stdio.h>

#include "common.h"

#ifndef VALUE
#error VALUE should have been externally defined!
#endif

int common(void)
{
  printf("%s: %d\n", __FUNCTION__, VALUE);
  return(VALUE);
} // common()
#-*-Makefile-*-

LDFLAGS=-L. -lglt
CXXFLAGS=-I. -DDEBUG -g -Wall

programs=test1 test2
test1_SRCS=test1.cpp common.cpp
test2_SRCS=test2.cpp common.cpp

libraries=libglt.a
libglt_a_SRCS=glt.cpp

test1_CXXFLAGS=-Itest1_dir -DVALUE=1
test2_CXXFLAGS=-Itest2_dir -DVALUE=2
libglt_a_CXXFLAGS=-Iglt_dir

#include common.mk
#include common2.mk
include common3.mk



#include <stdio.h>

#include "glt.h"

#define GLT_VALUE (27)

int glt(void)
{
  printf("%s: %d\n", __FUNCTION__, GLT_VALUE);
  return(GLT_VALUE);
} // glt()
#ifndef GLT_H
#define GLT_H

int glt(void);

#endif // GLT_H
#ifndef COMMON_H
#define COMMON_H

int common(void);

#endif // COMMON_H
#include <stdio.h>

#include "glt.h"
#include "common.h"

int main(int argc, char *argv[])
{
  printf("This really is test1.cpp.\n");
  printf("Calling common, should print 1.\n");
  common();
  printf("%s: %d\n", argv[0], glt());
  return(0);
} // main()
#colours
#RESETC=\033[0;37m
#COMPILING=\033[1;32m
#COMPILERC=\033[0;32m
#LINKING=\033[1;33;44m
#LINKERC=\033[0;33m
#ERRORC=\033[1;31m
#SUCCESSC=\033[1;32;44m

RESETC=\033[0;30m
COMPILING=\033[1;32m
COMPILERC=\033[0;32m
LINKING=\033[1;33;44m
LINKERC=\033[0;33m
ERRORC=\033[1;31m
SUCCESSC=\033[1;32;44m

.PHONY: all clean $(subdirs)
all: $(subdirs) $(libraries) $(programs)
        @echo "$(SUCCESSC)All targets done!$(RESETC)"

##
## Subdir template
##
define subdir_template
$(1):
        @cd $(1) && $$(MAKE)
endef

##
## Program template
##
define program_template
$(1)_OBJS = $$(addprefix $(1)_, $$($(1)_SRCS:.cpp=.o))

$(1): $$($(1)_OBJS)
        @echo "$$(LINKING)Linking address@hidden(RESETC)"
        @echo "$$(LINKERC)$$(CXX) $$^ $$(LDFLAGS) $$($(1)_LDFLAGS) 
$$($(1)_LIBS:%=-l%) -o address@hidden(RESETC)"
        @if ! $$(CXX) $$^ $$(LDFLAGS) $$($(1)_LDFLAGS) $$($(1)_LIBS:%=-l%) -o 
$$@; then \
        echo "$$(ERRORC)Linking failed for $$@ $$(RESETC)"; \
        exit 1; \
        fi

$(1)_%.o: %.cpp
        @echo "$$(COMPILERC)$(CXX) $$(CXXFLAGS) $$($(1)_CXXFLAGS) -MMD -c $$< 
-o address@hidden(RESETC)";
        @if $(CXX) $$(CXXFLAGS) $$($(1)_CXXFLAGS) -MMD -c $$< -o $$@; then \
         cp $(1)_$$*.d $(1)_$$*.P; \
         sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$$$//' -e '/^$$$$/ d' 
-e 's/$$$$/ :/' < $(1)_$$*.d >> $(1)_$$*.P; \
         rm -f $(1)_$$*.d; \
        else \
         echo "$$(ERRORC)Compilation failed for $$@ $$(RESETC)"; \
         rm -f $(1)_$$*.d; \
         exit 1; \
        fi

-include $$(addprefix $(1)_, $$($(1)_SRCS:.cpp=.P))
endef

##
## Library template
##
define library_template
$(2)_OBJS = $$(addprefix $(2)_, $$($(2)_SRCS:.cpp=.o))

$(1): $$($(2)_OBJS)
        @echo "$$(LINKING)Archiving address@hidden(RESETC)"
        ar crus $$@ $$^

$(2)_%.o: %.cpp
        @echo "$$(COMPILERC)$(CXX) $$(CXXFLAGS) $$($(2)_CXXFLAGS) -MMD -c $$< 
-o address@hidden(RESETC)";
        @if $(CXX) $$(CXXFLAGS) $$($(2)_CXXFLAGS) -MMD -c $$< -o $$@; then \
         cp $(2)_$$*.d $(2)_$$*.P; \
         sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$$$//' -e '/^$$$$/ d' 
-e 's/$$$$/ :/' < $(2)_$$*.d >> $(2)_$$*.P; \
         rm -f $(2)_$$*.d; \
        else \
         echo "$$(ERRORC)Compilation failed for $$@ $$(RESETC)"; \
         rm -f $(2)_$$*.d; \
         exit 1; \
        fi

-include $$(addprefix $(2)_, $$($(2)_SRCS:.cpp=.P))
endef

CXXFLAGS=-g -Wall
LIBS=-g -Wall

$(foreach subdir,$(subdirs),$(eval $(call subdir_template,$(subdir))))

$(foreach prog,$(programs),$(eval $(call program_template,$(prog))))

$(foreach lib,$(libraries),$(eval $(call library_template,$(lib),$(subst 
.,_,$(lib)))))

clean:
        @echo "$(ERRORC)Cleaning...$(RESETC)"
        rm -f *.[aodP] $(programs)
        @if [ "x$(subdirs)" != "x" ]; then \
         for d in $(subdirs); do \
          (cd $$d && $(MAKE) clean); \
         done; \
        fi

reply via email to

[Prev in Thread] Current Thread [Next in Thread]