-
Notifications
You must be signed in to change notification settings - Fork 155
Build system improvements #354
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
Changes from 5 commits
b998b83
eb05a26
01f3873
a73ac1f
0559c8e
6858fc5
1e6e144
fe243ff
818e6b6
eab1b65
ba03da0
cb33be4
f9c6eff
aa25e7f
d412599
ea27839
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,7 +8,6 @@ | |
| # SRCS=<files> ~ list of src files, default is all .c .F .F90 files in VPATH | ||
| # VPFILE=<file> ~ file with list of dirs, used to create VPATH | ||
| # SRCFILE=<file> ~ file with list of src files, used to create SRCS | ||
| # DEPGEN=<exec> ~ dependency generator utility, default is makdep | ||
| # | ||
| # <macro defns> ~ any macro definitions found in this file or the included | ||
| # MACFILE will be over-riden by cmd-line macro definitions | ||
|
|
@@ -31,7 +30,9 @@ VPFILE := NONE | |
| VPATH := . | ||
| SRCFILE := NONE | ||
| SRCS := NONE | ||
| DEPGEN := ./makdep # an externally provided dependency generator | ||
|
|
||
| # dependency generator | ||
| DEPGEN := ./makdep | ||
|
|
||
| ifneq ($(VPATH),.) | ||
| # this variable was specified on cmd line or in an env var | ||
|
|
@@ -58,26 +59,35 @@ endif | |
| OBJS := $(addsuffix .o, $(sort $(basename $(notdir $(SRCS))))) | ||
| DEPS := $(addsuffix .d, $(sort $(basename $(notdir $(SRCS))))) | ||
| INCS := $(patsubst %,-I%, $(VPATH) ) | ||
| OBJS_DEPGEN := $(addprefix $(ICE_CASEDIR)/,$(addsuffix .c, $(notdir $(DEPGEN)))) | ||
| MODDIR:= -I. | ||
| RM := rm | ||
|
|
||
| .SUFFIXES: | ||
| .SUFFIXES: .F90 .F .c .o | ||
|
|
||
| .PHONY: all | ||
| all: $(EXEC) | ||
|
|
||
| .PHONY: cice | ||
| cice: $(EXEC) | ||
|
|
||
| #------------------------------------------------------------------------------- | ||
| # include the file that provides macro definitions required by build rules | ||
| # note: the MACFILE may not be needed for certain goals | ||
| #------------------------------------------------------------------------------- | ||
|
|
||
| ifneq ($(MAKECMDGOALS), db_files) | ||
| -include $(MACFILE) | ||
| endif | ||
| -include $(MACFILE) | ||
|
|
||
| #------------------------------------------------------------------------------- | ||
| # echo file names, paths, compile flags, etc. used during build | ||
| # echo supported targets, file names, paths, compile flags, etc. used during build | ||
| #------------------------------------------------------------------------------- | ||
|
|
||
| .PHONY: targets | ||
| targets: | ||
| @echo " " | ||
| @echo "Supported Makefile Targets are: cice, makdep, depends, mostlyclean, clean, realclean, targets, db_files, db_flags" | ||
|
|
||
| .PHONY: db_files | ||
| db_files: | ||
| @echo " " | ||
| @echo "* EXEC := $(EXEC)" | ||
|
|
@@ -89,12 +99,23 @@ db_files: | |
| @echo "* SRCS := $(SRCS)" | ||
| @echo "* OBJS := $(OBJS)" | ||
| @echo "* DEPS := $(DEPS)" | ||
| @echo "* ULIBS := $(ULIBS)" | ||
| @echo "* SLIBS := $(SLIBS)" | ||
| @echo "* INCLDIR := $(INCLDIR)" | ||
| @echo "* OBJS_DEPGEN := $(OBJS_DEPGEN)" | ||
| .PHONY: db_flags | ||
| db_flags: | ||
| @echo " " | ||
| @echo "* cpp := $(CPP) $(CPPFLAGS) $(CPPDEFS) $(INCS) $(INCLDIR)" | ||
| @echo "* cc := $(CC) -c $(CFLAGS) $(INCS) $(INCLDIR)" | ||
| @echo "* .F.o := $(FC) -c $(FFLAGS) $(FIXEDFLAGS) $(INCS) $(INCLDIR)" | ||
| @echo "* .F90.o := $(FC) -c $(FFLAGS) $(FREEFLAGS) $(INCS) $(INCLDIR)" | ||
| @echo "* $(DEPGEN) := $(SCC) $(CFLAGS_HOST)" | ||
| @echo "* %.d : %.c := $(DEPGEN) $(INCS)" | ||
| @echo "* %.d : %.F := $(DEPGEN) $(INCS)" | ||
| @echo "* %.d : %.F90 := $(DEPGEN) $(INCS)" | ||
| @echo "* %.d : %.H := $(DEPGEN) $(INCS)" | ||
| @echo "* cpp := $(CPP) $(CPPFLAGS) $(CPPDEFS) $(INCLDIR)" | ||
| @echo "* .c.o := $(CC) $(CFLAGS) $(CPPDEFS) $(INCLDIR)" | ||
| @echo "* .F.o := $(FC) -c $(FFLAGS) $(FIXEDFLAGS) $(CPPDEFS) $(INCLDIR)" | ||
| @echo "* .F90.o := $(FC) -c $(FFLAGS) $(FREEFLAGS) $(CPPDEFS) $(MODDIR) $(INCLDIR)" | ||
| @echo "* $(notdir $(EXEC)) := $(LD) $(LDFLAGS) $(ULIBS) $(SLIBS)" | ||
|
|
||
| #------------------------------------------------------------------------------- | ||
| # build rule for makdep: MACFILE, cmd-line, or env vars must provide | ||
|
|
@@ -105,7 +126,8 @@ ifndef $(CFLAGS_HOST) | |
| CFLAGS_HOST := | ||
| endif | ||
|
|
||
| $(DEPGEN): $(ICE_CASEDIR)/makdep.c | ||
| $(DEPGEN): $(OBJS_DEPGEN) | ||
| @ echo "Building makdep" | ||
| $(SCC) -o $@ $(CFLAGS_HOST) $< | ||
|
|
||
| #------------------------------------------------------------------------------- | ||
|
|
@@ -116,46 +138,50 @@ $(EXEC): $(OBJS) | |
| $(LD) -o $(EXEC) $(LDFLAGS) $(OBJS) $(ULIBS) $(SLIBS) | ||
|
|
||
| .c.o: | ||
| $(CC) $(CFLAGS) $(CPPDEFS) $(INCS) $(INCLDIR) $< | ||
| $(CC) $(CFLAGS) $(CPPDEFS) $(INCLDIR) $< | ||
|
|
||
| .F.o: | ||
| $(FC) -c $(FFLAGS) $(FIXEDFLAGS) $(CPPDEFS) $(INCS) $(INCLDIR) $< | ||
| $(FC) -c $(FFLAGS) $(FIXEDFLAGS) $(CPPDEFS) $(INCLDIR) $< | ||
|
|
||
| .F90.o: | ||
| $(FC) -c $(FFLAGS) $(FREEFLAGS) $(CPPDEFS) $(INCS) $(INCLDIR) $< | ||
| $(FC) -c $(FFLAGS) $(FREEFLAGS) $(CPPDEFS) $(MODDIR) $(INCLDIR) $< | ||
|
|
||
| .PHONY: mostlyclean | ||
| mostlyclean: | ||
| $(RM) -f *.f *.f90 | ||
| $(RM) -f $(DEPS) $(OBJS) $(EXEC) | ||
|
|
||
| .PHONY: clean | ||
| clean: | ||
| $(RM) -f *.f *.f90 *.d *.mod *.o $(EXEC) | ||
| # $(RM) -f *.f *.f90 *.d *.$(MOD_SUFFIX) $(OBJS) | ||
| $(RM) -f *.f *.f90 $(DEPS) $(OBJS) $(DEPGEN) $(EXEC) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I suggest the following, which is also simpler : clean:
$(RM) -f *.o *.d *.mod $(EXEC)
realclean: clean
 $(RM) -f $(DEPGEN)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree. I will refactor a bit.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One other comment, the clean that the CICE code does by default is now using the Makefile clean. I changed that recently (maybe in this PR), not sure why it wasn't doing that before. |
||
|
|
||
| .PHONY: realclean | ||
| realclean: | ||
| $(RM) -f *.f *.f90 *.d *.$(MOD_SUFFIX) $(OBJS) $(EXEC) | ||
| $(RM) -f *.f *.f90 *.d *.mod *.o $(DEPS) $(OBJS) $(DEPGEN) $(EXEC) | ||
|
|
||
| #------------------------------------------------------------------------------- | ||
| # Build & include dependency files | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we could also take this opportunity to clean up what is uneeded here : all our files are *.F90 or *.c so the dependency generation for *.F and *.H can be removed. .F.o:
$(FC) -c $(FFLAGS) $(FIXEDFLAGS) $(CPPDEFS) $(INCLDIR) $<
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's OK to leave the other make rules in the Makefile for now. It could be that future development will need them. I don't think it hurts to have them there. I don't think folks actually look at the Makefile all that much. But I could be convinced otherwise. For now, I think I'll leave them as is. |
||
| #------------------------------------------------------------------------------- | ||
| # ASSUMPTIONS: | ||
| # o an externally provided dependency generator, $(DEPGEN), is available, | ||
| # o the dependency generator, $(DEPGEN), can be built, | ||
| # its cmd line syntax is compatible with the build rules below. Eg, for | ||
| # each .o file, there is a corresponding .d (dependency) file, and both | ||
| # will be dependent on the same src file, eg. foo.o foo.d : foo.F90 | ||
| # Also, the dependancy genorator's capabilities, limitations, and assumptions | ||
| # are understood & accepted. | ||
| #------------------------------------------------------------------------------- | ||
|
|
||
| %.d : %.c | ||
| depends: $(DEPS) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure the 'depends' target is needed... it's only use would be to manually recreate the dependencies by calling
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you're right that we may not need depends. I don't think it hurts to have it. Maybe someone wants to just generate the depends without building the rest of the code?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right that it does not hurt to have it. Although in that case I would mention somewhere in the documentation that the dependencies are usually automatically generated. |
||
|
|
||
| %.d : %.c $(DEPGEN) | ||
| @ echo "Building dependency for $@" | ||
| @ $(DEPGEN) -f $(INCS) $< | head -3 > $@ | ||
| %.d : %.F | ||
| %.d : %.F $(DEPGEN) | ||
| @ echo "Building dependency for $@" | ||
| @ $(DEPGEN) -f $(INCS) $< > $@ | ||
| %.d : %.F90 | ||
| %.d : %.F90 $(DEPGEN) | ||
| @ echo "Building dependency for $@" | ||
| @ $(DEPGEN) -f $(INCS) $< > $@ | ||
| %.d : %.H | ||
| %.d : %.H $(DEPGEN) | ||
| @ echo "Building dependency for $@" | ||
| @ $(DEPGEN) -f $(INCS) $< > $@ | ||
|
|
||
|
|
@@ -165,9 +191,15 @@ ifneq ($(MAKECMDGOALS), db_flags) | |
| ifneq ($(MAKECMDGOALS), mostlyclean) | ||
| ifneq ($(MAKECMDGOALS), clean) | ||
| ifneq ($(MAKECMDGOALS), realclean) | ||
| ifneq ($(MAKECMDGOALS), targets) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the new target 'target' should also have it's line here :
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch |
||
| ifneq ($(MAKECMDGOALS), makdep) | ||
| ifneq ($(MAKECMDGOALS), depends) | ||
| -include $(DEPS) | ||
| endif | ||
| endif | ||
| endif | ||
| endif | ||
| endif | ||
| endif | ||
| endif | ||
| endif | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,9 +4,31 @@ | |
| # If the cice binary is passed as an argument and the file exists, | ||
| # copy it into the run directory and don't build the model. | ||
|
|
||
| set dohelp = 0 | ||
| set directmake = 0 | ||
| set target = "UnDEFineD" | ||
| set ciceexe = "UnDEFineD" | ||
| if ($#argv == 1) then | ||
| set ciceexe = $1 | ||
| if ($#argv == 0) then | ||
| # continue, standard way to build | ||
| else if ($#argv == 1) then | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the argument checking is too drastic; it prevents one from using all the features of make (ex. see https://www.gnu.org/software/make/manual/make.html#Instead-of-Execution where some flags that are supported by make are listed). This is one of the reason I passed all arguments in my initial implementation (
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, let me see what I can do. I didn't think about passing command line arguments directly to gmake and wanted to keep the parsing simple. But I can see what that might be useful, I will try to refactor. Thanks for the careful review, not too picky at all!
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @phil-blain, what do you think the requirements are here? Is it just cice.build # standard approach or is there also a requirement for cice.build [gmake option] [gmake option] ... [target] and so forth. Should we support gmake arguments with and/or without a target like gmake --debug --keep-going and others as well? It seems to me if we are going to allow the ability to pass the gmake arguments from cice.build to gmake, it needs to be general, support multiple arguments, and work with a target as well. I will try to do that.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I've got it working, we definitely want the most flexibility and I think that was suggested in the review.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I agree that more flexibility is good, so all of these should work : cice.build # standard approach As a side note, with the changes you already made we are now able to call |
||
| # -h, --help, or target | ||
| if ("$1" == "-h" || "$1" == "--help") then | ||
| set dohelp = 1 | ||
| else | ||
| set directmake = 1 | ||
| set target = $1 | ||
| if ("$target" =~ "-*") then | ||
| echo "${0}: ERROR: invalid target ${target} starts with dash" | ||
| exit -99 | ||
| endif | ||
| endif | ||
| else if ($#argv == 2) then | ||
| # --exe ciceexe (undocumented feature, used only in test suites) | ||
| if ("$1" != "--exe") then | ||
| echo "${0}: ERROR: 2 arguments assume --exe ciceexe" | ||
| exit -99 | ||
| endif | ||
| set ciceexe = $2 | ||
| echo "${0}: ciceexe = ${ciceexe}" | ||
| if (-e ${ciceexe}) then | ||
|
|
||
|
|
@@ -25,6 +47,45 @@ if ($#argv == 1) then | |
| exit 0 | ||
|
|
||
| endif | ||
| else | ||
| echo "${0}: ERROR in arguments" | ||
| set dohelp = 1 | ||
| endif | ||
|
|
||
| if (${dohelp} == 1) then | ||
| cat << EOF1 | ||
|
|
||
| NAME | ||
| cice.build [-h,--help] [target] | ||
|
|
||
| SYNOPSIS | ||
| -h || --help | ||
| target | ||
|
|
||
| DESCRIPTION | ||
| --help, -h : help | ||
| target : specify make target, defined in Makefile | ||
|
|
||
| EXAMPLES | ||
| cice.build | ||
| will build the model using the recommended approach with all the bells and whistles | ||
| cice.build clean | ||
| is an example of a targeted build | ||
| cice.build --help | ||
| will show cice.build help | ||
| cice.build targets | ||
| will show valid Makefile targets | ||
|
|
||
| ADDITIONAL INFORMATION | ||
| The argument implementation is fairly primitive. It accepts only no arguments | ||
| (where it builds the default target), a target argument, or a -h||--help | ||
| argument. These cannot be mixed. | ||
|
|
||
| SEE ALSO | ||
| User Documentation at https://github.com/cice-consortium/cice/ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to link to read-the-docs here instead ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The problem is what version of readthedocs? Almost certainly whatever version we might link in the help output is incorrect. Master documentation is only correct for the current master. For released versions, would we need to manually change the link for each release? This is a case where it's easy for things to get out of sync. While pointing to the general cice repo isn't particularly useful either, at least I feel like it's never incorrect.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand. |
||
|
|
||
| EOF1 | ||
| exit -99 | ||
| endif | ||
|
|
||
| #==================================== | ||
|
|
@@ -47,10 +108,12 @@ set stamp = `date '+%y%m%d-%H%M%S'` | |
| set ICE_BLDLOG_FILE = "cice.bldlog.${stamp}" | ||
| set quiet = ${ICE_QUIETMODE} | ||
|
|
||
| if (${ICE_CLEANBUILD} == 'true') then | ||
| echo "cleaning objdir" | ||
| rm -r -f ${ICE_OBJDIR} | ||
| endif | ||
| # tcraig, this is handled below, is it needed here? | ||
| #if (${ICE_CLEANBUILD} == 'true') then | ||
| # echo "cleaning objdir" | ||
| # rm -r -f ${ICE_OBJDIR} | ||
| #endif | ||
| if !(-d ${ICE_RUNDIR}) mkdir -p ${ICE_RUNDIR} | ||
| if !(-d ${ICE_OBJDIR}) mkdir -p ${ICE_OBJDIR} | ||
| cd ${ICE_OBJDIR} | ||
|
|
||
|
|
@@ -79,6 +142,18 @@ ${ICE_SANDBOX}/cicecore/shared | |
| ${ICE_SANDBOX}/icepack/columnphysics | ||
| EOF | ||
|
|
||
| if (${directmake} == 1) then | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch, I am making those changes.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the second point, I think we decided for a direct make to avoid all the fluff. I think writing the make output to a bldlog file is part of that. I guess I view the circular dependencies as part of the fluff you get if you use the scripts the standard way. Also, the quietmode should not generally be used except by travis. For whatever reason, if we don't use the quiet mode with travis, it creates problems. it either concatenates the raw log file or it makes it very hard to find the errors. this was added just for travis and serves a purpose.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, I guess I viewed the 'fluff' as only the README.case file. But I don't feel strongly about that. So either way is fine. |
||
| echo "make ${target}" | ||
| ${ICE_MACHINE_MAKE} -j ${ICE_MACHINE_BLDTHRDS} VPFILE=Filepath EXEC=${ICE_RUNDIR}/cice \ | ||
| -f ${ICE_CASEDIR}/Makefile MACFILE=${ICE_CASEDIR}/Macros.${ICE_MACHCOMP} ${target} | ||
| set bldstat = ${status} | ||
| if (${bldstat} != 0) then | ||
| echo "${0}: targeted make FAILED" | ||
| exit -99 | ||
| endif | ||
| exit 0 | ||
| endif | ||
|
|
||
| echo " " | ||
| echo ICE_GRID = ${ICE_GRID} | ||
| echo ICE_NTASK = ${ICE_NTASKS} | ||
|
|
@@ -88,13 +163,8 @@ echo "Filepath = " | |
| cat ${ICE_OBJDIR}/Filepath | ||
| echo " " | ||
|
|
||
| echo "building makdep" | ||
| ${ICE_MACHINE_MAKE} \ | ||
| -f ${ICE_CASEDIR}/Makefile MACFILE=${ICE_CASEDIR}/Macros.${ICE_MACHCOMP} makdep || exit 2 | ||
|
|
||
| echo "building cice > ${ICE_OBJDIR}/${ICE_BLDLOG_FILE}" | ||
|
|
||
| if !(-d ${ICE_RUNDIR}) mkdir -p ${ICE_RUNDIR} | ||
| if !($?ICE_MACHINE_BLDTHRDS) then | ||
| set ICE_MACHINE_BLDTHRDS = 1 | ||
| endif | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a single
.PHONY: all cice db_files db_flags mostlyclean clean realcleanline would also workThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, good to know. I may do that instead, it's cleaner.