Skip to content
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

makefile improvements, enable dynamic library #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 62 additions & 27 deletions makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
SHELL = /bin/sh
OS := $(shell uname -s)
ARCH := $(shell uname -m)
MACHINE_ARCH := $(shell uname -p)

CC = clang++
AR = ar
RANLIB = ranlib
ifeq ($(OS),Darwin)
LIBEXT = dylib
else
LIBEXT = so
endif

CFLAGS = -g -Wall
CC ?= clang
CXX ?= clang++
AR ?= ar
RANLIB ?= ranlib

CFLAGS ?= -g -Wall

# Comment out CFLAGS line below for compatability mode for 32bit file sizes
# (less than 2GB) and systems that have compilers that treat int as 64bit
Expand All @@ -15,13 +25,21 @@ CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
CFLAGS += -O3 -fomit-frame-pointer -fstrict-aliasing -ffast-math

# Comment out CFLAGS line below to disable AVX2 instruction set (performance will suffer)
CFLAGS += -mavx2
ifneq (,$(filter x86_64 i686 i386,$(ARCH)))
CFLAGS += -mavx2
endif

# Comment out CFLAGS line below to disable OpenMP optimizations
CFLAGS += -fopenmp -DLIBBSC_OPENMP_SUPPORT
OPENMP ?= 0
ifneq (,$(filter 1 true yes,$(OPENMP)))
CFLAGS += -fopenmp -DLIBBSC_OPENMP_SUPPORT
endif

# Comment out CFLAGS line below to enable debug output
CFLAGS += -DNDEBUG
DEBUG ?= 0
ifneq (,$(filter 0 false no,$(DEBUG)))
CFLAGS += -DNDEBUG
endif

# Comment out CFLAGS line below to disable Sort Transform
CFLAGS += -DLIBBSC_SORT_TRANSFORM_SUPPORT
Expand All @@ -30,7 +48,18 @@ CFLAGS += -DLIBBSC_SORT_TRANSFORM_SUPPORT
CFLAGS += -DLIBBSC_ALLOW_UNALIGNED_ACCESS

# Where you want bsc installed when you do 'make install'
PREFIX = /usr
PREFIX ?= /usr

NATIVE ?= 0
ifneq (,$(filter 1 true yes,$(NATIVE)))
ifneq (,$(filter arm% aarch64,$(ARCH)))
CFLAGS += -mcpu=native
else ifneq (,$(filter powerpc,$(MACHINE_ARCH)))
CFLAGS += -mtune=native
else
CFLAGS += -march=native
endif
endif

OBJS = \
adler32.o \
Expand All @@ -46,21 +75,25 @@ OBJS = \
st.o \
bwt.o \

all: libbsc.a bsc
all: libbsc.a bsc libbsc.$(LIBEXT)

bsc: libbsc.a bsc.cpp
$(CC) $(CFLAGS) bsc.cpp -o bsc -L. -lbsc
$(CXX) $(CFLAGS) $(LDFLAGS) bsc.cpp -o $@ $<

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In all places where CXX is used to compile C++ code, CXXFLAGS should be used, not CFLAGS.


libbsc.a: $(OBJS)
rm -f libbsc.a
$(AR) cq libbsc.a $(OBJS)
rm -f $@
$(AR) cq $@ $(OBJS)
@if ( test -f $(RANLIB) -o -f /usr/bin/ranlib -o \
-f /bin/ranlib -o -f /usr/ccs/bin/ranlib ) ; then \
echo $(RANLIB) libbsc.a ; \
$(RANLIB) libbsc.a ; \
echo $(RANLIB) $@ ; \
$(RANLIB) $@ ; \
fi

install: libbsc.a bsc
libbsc.$(LIBEXT): $(OBJS)
rm -f $@
$(CC) $(CFLAGS) -fPIC -shared $(LDFLAGS) -o $@ $(OBJS)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Darwin you should use -dynamiclib instead of -shared, and you must use -install_name to set the absolute path where the library will be installed, and you should set -current_version and -compatibility_version to appropriate values.

If these objects are compiled from C++ code, you must use CXX to link, not CC, otherwise the C++ standard library will not be linked in.

Use CXXFLAGS when linking C++ code since that's where a user (or MacPorts, in our case) will put important flags like -stdlib=libc++ that are also needed at link time. (MacPorts can't know whether a port is linking objects built from C or C++ code so it does not put that flag in LDFLAGS).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's one object that is compiled from C in this lib tho (see line 115), will switching to CXX and CXXFLAGS break anything?
Also do I just set those versions to the current project version?

Copy link

@ryandesign ryandesign Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using CXX to link C code works fine.

The only part of CXXFLAGS of relevance when linking, as far as I know, is the -stdlib flag. Since CXX accepts that flag it's fine. As far as I know, there's nothing in CFLAGS of interest at link time so there wouldn't be a need to use that.

Library versioning is a complicated topic about which you can find much written on the Internet, and specifically with regard to how macOS handles it.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since CXX accepts that flag it's fine.

@ryandesign Not necessarily so, AFAIK. With gcc it is a non-default config option, which is not supported by default. (Yes, I know that MacPorts enables it on x86 and arm.)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not relevant. If a user is using a C++ compiler that doesn't support a flag they obviously wouldn't add that flag to CXXFLAGS.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sure.


install: libbsc.a bsc libbsc.$(LIBEXT)
if ( test ! -d $(DESTDIR)$(PREFIX)/bin ) ; then mkdir -p $(DESTDIR)$(PREFIX)/bin ; fi
if ( test ! -d $(DESTDIR)$(PREFIX)/lib ) ; then mkdir -p $(DESTDIR)$(PREFIX)/lib ; fi
if ( test ! -d $(DESTDIR)$(PREFIX)/include ) ; then mkdir -p $(DESTDIR)$(PREFIX)/include ; fi
Expand All @@ -70,42 +103,44 @@ install: libbsc.a bsc
chmod a+r $(DESTDIR)$(PREFIX)/include/libbsc.h
cp -f libbsc.a $(DESTDIR)$(PREFIX)/lib
chmod a+r $(DESTDIR)$(PREFIX)/lib/libbsc.a
cp -f libbsc.$(LIBEXT) $(DESTDIR)$(PREFIX)/lib
chmod a+r $(DESTDIR)$(PREFIX)/lib/libbsc.$(LIBEXT)
Comment on lines +106 to +107

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typically one installs files using install instead of cp and chmod.


clean:
rm -f *.o libbsc.a bsc
rm -rf *.o libbsc.a libbsc.$(LIBEXT) bsc bsc.dSYM

adler32.o: libbsc/adler32/adler32.cpp
$(CC) $(CFLAGS) -c libbsc/adler32/adler32.cpp
$(CXX) $(CFLAGS) -c libbsc/adler32/adler32.cpp

libsais.o: libbsc/bwt/libsais/libsais.c
$(CC) $(CFLAGS) -c libbsc/bwt/libsais/libsais.c

coder.o: libbsc/coder/coder.cpp
$(CC) $(CFLAGS) -c libbsc/coder/coder.cpp
$(CXX) $(CFLAGS) -c libbsc/coder/coder.cpp

qlfc.o: libbsc/coder/qlfc/qlfc.cpp
$(CC) $(CFLAGS) -c libbsc/coder/qlfc/qlfc.cpp
$(CXX) $(CFLAGS) -c libbsc/coder/qlfc/qlfc.cpp

qlfc_model.o: libbsc/coder/qlfc/qlfc_model.cpp
$(CC) $(CFLAGS) -c libbsc/coder/qlfc/qlfc_model.cpp
$(CXX) $(CFLAGS) -c libbsc/coder/qlfc/qlfc_model.cpp

detectors.o: libbsc/filters/detectors.cpp
$(CC) $(CFLAGS) -c libbsc/filters/detectors.cpp
$(CXX) $(CFLAGS) -c libbsc/filters/detectors.cpp

preprocessing.o: libbsc/filters/preprocessing.cpp
$(CC) $(CFLAGS) -c libbsc/filters/preprocessing.cpp
$(CXX) $(CFLAGS) -c libbsc/filters/preprocessing.cpp

libbsc.o: libbsc/libbsc/libbsc.cpp
$(CC) $(CFLAGS) -c libbsc/libbsc/libbsc.cpp
$(CXX) $(CFLAGS) -c libbsc/libbsc/libbsc.cpp

lzp.o: libbsc/lzp/lzp.cpp
$(CC) $(CFLAGS) -c libbsc/lzp/lzp.cpp
$(CXX) $(CFLAGS) -c libbsc/lzp/lzp.cpp

platform.o: libbsc/platform/platform.cpp
$(CC) $(CFLAGS) -c libbsc/platform/platform.cpp
$(CXX) $(CFLAGS) -c libbsc/platform/platform.cpp

st.o: libbsc/st/st.cpp
$(CC) $(CFLAGS) -c libbsc/st/st.cpp
$(CXX) $(CFLAGS) -c libbsc/st/st.cpp

bwt.o: libbsc/bwt/bwt.cpp
$(CC) $(CFLAGS) -c libbsc/bwt/bwt.cpp
$(CXX) $(CFLAGS) -c libbsc/bwt/bwt.cpp

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There seems to be an awful lot of code duplication here. Typically there is a single rule that arranges for all source code files (of one language) to be compiled into objects.