Re:Header file dependency, rpath, soname and more with GCC

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

 



(Fixed the web mail format. Sorry!)

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.

---


# 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    = -fPIC # -g -O3 # CXXFLAGS for .cpp
CPPFLAGS  = -MMD -MP # -I../bar
LDFLAGS   = -shared # -L$(OBJDIR)/bar
LDLIBS    = # -lbar
#CC       = $(CXX) # link with CXX for .cpp

LDFLAGS  += -Wl,-rpath,'$$ORIGIN/../bar'
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)/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>
#include 
#include <assert.h>

#ifndef NDEBUG
#include <sanitizer lsan_interface.h="">
#endif

#include "foo.h"

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

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

  int a[1024];
  int n = 10240;
  a[n] = 1; // asan
  assert(0); // -DNDEBUG
}</sanitizer></assert.h></stdio.h>




[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