# Makefile designed and tested for GNU C/C++ toolchain, under Gentoo OS.
# Written by Pawel Tatera
# Copyright (c) 2014, 2015 TinyIT
# All rights reserved

# Note that this file was prepared with speed and simplicity in mind.
# It does not support professional build tools like automake or autoconf (yet).

# This Makefile can handle 'cross-compiling'. When building on a 32 bit machine
# for the amd64 architecture - X64=1 should be defined.

# GNU toolchain
ifndef X64
# C compiler
CC=gcc
# C++ compiler
CXX=g++
# Linker
LD=ld
# Archiver (static modules linker)
AR=ar
else
CC=x86_64-pc-linux-gnu-gcc
CXX=x86_64-pc-linux-gnu-g++
LD=x86_64-pc-linux-gnu-ld
AR=x86_64-pc-linux-gnu-ar
endif
# Broomstick
RM=rm

# Build flags
# -g for debugging
# -c compile only
# -fpic
#    build position independent code; solves the DT_TEXTREL issue when linking
# -fno-stack-protector
#    fix for undefined ref. to '__stack_chk_fail_local', in latest gcc builds.
#    this is a walk around for libc releases where the stack protector has
#    been disabled more or less intentionally...
CFLAGS=-g -c -I./include
CXXFLAGS=$(CFLAGS)
LIB_CXXFLAGS=$(CXXFLAGS) -fpic -fno-stack-protector

# How to find GCC path (we all love tricks)
CXXLDIR=`$(CXX) -print-file-name=`

# Flags for the ld linker
# -E export all dynamic symbols
# -shared link as shared object
# -soname internal library name
# -lstdc++ link with the shared version of libstdc++ 
#
# If called by g++:
#LDFLAGS=-shared -Wl,-soname,libtconv.0.so
#
# If called directly:
LDFLAGS=-L./ -L$(CXXLDIR)

all: libtconv.a libtconv.so tctest

tconv.o: tconv.cpp include/tconv.h
	$(CXX) $(LIB_CXXFLAGS) tconv.cpp

tconv_c.o: tconv_c.cpp include/tconv.h
	$(CXX) $(LIB_CXXFLAGS) tconv_c.cpp

libtconv.a: tconv.o tconv_c.o
	$(AR) cr libtconv.a tconv.o tconv_c.o

libtconv.so: tconv.o tconv_c.o
	$(LD) $(LDFLAGS) -o libtconv.so -E -shared -soname=libtconv.so.0 tconv_c.o tconv.o -lstdc++ 

tctest: tctest.cpp libtconv.so
	$(CXX) $(CFLAGS) -o tctest.o tctest.cpp
	$(CXX) $(LDFLAGS) -o tctest tctest.o -ltconv

clean:
	$(RM) -f *\.o

distclean: clean
	$(RM) -f tc tcx libtconv.a libtconv.so*
	$(RM) -f tctest

# DEMO binaries

# C++ binary:
#tcx: tcx.cpp
#	$(CXX) $(CXXFLAGS) -o tcx.o tcx.cpp
#	$(CXX) $(LDFLAGS) -o tcx tcx.o -ltconv 

# Stand alone C-executable:
tc: tc.c libtconv.so
	$(CC) $(CFLAGS) -o tc.o tc.c
	$(CC) $(LDFLAGS) -ltconv -lstdc++ -o tc tc.o

# When using C compiler to invoke the linker, it might be necessary to tell it
# to link with stdc++ too (tconv is a C++ code):
#$(CC) $(LDFLAGS) -o tc tconv_c.o tconv.o tc.o -lstdc++
#
# C++ compiler just accepts both C/C++ objects when linking.
# All the rest comes out of the box:
#$(CXX) $(LDFLAGS) -o tc tconv_c.o tconv.o tc.o
#
# Calling the linker directly ends up with passing things directly
# from a command line: paths, libraries, etc.
#$(LD) $(LDFLAGS) -L/usr/lib/gcc/i686-pc-linux-gnu/4.8.3 -o tc \
#  tconv_c.o tconv.o tc.o -lc -lstdc++ -l?_WHAT_ELSE_?

# crt1.o	; 'new way' to put _start; __libc_start_main; ...
# crti.o	; _init; ...
# crtbegin.o	; used by GCC to find constructors
# crtbeginS.o	; used by GCC to find constructors when building PIEs
# crtend.o	; used by GCC to find destructors
# crtendS.o	; used by GCC to find destructors when building PIEs
# crtn.o	;

# $(LD) /usr/lib/crt1.o /usr/lib/crti.o $(GCCLDIR)/crtbegin.o $(LDFLAGS) -o sb.bin sb.o $(GCCLDIR)/crtend.o /usr/lib/crtn.o -lc -ltconv

sb.bin: sandbox.c libtconv.so
	$(CC) $(CFLAGS) -o sb.o sandbox.c
	$(CC) $(LDFLAGS) -o sb.bin sb.o -ltconv

sbx.bin: sandbox.cpp libtconv.so
	$(CXX) $(CFLAGS) -o sbx.o sandbox.cpp
	$(CXX) $(LDFLAGS) -o sbx.bin sbx.o -ltconv
