1#========================================================================
  2#
  3# NAME
  4# 
  5#     makefile
  6#
  7# DESCRIPTION
  8# 
  9#     Makefile for UNIX systems and Windows + Cygwin for compiling 
 10#     and testing CRCDemo.
 11#
 12#     Run from a command window by calling
 13#
 14#         make
 15#
 16#     To compile and test the program, type
 17#
 18#         make test
 19#
 20#
 21#  LEGAL
 22#
 23#     FFT Version 1.6 -  An FFT utility library in C++.
 24#     Copyright (C) 1999-2024 by Sean Erik O'Connor.  All Rights Reserved.
 25#
 26#     This program is free software: you can redistribute it and/or modify
 27#     it under the terms of the GNU General Public License as published by
 28#     the Free Software Foundation, either version 3 of the License, or
 29#     (at your option) any later version.
 30#
 31#     This program is distributed in the hope that it will be useful,
 32#     but WITHOUT ANY WARRANTY; without even the implied warranty of
 33#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 34#     GNU General Public License for more details.
 35#
 36#     You should have received a copy of the GNU General Public License
 37#     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 38#    
 39#     The author's address is seanerikoconnor!AT!gmail!DOT!com
 40#     with the !DOT! replaced by . and the !AT! replaced by @
 41#
 42#=============================================================================
 43
 44# Put this pseudo-target first so make without command line options executes it.
 45all: makeAllExes
 46
 47
 48#============================== Configuration ================================
 49
 50# Find out which operating system we are running on:  macOS, Linux, etc.
 51UNAME := $(shell uname -s)
 52
 53# macOS.  Tested on my MacBook Pro laptop mid-2015 model with Intel x86_64 architecture, also my MacBook Pro 2021 M1 Max ARM CPU.
 54ifeq ($(UNAME), Darwin)
 55PLATFORM = mac
 56endif
 57
 58# Linux.  Tested on my Ubuntu Linux system running on my Cyperpower PC with a 64-bit AMD CPU.
 59ifeq ($(UNAME), Linux)
 60PLATFORM = linux
 61endif
 62
 63# Cygwin.  For cygwin 2.2 64-bit on Windows 10 64-bit.  Not tested.  From https://en.wikipedia.org/wiki/Uname
 64ifeq ($(UNAME), CYGWIN_NT-10.0)
 65PLATFORM = cygwin
 66endif
 67
 68# Default platform is macOS
 69ifndef PLATFORM
 70PLATFORM = mac
 71endif
 72
 73
 74#============================== Compiler, Linker, and CPU architecture =======================
 75
 76# Type of compiler to use.
 77# Mac uses the clang C++/C compiler, same as XCode.
 78ifeq ($(PLATFORM), mac)
 79CPP     = clang++
 80CPPLINK = clang++
 81CC      = clang++ -x c
 82CCLINK  = clang 
 83# Ubuntu Linux uses the gcc C++/C compiler.
 84else ifeq ($(PLATFORM), linux)
 85CPP     = g++
 86CPPLINK = g++
 87CC      = gcc -x c
 88CCLINK  = gcc
 89# Windows uses the GNU C++/C compiler.
 90else ifeq ($(PLATFORM), cygwin)
 91CPP     = g++
 92CPPLINK = g++
 93CC      = gcc
 94CCLINK  = gcc
 95endif
 96
 97# Architecture (CPU type).
 98ifeq ($(PLATFORM), mac)
 99# The new MacBook Pro uses Apple Silicon CPU based on ARM.  
100ARCH = -arch arm64
101# If you specify x86 architecture, the executable will still run due to Apple's Rosetta 2 Intel to ARM code translation, 
102# but much more slowly than if you use the native CPU architecture.
103#ARCH = -arch x86_64
104else ifeq ($(PLATFORM), linux)
105ARCH = 
106else ifeq ($(PLATFORM), cygwin)
107ARCH =
108endif
109
110
111
112#============================== Compiler and Linker Settings, Libraries =======================
113
114# Compile the C++20 standard and its libraries.
115ifeq ($(PLATFORM), cygwin)
116CPP_OPTIONS = -std=c++20
117CPP_LIBS = -L"/usr/lib" 
118C_OPTIONS =
119C_LIBS = -L"/usr/lib" 
120else ifeq ($(PLATFORM), mac)
121CPP_OPTIONS = -std=c++20 -stdlib=libc++
122C_OPTIONS =
123CPP_LIBS = 
124C_LIBS =
125else ifeq ($(PLATFORM), linux)
126CPP_OPTIONS = -std=c++20 -D USE_EXPERIMENTAL_FILESYSTEM_GNU_CPP
127C_OPTIONS =
128CPP_LIBS = -lm -lstdc++fs 
129C_LIBS = -lm -lstdc++fs
130endif
131
132# Link flags.
133ifeq ($(PLATFORM), mac)
134LFLAGS = $(ARCH)
135else ifeq ($(PLATFORM), linux)
136LFLAGS =
137endif
138
139#============================== Optimization =======================
140
141# Select on = optimized code for speed.  off = compile for debugging
142OPTIMIZATION = on
143
144# Use the highest optimization level unless weird stuff happens.
145ifeq ($(OPTIMIZATION), on)
146CPP_DEBUG_FLAGS = -O3
147else
148CPP_DEBUG_FLAGS = -g3
149endif
150
151
152#============================== ALL Compile and Link Flags =======================
153
154# Gather all C++ and C flags together.
155CPP_FLAGS = $(ARCH) $(CPP_DEBUG_FLAGS) $(CPP_INC) $(CPP_OPTIONS)
156C_FLAGS   = $(ARCH) $(C_DEBUG_FLAGS)   $(C_INC) $) $(C_OPTIONS)
157
158
159#============================== Root directories =============================
160
161# Source file root directories.
162CPP_SRC_DIR	= ../SourceCode
163
164# Object file root directories.
165CPP_OBJ_DIR 	= Bin
166
167# Executable file root directories.
168CPP_BIN_DIR		= Bin
169
170
171#============================== Include Files =======================
172
173# Include files.
174ifeq ($(PLATFORM), cygwin)
175CPP_INC = -I /usr/include -I "/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/include/c++"
176endif
177
178
179#============================== List of Files ================================
180
181# Object files.
182CPP_OBJ  		= $(CPP_OBJ_DIR)/FFT.o
183
184# Main program object files.
185CPP_OBJ_MAIN 	= $(CPP_OBJ_DIR)/testFFT.o
186
187# Main program executables.
188CPP_BIN_MAIN		= $(CPP_BIN_DIR)/testFFT.exe
189
190
191#============================== Implicit Rules ===============================
192
193# Link all object files to executables.
194$(CPP_BIN_MAIN): $(CPP_OBJ_MAIN) $(CPP_OBJ)
195	$(CPPLINK) $(LFLAGS) $(CPP_OBJ_MAIN) $(CPP_OBJ) -o $(CPP_BIN_MAIN) $(CPP_LIBS)
196
197# C++ and C source file compilation to object files.
198$(CPP_BIN_DIR)/%.o : $(CPP_SRC_DIR)/%.cpp
199	$(CPP) -c $(CPP_FLAGS) $< -o $@
200
201# List of all file.o : file.h dependencies.
202FFT.o: FFT.cpp fft.h
203testFFT.o: testFFT.cpp fft.h
204
205
206#============================== Targets ======================================
207
208# Make all the executables.
209makeAllExes: $(CPP_BIN_MAIN)
210
211# Run tests.
212test: $(CPP_BIN_MAIN)
213	echo "Testing FFT.  Return status = 1 because test throws an exception, but ignore it."
214	-$(CPP_BIN_MAIN) fftIn.txt fftOut.txt
215	@echo "Comparing output to MacBook results [you should see no differences]"
216	@diff fftOut.txt fftOut-macOS-ARM-M1max-clang.txt
217	@echo "Done"
218	@echo "Comparing output to Ubuntu results [you should see no differences]"
219	@diff fftOut.txt fftOut-UbuntuLinux-AMD-x86_64-gcc.txt
220	@echo "Done"
221
222# Remove all C and C++ object files and binaries and output files.
223#     - in front of the tells make to ignore a non-zero return code from a shell command.  So we don't stop if any files are missing.
224#     @ in front of the shell command line prevents it from being printed to the console as make runs.
225clean:
226	-@echo "Cleaning up object files and executables"
227	-rm fftOut.txt
228	-rm $(CPP_OBJ) $(CPP_OBJ_MAIN) $(CPP_BIN_MAIN)