For people new to coding or using supercomputers to submit jobs, compiling can be a new concept. In programming, a compiler takes source code (e.g. written in C/C++, Python, Fortran, etc.) and translates it into a lower-level programming language (e.g. assembly language or machine code). When a compiler runs successfully, the source code will be converted to an executable program which the computer understands how to run. For more info on compilers, check out this video.
To compile a program, we use the ‘make’ command. When we have multiple source files (which we often do when running complex water management models), a makefile file helps organize directions to give to the compiler. If you are not creating a model from scratch, you may already have an existing makefile which are conventionally named ‘makefile’ or ‘Makefile’. If that is the case, compiling is easy if all the files are in the proper directory. Simply type ‘make’ in the command line interface to compile your code.
If you would like to edit your makefile, create one from scratch, or just want to learn more about the ‘make’ command and makefiles, check out the resources below:
Introduction to ‘make’ and compiler options:
- Video: Make by the Intro to Computer Science course at Harvard
- Video: Libraries by the Intro to Computer Science course at Harvard
- Video: Compilers by the Intro to Computer Science course at Harvard
- Text: Frequently used GCC compiler options
- Text + Tool: GCC code generator tool
Introductory tutorials for makefiles:
Makefile naming:
Makefile macros:
- Text: Makefile – macros
- Text: Special macros for makefiles
Compiler flags:
For a list of compiler flags, see the manual or ‘man’ page for the compiler: e.g. $man <compiler_name>. The convention for naming makefile macros for compiler flags for gcc and g++ are CFLAGS and CPPFLAGS, respectively.
Example Makefile (C or C++):
The conventional file organization for this work is to create a src (or source) and bin (or binary) directory. The source code will go in /src while the makefile and any input files will go in /bin. Once the executable is created, it will be located in /bin as well. Below is a truncated version of a makefile I made for a water treatment plant model (written in C) based on a makefile I found for LRGV (written in C++). In general, there is little difference between a makefile for a program written in C or C++, so this template file can be used for either language by simply commenting or uncommenting the makefile macros for the language for which you want to compile (e.g. CC, CXX, CFLAGS, CPPFLAGS). One special difference between compiling C and C++ is that a common library, math.h, is automatically linked for C++ but must be explicitly linked for C. You’ll notice that I’ve explicitly linked it in the code below, so as long as the C code I’ve written is also valid C++, I should be able to use either compiler since C is a subset of C++. Enjoy!
MAIN_DIR=./.. #from within /bin go to main directory which contains /bin and /src directories SOURCE_DIR = $(MAIN_DIR)/src #navigate to directory which contains source code SOURCES = \ $(SOURCE_DIR)/basin.c \ $(SOURCE_DIR)/breakpt.c \ #I’ll leave out some files for the sake of space $(SOURCE_DIR)/unittype.c \ $(SOURCE_DIR)/uptable.c \ $(SOURCE_DIR)/writewtp.c \ OBJECTS=$(SOURCES:.c=.o) #name object files based on .c files CC=gcc #select the type of compiler: this once in for C #CXX=g++ CFLAGS=-c -O3 -Wall -I. -I$(SOURCE_DIR) #set flags for gcc #CPPFLAGS=-c -O3 -Wall -I. -I$(SOURCE_DIR) #set flags for g++ LIBS=-lm # link libraries (e.g. math.h with -lm: goo.gl/Bgq75V) EXECUTABLE=wtp_v2-2_borg-mp #name of the executable file all: $(SOURCES) $(EXECUTABLE) rm -rf $(SOURCE_DIR)/*.o $(EXECUTABLE): $(OBJECTS) $(CC) $(OBJECTS) -o $@ $(LIBS) .c.o: $(CC) $(CFLAGS) $^ -o $@ clean: #’make clean’ will remove all compilation files rm -f $(SOURCE_DIR)/*.o $(EXECUTABLE)