help-make
[Top][All Lists]
Advanced

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

Header file dependency, rpath, soname and more with Makefile


From: ljh
Subject: Header file dependency, rpath, soname and more with Makefile
Date: Wed, 15 Mar 2023 15:03:36 +0800

Hi community,

Currently, I can handle these tasks in C and C++ programming with Makefile:

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!

---


$ 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    = -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>

reply via email to

[Prev in Thread] Current Thread [Next in Thread]