Header file dependency, rpath, soname and more with GCC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi community,


Currently, I can handle these tasks in C and C++ programming with GCC 
on Linux:


1. Header file dependency;
2. rpath (for build and install);
3. soname for so versioning;
4. Debug or Release mode;
5. out-of-source build;


I want to know if there are some other tasks which are missing from the 
above list and I need to handle them too. Many thanks!


The above tasks can be handled in my CMake, Autotools, or manual Makefile.
Below is my Makefile.




---




$ tree --charset C
.
|-- build
|   |-- foo
|   |   |-- foo
|   |   |-- foo.d
|   |   |-- foo.o
|   |   |-- libfoo.so -> libfoo.so.1.2.3
|   |   |-- libfoo.so.1 -> libfoo.so.1.2.3
|   |   `-- libfoo.so.1.2.3
|   `-- main
|       |-- main
|       |-- main.d
|       `-- main.o
|-- foo
|   |-- foo.c
|   |-- foo.h
|   `-- Makefile
|-- main
|   |-- main.c
|   `-- Makefile
`-- Makefile


$ 




---




# Makefile for top dir


# $(call makever,1.2.3)
# major.minor.patch
# libtool manual: -version-number
define makever
	@ $(MAKE) -C $@ soname=lib$@.so.$(word 1,$(subst ., ,$(1)))


	@ cp $(OBJDIR)/$@/$@ $(OBJDIR)/$@/lib$@.so.$(1)


	@ cd $(OBJDIR)/$@ ; \
		ln -f -s lib$@.so.$(1) lib$@.so.$(word 1,$(subst ., ,$(1))) ; \
		cd - >/dev/null 2>&1 ;


	@ cd $(OBJDIR)/$@ ; \
		ln -f -s lib$@.so.$(1) lib$@.so ; \
		cd - >/dev/null 2>&1 ;
endef


# make # BUILD_DIR=build
ifdef BUILD_DIR
export OBJDIR = $(abspath $(BUILD_DIR))
else
export OBJDIR = $(abspath build)
endif


SUBDIRS = main foo


all : $(SUBDIRS)
install : $(SUBDIRS)
$(SUBDIRS) : | $(OBJDIR)
$(OBJDIR) : ; @ mkdir $@


main : foo
main : ; @ $(MAKE) -C $@
foo : ; $(call makever,1.2.3)


# make DESTDIR=~/foo install
# Alexandre Duret-Lutz's Autotools Tutorial (without animations):
# "is ready to be uncompressed in / on many hosts"
install :
	install -d $(DESTDIR)/usr/local/bin
	install -d $(DESTDIR)/usr/local/lib
	install -m 0755 $(OBJDIR)/main/main $(DESTDIR)/usr/local/bin
	cp -P $(OBJDIR)/foo/*.so* $(DESTDIR)/usr/local/lib


clean :
	@ for dir in $(SUBDIRS); do \
		$(MAKE) -C $$dir $@; \
	done
	-rm -fr $(OBJDIR)


.PHONY : $(SUBDIRS) all install clean




---




# Makefile for subdir


# build shared library with -fPIC, -shared
CFLAGS    = # -g -O3 -fPIC # CXXFLAGS for .cpp
CPPFLAGS  = -MMD -MP -I../foo
LDFLAGS   = -L$(OBJDIR)/foo # -shared
LDLIBS    = -lfoo
#CC       = $(CXX) # link with CXX for .cpp


LDFLAGS  += -Wl,-rpath,'$$ORIGIN/../foo'
LDFLAGS  += -Wl,-rpath,'$$ORIGIN/../lib'
#LDFLAGS += -Wl,-soname,$(soname)


# make # NDEBUG=1
ifdef NDEBUG
CFLAGS   += -O3 # .cpp
CPPFLAGS += -DNDEBUG
else
CFLAGS   += -g # .cpp
LDFLAGS  += -fsanitize=address
endif


SUBDIR    = $(OBJDIR)/$(lastword $(subst /, ,$(CURDIR)))


all : $(SUBDIR)/main # $(SUBDIR)/foo


# https://make.mad-scientist.net/papers/how-not-to-use-vpath/
$(SUBDIR)/main : $(addprefix $(SUBDIR)/,$(patsubst %.c,%.o,$(wildcard *.c))) # .cpp
	$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@


$(SUBDIR)/%.o : %.c | $(SUBDIR) # .cpp
	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<


$(SUBDIR) : ; @ mkdir $@


-include $(SUBDIR)/*.d
clean : ; -rm -fr $(SUBDIR)
.PHONY : all clean




---




# Makefile for subdir


# build shared library with -fPIC, -shared
CFLAGS &nbsp; &nbsp;= -fPIC # -g -O3 # CXXFLAGS for .cpp
CPPFLAGS &nbsp;= -MMD -MP # -I../bar
LDFLAGS &nbsp; = -shared # -L$(OBJDIR)/bar
LDLIBS &nbsp; &nbsp;= # -lbar
#CC &nbsp; &nbsp; &nbsp; = $(CXX) # link with CXX for .cpp


LDFLAGS &nbsp;+= -Wl,-rpath,'$$ORIGIN/../bar'
LDFLAGS &nbsp;+= -Wl,-rpath,'$$ORIGIN/../lib'
LDFLAGS &nbsp;+= -Wl,-soname,$(soname)


# make # NDEBUG=1
ifdef NDEBUG
CFLAGS &nbsp; += -O3 # .cpp
CPPFLAGS += -DNDEBUG
else
CFLAGS &nbsp; += -g # .cpp
LDFLAGS &nbsp;+= -fsanitize=address
endif


SUBDIR &nbsp; &nbsp;= $(OBJDIR)/$(lastword $(subst /, ,$(CURDIR)))


all : $(SUBDIR)/foo # $(SUBDIR)/bar


# https://make.mad-scientist.net/papers/how-not-to-use-vpath/
$(SUBDIR)/foo : $(addprefix $(SUBDIR)/,$(patsubst %.c,%.o,$(wildcard *.c))) # .cpp
	$(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@


$(SUBDIR)/%.o : %.c | $(SUBDIR) # .cpp
	$(CC) $(CFLAGS) $(CPPFLAGS) -c -o $@ $<


$(SUBDIR) : ; @ mkdir $@


-include $(SUBDIR)/*.d
clean : ; -rm -fr $(SUBDIR)
.PHONY : all clean




---




#include <stdio.h&gt;
#include <signal.h&gt;
#include <assert.h&gt;


#ifndef NDEBUG
#include <sanitizer/lsan_interface.h&gt;
#endif


#include "foo.h"


void handlerCont(int signum) {
&nbsp; printf("SIGCONT %d\n", signum);
#ifndef NDEBUG
&nbsp; __lsan_do_recoverable_leak_check();
#endif
}


int main() {
&nbsp; signal(SIGCONT, handlerCont); // kill -CONT 123 # pid
&nbsp; printf("main\n");
&nbsp; foo();


&nbsp; int a[1024];
&nbsp; int n = 10240;
&nbsp; a[n] = 1; // asan
&nbsp; assert(0); // -DNDEBUG
}




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux