Cross compiling c application library referring other libraries symbolically linked - linux

I am trying to build an application(libnodeapplication) which is dependent on a shared library(libnode.so) which in turn depends on another shared library(libgentoo-5.so.100) which I have pasted at the same location as the libnode(inside /usr/lib/)
Problem is second dependent library is symbolically linked to another file
what changes are needed in the compile command to build it successfully(for symbolically linkd files refrened in the shared library)
I tried with -Wl,-rpath=<path to usr/lib/path_to_libgentoo-5.so.100 (also without file name) as well :
command2 :
gcc main.o -o libnodeapplication -L/usr/lib/-lnode -Wl,-rpath=/usr/lib/
error
below is the error
ld: warning: libgentoo-5.so.100, needed by /usr/lib/libnode.so, not found (try using -rpath or -rpath-link)
usr/lib/libnode.so: undefined reference to `symbol1 in libgentoo-5.so.100'
usr/lib/libnode.so: undefined reference to `symbol2 in libgentoo-5.so.100'
usr/lib/libnode.so: undefined reference to `symbol3 in libgentoo-5.so.100'
.
.
.
and so on
(for simplicity i have used gcc instead of arm linux cross compiler)
so my end application is libnodeapplication which depends on shared lib => libnode.so
libnode.so is being built using the libgentoo-5.so.100 (which is present in the /usr/lib and symbolically linked to libgentoo-5.so.100.20.0 : libgentoo-5.so.100 -> libgentoo-5.so.100.20.0)
I use this command1 :
gcc obj1.o obj2.o obj3.o -shared -o libnode.so /usr/lib/libgentoo-5.so.100
When i try to use the objdum -t libnode.so , I can find all those symbols which are reported as undefined symbols when I try to build the libnodeapplication by above command2
My Makefile(for libnodeapplication)
CC=<path to tool chain>arm-linux-gnueabihf-gcc
CFLAGS=-Wall
LIB_NAME=-lnode
LIBS=-L$(TARGET_DIR)/usr/lib
INCS=-I./include/
OBJS=libnodeapplication.o
libnodeapplication: $(OBJS)
$(CC) $(OBJS) -o libnodeapplication $(LIBS) $(LIB_NAME)
main.o: main.c
$(CC) $(INCS) $(CFLAGS) -c $< -o $#
clean:
-rm -rf *.o libnodeapplication
-rm -rf $(TARGET_DIR)/root/libnodeapplication
install:
cp libnodeapplication $(TARGET_DIR)/root
chmod +x $(TARGET_DIR)/root/libnodeapplication
Make file for libnode.so
CC=<path to tool chain>arm-linux-gnueabihf-gcc
CFLAGS=-Wall -fPIC
INCS=-I./include/
LIBS=$(TARGET_DIR)/usr/lib/libgentoo-5.so.100
OBJS=libnode.o helper.o
libnode: $(OBJS)
$(CC) $(OBJS) -shared -o a.so $(LIBS)
libnode.o: libnode.c
$(CC) $(INCS) $(CFLAGS) -c $< -o $#
helper.o: helper.c
$(CC) $(INCS) $(CFLAGS) -c $< -o $#
clean:
-rm -rf *.o
-rm -rf libnode.so
-rm -rf $(TARGET_DIR)/usr/lib/libnode.so
-rm -rf $(TARGET_DIR)/usr/include/libnode.h
install:
-cp libnode.so $(TARGET_DIR)/usr/lib
-cp libnode.h $(TARGET_DIR)/usr/include

There is no problem to link against symbolic links.
The problem here is that the linker is trying to resolve all the references, so it needs libgentoo-5.so.100. If you have already used libgentoo-5.so.100 when generating libnode.so, you can add -Wl,-rpath-link=path_to_libgentoo (which is the same as the path for libnode) and it will work.
An other solution could be to also use libgentoo-5.so.100 when linking the executable. with -l and -L options.
there is a minimaliste exemple:
all:exec
libx:
cd xf; \
arm-linux-gnueabihf-gcc -c $(CFLAGS) -fpic x.c -I.;\
arm-linux-gnueabihf-gcc -shared -o libx.so x.o;\
ln -s libx.so libx.so.10;\
liby:libx
arm-linux-gnueabihf-gcc -c $(CFLAGS) -fpic y.c -I. -I./xf
arm-linux-gnueabihf-gcc -shared -o liby.so y.o /home/youssef/test/arm2/xf/libx.so.10
exec:liby
arm-linux-gnueabihf-gcc $(CFLAGS) -o exec z.c -I. -I./xf -L. -ly -Wl,-rpath=./xf
the folder xf contain x.c ( which contain one function ) and x.h.
y.c contain one function which call the function in x.c.
z.c contain one function which call the function in y.c.
This example compile well with arm-linux-gnueabihf-gcc (Ubuntu/Linaro 7.5.0-3ubuntu1~18.04) 7.5.0

Everything looks fine, but I noticed you forgot the -L flag in the Makefile for libnode
LIBS=$(TARGET_DIR)/usr/lib/libgentoo-5.so.100
=>
LIBS=-L$(TARGET_DIR)/usr/lib/libgentoo-5.so.100
Also when linking you usually don't have to specify the full path/name of your library, Usually you would go only with the flag
-lgentoo The reason is the compiler will look in $PATH for a suitable library that will be named 'libgentoo.so' wich will be a sym link to whatever version is currently used on your system, for example
$ls /usr/lib/libgentoo*
/usr/lib/libgentoo.so -> /usr/lib/libgentoo-5.so
/usr/lib/libgentoo-5.so -> /usr/lib/libgentoo-5.so.100
/usr/lib/libgentoo-5.so.100

Your command1 was right - you just have to use the same way in command2: name the library directly.
command2: gcc main.o -o libnodeapplication /usr/lib/node.so
Full working example:
$ cat b.c # (= libgentoo)
int b(int x) {
return x%4;
}
$ cat a.c # (= libnode)
int b(int);
int a(int x) {
return b(x+3);
}
$ cat main.c # (= nodeapplication)
int a(int);
int main() {
return a(2);
}
$ pwd
/mounts/compilepartition/a-b-main/
$ mkdir -p ../toomuch # (Just for fun)
$ gcc -shared -o b.so b.c
$ gcc a.c -shared -o a.so $PWD/b.so
$ gcc main.c -o app /mounts/compilepartition/toomuch/../a-b-main/a.so
$ ldd app
linux-gate.so.1 (0xf7...)
/mounts/compilepartition/toomuch/../a-b-main/a.so (0xf7...)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7...)
/mounts/compilepartition/a-b-main/b.so (0xf7...)
/lib/ld-linux.so.2 (0x56...)
$ ./app; echo $?
1
$
Tip: For cross compiling, you can hide your build path, e.g. with
gcc a.c -shared -o a.so -L /my/complex/build/path -l:b.so
Link-time path /my/complex/build/path/b.so
Run-time path ??? -> must be found at runtime
Tip: For cross compiling, you can replace your build path, e.g. with
gcc a.c -shared -o a.so -L /my/complex/build/path -l:b.so -W,-rpath=/usr/lib
Link-time path /my/complex/build/path/b.so
Run-time path /usr/lib/b.so
(OK, it's no replacement, you're just adding a hint. Maybe you will actually get a different b.so)
Tip: For runtime searching relative to the object/executable, use '$ORIGIN' (quoted in single quotes! (in GNU/Linux or GNU/*, probably even in Windows))
gcc a.c -shared -o a.so -L /my/complex/build/path -l:b.so -W,-rpath='$ORIGIN'/sub
Link-time path /my/complex/build/path/a.so
Link-time path /my/complex/build/path/b.so
Run-time path /usr/lib/a.so (for instance)
Run-time path /usr/lib/sub/b.so
(Warning: this gets complicated because you may need to store the sub-sub-libraries in the required relative path at link-time for linking e.g. a final executable.)
Tip: You can look on shared objects' and final executables' load dependencies with ldd ./a.so or ldd ./app (host=target). If host!=target use strings ./a.so or strings ./app -> here you see "b.so"/"a.so" and "/usr/lib", amongst lots of cryptic stuff.

Related

Compiling with SDCC fails with -Wall option

I'm compiling a 8051 project with SDCC but has a problem with Makefile, the following sources:
TARGET = test
CC = sdcc
CFLAGS = -Wall -I.
RM = rm -rf
SRCS = $(wildcard *.c)
RELS = $(patsubst %.c,%.rel,$(SRCS))
$(TARGET).bin: $(TARGET).hex
objcopy -I ihex -O binary $< $#
$(TARGET).hex: $(TARGET).ihx
packihx $< > $#
$(TARGET).ihx: $(RELS)
#echo Linking ...
$(CC) $(CFLAGS) $< -o $#
#echo Build finish!
%.rel: %.c
#echo Compiling ...
$(CC) $(CFLAGS) -c $< -o $#
.PHONY: clean
clean:
#echo Removing ...
$(RM) *.rel *.ihx *.lk *.lst *.map *.mem *.rst *.sym *.asm $(TARGET)
#echo Removed!
When I run make it has errors:
minh#PCDESIGN:~/workspaces/programMSC51/test$ make
Compiling ...
sdcc -Wall -I. -c main.c -o main.rel
sdas Assembler V02.00 + NoICE + SDCC mods (Intel 8051)
Copyright (C) 2012 Alan R. Baldwin
This program comes with ABSOLUTELY NO WARRANTY.
Usage: [-Options] file
Usage: [-Options] outfile file1 [file2 file3 ...]
-d Decimal listing
-q Octal listing
-x Hex listing (default)
-g Undefined symbols made global
-a All user symbols made global
-b Display .define substitutions in listing
-bb and display without .define substitutions
-c Disable instruction cycle count in listing
-j Enable NoICE Debug Symbols
-y Enable SDCC Debug Symbols
-l Create list file/outfile[.lst]
-o Create object file/outfile[.rel]
-s Create symbol file/outfile[.sym]
-p Disable automatic listing pagination
-u Disable .list/.nlist processing
-w Wide listing format for symbol table
-z Disable case sensitivity for symbols
-f Flag relocatable references by ` in listing file
-ff Flag relocatable references by mode in listing file
-I Add the named directory to the include file
search path. This option may be used more than once.
Directories are searched in the order given.
removing
make: *** [Makefile:22: main.rel] Error 1
How can I fix this?
Unlike other compilers, SDCC does not have a -Wall option. You should remove it from CFLAGS = -Wall -I. in the Makefile.
It also does not have a replacement. There are options --less-pedantic and -Werror, which gives you fewer warnings, or treats warnings as errors, respectively, but there is no option for creating more warnings.
The manual mentions --more-pedantic, but
Actually this is not a SDCC compiler option but if you want more warnings you can use a separate tool dedicated to syntax checking [...]
See SDCC Compiler User Guide (version 4.1.12), section 3.3.4.

How to fix ld: cannot find kernel.bin: No such file or directory

I'm trying to run an implementation of an operating system and I get this error when I run make on the terminal, I use ubuntu 20.04.
This is the makefile:
C_SOURCES = $(wildcard kernel/*.c drivers/*.c cpu/*.c libc/*.c)
HEADERS = $(wildcard kernel/*.h drivers/*.h cpu/*.h libc/*.h)
# Nice syntax for file extension replacement
OBJ = ${C_SOURCES:.c=.o cpu/interrupt.o}
# Change this if your cross-compiler is somewhere else
CC = /usr/local/i386elfgcc/bin/i386-elf-gcc
GDB = /usr/local/i386elfgcc/bin/i386-elf-gdb
# -g: Use debugging symbols in gcc
CFLAGS = -g -ffreestanding -Wall -Wextra -fno-exceptions -m32
# First rule is run by default
os-image.bin: boot/bootsect.bin kernel.bin
cat $^ > os-image.bin
# '--oformat binary' deletes all symbols as a collateral, so we don't need
# to 'strip' them manually on this case
kernel.bin: boot/kernel_entry.o ${OBJ}
ld -melf_i386 -o -no-PIE $# -Ttext 0x1000 $^ --oformat binary
# Used for debugging purposes
kernel.elf: boot/kernel_entry.o ${OBJ}
ld -melf_i386 -o -no-PIE $# -Ttext 0x1000 $^
run: os-image.bin
qemu-system-i386 -fda os-image.bin
# Open the connection to qemu and load our kernel-object file with symbols
debug: os-image.bin kernel.elf
qemu-system-i386 -s -fda os-image.bin -d guest_errors,int &
${GDB} -ex "target remote localhost:1234" -ex "symbol-file kernel.elf"
# Generic rules for wildcards
# To make an object, always compile from its .c
%.o: %.c ${HEADERS}
${CC} ${CFLAGS} -c $< -o $#
%.o: %.asm
nasm $< -f elf -o $#
%.bin: %.asm
nasm $< -f bin -o $#
clean:
rm -rf *.bin *.dis *.o os-image.bin *.elf
rm -rf kernel/*.o boot/*.bin drivers/*.o boot/*.o cpu/*.o libc/*.o
And this is the source for the code, I wasn't able to install the cross compiler that is in the tutorial. So I tried to change the makefile to work with the default gcc:
source
You linker commands are buggy because you misplaced the -no-PIE option.
Instead of ld -o -no-PIE $#, write ld -o $# -no-PIE:
kernel.bin: boot/kernel_entry.o ${OBJ}
ld -melf_i386 -o $# -no-PIE -Ttext 0x1000 $^ --oformat binary
kernel.elf: boot/kernel_entry.o ${OBJ}
ld -melf_i386 -o $# -no-PIE -Ttext 0x1000 $^
$# is the target of your make command (here kernel.bin and kernel.elf). Misplacing it like you did, you are instructing ld to output the result as a file named -no-PIE and to use kernel.bin (resp. kernel.elf) as an input. Hence the error message since the input does not exist yet.

Makefile error in C linux

I have an error while making my makefile in linux. Here's my code:
CC = gcc
CFLAGS = -Wall -m32 -g -fno-stack-protector -z execstack -O0
SHELL_SOURCES = Shell.c
SHELL = Shell
.PHONY: all target1 clean
all: target1
target1: $(SHELL)
$(SHELL): $(SHELL_SOURCES)
$(CC) $(CFLAGS) $^ -o $#
clean:
rm -rf $(SHELL)
The error I get is:
gcc -Wall -m32 -g -fno-stack-protector -z execstack -O0 Shell.c -o Shell
make: Shell: Command not found
Makefile:16: recipe for target 'Shell' failed
make: *** [Shell] Error 127
You can't use SHELL as a variable in a Makefile, it is used to know what shell (/bin/sh, /bin/bash, etc) will be used in your Makefile.
CC = gcc
CFLAGS = -Wall -m32 -g -fno-stack-protector -z execstack -O0
EXE_SOURCES = Shell.c
EXE = Shell
.PHONY: all target1 clean
all: target1
target1: $(EXE)
$(EXE): $(EXE_SOURCES)
$(CC) $(CFLAGS) $^ -o $#
clean:
rm -rf $(EXE)
Take more time to read documentation of GNU make
You should remove spaces around variable assignments, e.g. code
CC= gcc
Beware that tab characters are significant in Makefile-s (in rules, for their action lines). Use some editor aware of that (e.g. emacs has a mode for Makefile). See also this example (but the rule action should really start with a tab character). Notably, you need a tab just before the $(CC) $(CFLAGS) $^ -o $# and another one before rm.
Consider also using remake -x to debug your Makefile, or at least make --trace
But the main bug was indeed, as answered by Cpatricio, to use the SHELL variable. Be careful when using variables or names already known to make. Actually, I have the habit of prefixing my make variable names with a common prefix, so you could have defined your variables like JOJOIGA_SOURCES=$(wildcard *.c), JOJOIGA_SHELL=Shell etc....

Compiling C++ and C files in one makefile

I have a makefile that looks like this:
CS := a.c b.c
CPPS := foo.cpp bar.cpp
SOURCES := $(CS) $(CPPS)
OBJS := $(CS:%.c=$(OBJSDIR)/%.o) $(CPPS:%.cpp=$(OBJSDIR)/%.o)
I want to create a single rule to compile them all. But the only option I can think of is this:
$(OBJSDIR)/%.o: %.cpp
$(GXX) $(GXXFLAGS) -c $< -o $#
But of course it doesn't work because some of the object files don't have a matching C++ source file.
Any idea?
suppose you have a.cc, b.cc and c.cc, and on the other side, d.c, e.c and f.c
program_objs = a.o b.o c.o d.o e.o f.o
program: $(program_objs)
$(CC) $(LDFLAGS) -o $# $(program_objs)
You don't need anything more, as make will automatically detect which files are c++ and which ones are plain c and will select the proper compiler.
in case you want something special, not included in makefile, you can add some suffixes (file types) with the rule:
.SUFFIXES: .a .b .o
and then use the following rules to compile them to .o
.a.o:
$(COMPILER_A) $(COMPILER_A_FLAGS) -c $# -o $<
.b.o:
$(COMPILER_B) $(COMPILER_B_FLAGS) -c $# -o $<
and let makefile select the proper compiler (the one stored in variables COMPILER_A or COMPILER_B) to do the work.
Of course, you can compile something to a .o file with an explicit rule, as in:
a.o: a.cc
g++ -o a.o -c a.cc
b.o: b.cc
g++ -o b.o -c b.cc
c.o: c.cc
g++ -o c.o -c c.cc
d.o: d.c
gcc -o d.o -c d.c
e.o: e.c
gcc -o e.o -c e.c
f.o: f.c
gcc -o f.o -c f.c
Note #1:
Some sugestions have been made on GNU make % pattern to construct implicit rules for targets. Below is a rewritting of the implicit rules above to do the same thing:
%.o: %.a
$(COMPILER_A) $(COMPILER_A_FLAGS) -c $# -o $<
%.o: %.b
$(COMPILER_B) $(COMPILER_B_FLAGS) -c $# -o $<
As always, $# means the target of the rule and $< (you can use also $* for the file name without any matching suffixes) the left needed file. For a complete list of automatic variables that can be used, I suggest you to read your make manual. Take into account that the old suffix syntax is reversed from the new one (the target suffix appears last in the old syntax, the new syntax being more similar to a normal makefile rule with the target on the left side of the colon)
I want to create a single rule to compile them all.
As Etan Reisner said in the comment section, make already has implicit rules to compile .c and .cpp file, so the real answer to your question is:
Do not write anything to compile your object files.
That said, you should now remove those two variables: $(GXX) and $(GXXFLAGS).
To provide flags to cc or gcc one should use the CFLAGS built-in variable.
To provide flags to g++ one should use the CXXFLAGS built-in variable.
To provide flags to the preprocessor (cpp) one should use the CPPFLAGS variable.
Since you're mixing C and C++ source files, you should use the CXX variable as the linker command.

make for compiling — all *.c files in folders & subfolders in project

To compile two files i have created a makefile where i use to mention the object name or i can use the pattern rule using patsubst.
# ----------------------------------------------------------------------------
# Makefile for building tapp
#
# Copyright 2010 FriendlyARM (http://www.arm9.net/)
#
ifndef DESTDIR
DESTDIR ?= /opt/FriendlyARM/tiny6410/linux/rootfs_qtopia_qt4
endif
#CFLAGS = -c -Wall -O2 # wall is for warning show and 02 is optiminisation level 2
CFLAGS = -c -O2 # wall is for warning show and 02 is optiminisation level 2
#CC = arm-linux-gcc # compiler name
CC = gcc # compiler name
LD = ld
INSTALL = install #
TARGET = led_player_project
#OBJ = led-player_backup.o led-player.o
OBJ := $(patsubst %.c,%.o,$(wildcard *.c */*.c))
#OBJ = $(shell find . -name '*.c')
all: $(TARGET)
#all: $(OBJ)
led_player_project : $(OBJ)
$(LD) $(LDFLAGS) -o $# $(OBJ) $(LIBS)
# $(LD) $(LDFLAGS) -o $# $< $(LIBS)
%.o : %.c
$(CC) $(CFLAGS) $< -o $#
#$< -o $#
install: $(TARGET)
$(INSTALL) $^ $(DESTDIR)/usr/bin
clean :
rm -rf *.o $(TARGET) $(OBJ)
# ----------------------------------------------------------------------------
.PHONY: $(PHONY) install clean
# End of file
# vim: syntax=make
#EOF
Now if my project contains folder contains subfolders & they contains further files. Then can i write pattern rule to compile every file & create an common executable?
1> Do i will have to create makefile in every-subfolder so that i can invoke that makefile from main makefile, like integrating static driver to linux kernel each driver have respective makefile ?
2> Or common makefile for full project ?
3> can i use patsubst to compile every file without mentioning there name.
4> How can i combine every *.o to create on executable called main.
Edit :---
#Jan Hudec
I have modified my makefile as per your comment (i have posted it above). Now i am just trying with two folders inside my main folder. I am getting following error
Folder structure :--
main Folder ----> one Folder
----> two Folder
Folder Main contains :--
main.c
main.h
Makefile
Folder one contains :--
one.c
one.h
Folder two contains :--
two.c
two.h
main.c content :--
#include <stdio.h>
#include <stdlib.h>
#include "main.h"
int main()
{
char *p;
printf("\n\n main \n");
one();
two();
return 0;
}
main.h content :---
#include "one/one.h"
#include "two/two.h"
one.c content :---
#include <stdio.h>
#include <stdlib.h>
#include "one.h"
void one()
{
printf("\n one \n");
}
one.h content :---
void one();
two.c content :---
#include <stdio.h>
#include <stdlib.h>
#include "two.h"
void two()
{
printf("\n two \n");
}
two.h content :---
void two();
Error i got at make time :----
ignite#ignite:~/testing/main$ make
gcc -c -O2 main.c -o main.o
gcc -c -O2 one/one.c -o one/one.o
gcc -c -O2 two/two.c -o two/two.o
ld -o led_player_project main.o one/one.o two/two.o
ld: warning: cannot find entry symbol _start; defaulting to 0000000008048080
main.o: In function `main':
main.c:(.text.startup+0x11): undefined reference to `puts'
one/one.o: In function `one':
one.c:(.text+0xb): undefined reference to `puts'
two/two.o: In function `two':
two.c:(.text+0xb): undefined reference to `puts'
make: *** [led_player_project] Error 1
ignite#ignite:~/testing/main$
Ad 1 and 2: The filenames can safely include directories and % matches / as necessary. So you can easily have:
$(wildcard subdir/*.c) $(wildcard anotherdir/*.c)
or even
$(wildcard */*.c)
... or as suggested by keltar in comment
$(shell find . -name '*.c')
which is recursive.
Ad 3: You are doing it.
Ad 4: Create a target with $(OBJ) as dependencies and use the automatic variable just as you do for compilation:
main : $(OBJ)
$(LD) $(LDFLAGS) -o $# $< $(LIBS)
Perhaps another solution too. I have a source directory in my project dir which contains subdirectories. And I dont want have a Makefile in every subdirectories or something else. And I want to build everything only with one makefile in rootdir of project: So for my static library in c++ i did this makefile. Perhaps it could be a solution for you too. But I didnt test it well with paralell builds via "make -j4" or so.
BUILDCXX=g++-10
CHECKCXX=clang++-12
CXXFLAGS=-std=c++17 -Wall -Werror -Wextra -g -pg -O0 -I. -DDEBUG
CXXFLREL=-std=c++17 -Wall -Werror -Wextra -O3 -s -I. -DNDEBUG
CXXFLAGSLIB=$(CXXFLAGS)
CXXFLAGSTST=$(CXXFLAGS) -DRLOG_COMPONENT="clbc"
LDFLAGS=
LDFLAGSLIB=$(LDFLAGS)
LDFLAGSTST=$(LDFLAGS) -L./target/lib -lUnitTest++ -lclbc
OUTDIR=target
OUTDIRLIB=$(OUTDIR)/lib
OUTDIRTST=$(OUTDIR)/bin
OUTDIROBJ=$(OUTDIR)/obj
OUTFILELIB=libclbc.a
OUTFILETST=runtests
SRCDIR=source
SRCDIRLIB=$(SRCDIR)/lib
SRCDIRTST=$(SRCDIR)/test
SRCDIRSLIBR := $(shell find $(SRCDIRLIB) -maxdepth 3 -type d)
SRCFILESLIB := $(foreach dir,$(SRCDIRSLIBR),$(wildcard $(dir)/*.cpp))
OBJFILESLIB := $(addprefix $(OUTDIROBJ)/,$(notdir $(patsubst %.cpp,%.o,$(SRCFILESLIB))))
SRCDIRSTSTR := $(shell find $(SRCDIRTST) -maxdepth 3 -type d)
SRCFILESTST := $(foreach dir,$(SRCDIRSTSTR),$(wildcard $(dir)/*.cpp))
OBJFILESTST := $(addprefix $(OUTDIROBJ)/,$(notdir $(patsubst %.cpp,%.o,$(SRCFILESTST))))
.PHONY: all
all: clean lib
check-syntax:
$(CHECKCXX) $(CXXFLAGS) -s -o /dev/null -S $(CHK_SOURCES)
clean:
#rm -rf $(OUTDIR)
lib:$(OBJFILESLIB)
#mkdir -p $(OUTDIRLIB)
#echo " TargetLib :" $(OUTDIRLIB)/$(OUTFILELIB)
# ar rcs $(OUTDIRLIB)/$(OUTFILELIB) $^
test:$(OBJFILESTST)
#mkdir -p $(OUTDIRTST)
#echo "TargetTest :" $(OUTDIRTST)/$(OUTFILETST)
# $(BUILDCXX) $(OBJFILESTST) -o $(OUTDIRTST)/$(OUTFILETST) $(LDFLAGSTST)
release: CXXFLAGSLIB=$(CXXFLREL)
release:$(OBJFILESLIB)
#mkdir -p $(OUTDIRLIB)
#echo "RTargetLib :" $(OUTDIRLIB)/$(OUTFILELIB)
# ar rcs $(OUTDIRLIB)/$(OUTFILELIB) $^
define set_real_src_file
$(eval REAL_SRC_FILE=$(strip $(1)))
endef
define set_nothing
endef
define get_real_src_file
$(if $(strip $(findstring $(strip $(1)),$(strip $(2)))),$(call set_real_src_file,$(2)),$(call set_nothing))
endef
define get_source_file
#echo ObjectFile : $(1)
$(eval REAL_SRC_SEARCH=$(notdir $(patsubst %.o,%.cpp,$(1))))
$(eval REAL_SRC_FILE=)
$(foreach word,$(2), $(call get_real_src_file, $(REAL_SRC_SEARCH),$(word)))
endef
$(OBJFILESLIB): $(SRCFILESLIB)
#mkdir -p $(OUTDIROBJ)
$(call get_source_file,$#,$^,$<)
# $(BUILDCXX) $(CXXFLAGSLIB) -c $(REAL_SRC_FILE) -o $#
$(OBJFILESTST): $(SRCFILESTST)
#mkdir -p $(OUTDIROBJ)
$(call get_source_file,$#,$^,$<)
# $(BUILDCXX) $(CXXFLAGSTST) -c $(REAL_SRC_FILE) -o $#
But I guess it runs only with GNUMake and no other implementations of make.

Resources