Compilation issue while using traceroute in a custom tool - linux

For my master thesis, I am developing a tool to test and evaluate a formula for multipath networks.
I will be using the traceroute tool to trace the network between two multihomed hosts by passing to it -s flag, src IP and dst IP. I have multiple source and dest IPs. So the traceroute will be performed multiple times.
I am not good with compilation stuff. The downloaded code for traceroute-2.1.0 from the website https://sourceforge.net/projects/traceroute/files/traceroute/ has following "make" related files.
Makefile
make.defines
make.rules
default.rules
I have applied my changes to the code in traceroute.c, and I can compile it properly by "make" and "make install". But these changes are made to the traceroute tool for the system(obviously).
What I want to achieve is, to have it with a new name, for example "mytrace" instead of "traceroute". So it doesnt come in conflict with the traceroute tool and I could use both tools. Calling with "traceroute" and other with "mytrace" in cmd line.
Question is: What changes I must make before recompiling, in order to achieve it.
Here is the code of the file "makefile".
# Global Makefile.
# Global rules, targets etc.
#
# See Make.defines for specific configs.
#
srcdir = $(CURDIR)
override TARGET := .MAIN
dummy: all
include ./Make.rules
targets = $(EXEDIRS) $(LIBDIRS) $(MODDIRS)
# be happy, easy, perfomancy...
.PHONY: $(subdirs) dummy all force
.PHONY: depend indent clean distclean libclean release store libs mods
allprereq := $(EXEDIRS)
ifneq ($(LIBDIRS),)
libs: $(LIBDIRS)
ifneq ($(EXEDIRS),)
$(EXEDIRS): libs
else
allprereq += libs
endif
endif
ifneq ($(MODDIRS),)
mods: $(MODDIRS)
ifneq ($(MODUSERS),)
$(MODUSERS): mods
else
allprereq += mods
endif
ifneq ($(LIBDIRS),)
$(MODDIRS): libs
endif
endif
all: $(allprereq)
depend install: $(allprereq)
$(foreach goal,$(filter install-%,$(MAKECMDGOALS)),\
$(eval $(goal): $(patsubst install-%,%,$(goal))))
what = all
depend: what = depend
install install-%: what = install
ifneq ($(share),)
$(share): shared = yes
endif
ifneq ($(noshare),)
$(noshare): shared =
endif
$(targets): mkfile = $(if $(wildcard $#/Makefile),,-f
$(srcdir)/default.rules)
$(targets): force
#$(MAKE) $(mkfile) -C $# $(what) TARGET=$#
force:
indent:
find . -type f -name "*.[ch]" -print -exec $(INDENT) {} \;
clean:
rm -f $(foreach exe, $(EXEDIRS), ./$(exe)/$(exe)) nohup.out
rm -f `find . \( -name "*.[oa]" -o -name "*.[ls]o" \
-o -name core -o -name "core.[0-9]*" -o -name a.out \) -print`
distclean: clean
rm -f `find $(foreach dir, $(subdirs), $(dir)/.) \
\( -name "*.[oa]" -o -name "*.[ls]o" \
-o -name core -o -name "core.[0-9]*" -o -name a.out \
-o -name .depend -o -name "_*" -o -name ".cross:*" \) \
-print`
libclean:
rm -f $(foreach lib, $(LIBDIRS), ./$(lib)/$(lib).a ./$(lib)/$(lib).so)
# Rules to make whole-distributive operations.
#
STORE_DIR = $(HOME)/pub
release release1 release2 release3:
#./chvers.sh $#
#$(MAKE) store
store: distclean
#./store.sh $(NAME) $(STORE_DIR)

I wrote to the programmer of the tool, his solution worked for me. Here it is:
Just rename the sub-directory "traceroute" to another name, say "mytrace".
IOW, you'll have "include, libsupp, mytrace" instead of "include, libsupp, traceroute".
Additionally, if you plan to create a tarball with the changed name etc., it seems that you have to rename "NAME = traceroute" to "NAME = mytrace" in the Make.defines file.
Best regards,
Dmitry Butskoy

Related

makefile with many source folders

The original makefile I have, which works, only involves one source folder and the makefile is stored inside this folder. Now I have multiple folders inside my src folder.
I am using an autogeneration script to work out dependencies and objective files. Each subfolder has a Make-deps and Make-objs file. These are generated from the $(AUTOGEN) command
Before I had this:
deps:
$(AUTOGEN) -d -s $(SRCDIR) -f ../scripts/fgenrc ;\
sed -i "" -e's/(SRCDIR)/(OBJDIR)/' Make-objs ; \
sed -i "" -e's/(SRCDIR)\(.*\)\.o/(OBJDIR)\1\.o/g' Make-deps ; \
So $(AUTOGEN) is just the shell script which makes the dependencies and $(SRCDIR) is where the source files are. Make-obj and Make-deps are the files containing the dependencies and objective file names.
Somewhere else I have the following:
$(OBJDIR)/%.o: %.f Makefile
#$(F90) $(FFLAGS) $(POPTIONS) -o $# $<
Now I want to this but where my %.f files are in various folders, and also where I have several Make-obj and Make-deps.
Maybe I should show an example of Make-obs and Make-deps:
Make-deps:
$(OBJDIR)/fluxes.o fluxes.o: \
path/to/src/folder1/fluxes.f90 \
$(OBJDIR)/mod.o \
$(OBJDIR)/ig.o ig.o: \
path/to/src/folder1/ig.f90 \
$(OBJDIR)/mod.o \
from the sed command I change the objective file path to be $(OBJDIR) because this is where I move them when being compiled.
Make-obj
OBJS = \
$(OBJDIR)/fluxes.o \
$(OBJDIR)/ig.o \
Now I have defined
SOURCE_FILES_c := $(shell find $(SRCDIR) -name '*.c')
SOURCE_FILES_f90 := $(shell find $(SRCDIR) -name '*.f90')
which are all source files found the SRCDIR and its subfolders. Also I have defined
DEPS_FILES := $(shell find $(SRCDIR) -name 'Makefile-deps')
OBJS_FILES := $(shell find $(SRCDIR) -name 'Makefile-objs')
which are all dependency and objective files. These are found in each subfolder containing some source code.
Then, I am trying to do following. (The target deps seems to work as when I comment out the compilation rule it does create the deps and objs file correctly in each folder.)
code: create_dir deps scripts
#make -j $(CORES) $(NAMEEXE)
$(NAMEEXE): $(LIBRARY) $(OBJS)
#$(F90) $(FFLAGS) $(OPTIONS) -o $(OBJDIR)/$(MAIN).o main/$(MAIN).f90
#$(F90) -o $(NAMEEXE) $(LOPTIONS) $(OBJS) $(LIBRARY) && \
deps:
${AUTOGEN} -d $(AUTOGEN_COMMAND) -f ${AUTOCONF} ; \
$(SEDI) -e "s/[(][^)]*[)]/\$$(OBJDIR)/g" $(OBJS_FILES) ; \
$(SEDI) -e "s/[(][^)]*[)]\(.*\)\.o/\$$(OBJDIR)\1\.o/g"
$(DEPS_FILES) ; \
$(OBJDIR)/%.o: $(SOURCE_FILES_f:.f90=.o) Makefile
#$(F90) $(FFLAGS) $(POPTIONS) -o $# $< && \
( mv -f *.mod $(OBJDIR) > /dev/null 2>&1;
$(OBJDIR)/%.o: $(SOURCE_FILES_c:.c=.o) Makefile
#$(F90) $(FFLAGS) $(POPTIONS) -o $# $< && \
( mv -f *.mod $(OBJDIR) > /dev/null 2>&1;
%.o: $(SOURCE_FILES_c:.c=.o) Makefile
#make $(OBJDIR)/$#
%.o: $(SOURCE_FILES_c:.c=.f90) Makefile
#make $(OBJDIR)/$#
I am including the deps and objs by this command
-include $(DEPS_FILES)
-include $(OBJS_FILES)
I obviously did not want put the entire makefile here, but if something is missing before you can understand what's going on please let me know.
When I type make the error I get is that my $(main) source file cannot open the compiled module file which is included in the main source.
This is because it is not compiled, but this also means that my dependency file is not working as intended?
When I look into my corresponding dep file which includes the main file, I can see that the dependency modules are added to the source file

Makefile: Run multiple targets

I would like to run two targets using a makefile but don't know how to specify the targets from the command line.
This is my makefile.
.PHONY: all clean test
PYTHON=python
PYTESTS=pytest
all:
$(PYTHON) setup.py build_ext --inplace
clean:
find . -name "*.so" -o -name "*.pyc" -o -name "*.md5" -o -name "*.pyd" | xargs rm -f
find . -name "*.pyx" -exec ./tools/rm_pyx_c_file.sh {} \;
benchmark_coverage:
$(PYTESTS) benchmarks --cov=skimage
coverage: test_coverage
test_coverage:
$(PYTESTS) -o python_functions=test_* skimage --cov=skimage
So, I'm mainly interested in coverage, benchmark_coverage and test_coverage.
When I run the command make coverage, it runs$(PYTESTS) -o python_functions=test_* skimage --cov=skimage.
When I run make bench_coverage, it runs
$(PYTESTS) benchmarks --cov=skimage.
Now, I want to run both of these together, how do I do this?
Someone suggested me make coverage bench_coverage but it only runs the first command.
Please help.
Thanks
I tried creating the following Makefile:
a:
echo a
b:
echo b
and if I run make a b it runs both, so running multiple targets actually is allowed.

How not to remake pre-requisites when final target exists with Make

In the following Makefile, I would like make not to remake the ALL md5 files when the final file: checksums.md5 already exists:
SOURCEDIR := .
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
STAGES := .md5
CAT := checksums.md5
ALL := $(foreach I, $(STAGES), $(addsuffix $I, $(SOURCES)))
all : ${CAT}
%.md5: %
md5sum $< > $#
${CAT} : ${ALL}
cat $^ >> $#
rm *gz.md5
You can use conditionals. Example:
SOURCEDIR := .
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
STAGES := .md5
CAT := checksums.md5
ALL := $(foreach I,$(STAGES),$(addsuffix $(I),$(SOURCES)))
ifeq ($(wildcard $(CAT)),)
all: $(CAT)
%.md5: %
md5sum $< > $#
$(CAT): $(ALL)
cat $^ >> $#
rm $(ALL)
else
all:
#echo "Nothing to be done"
endif
Explanation: if checksums.md5 exists, $(wildcard $(CAT)) will expand as checksums.md5 (not the empty string) and the ifeq conditional will instantiate what is between else and endif. If checksums.md5 does not exist, $(wildcard $(CAT)) will expand as the empty string and the ifeq conditional will instantiate what is between ifeq and else. It is a bit like if you had two different Makefiles for the two situations.
Notes:
I suppressed useless spaces in your foreach call (avoid useless spaces with make, they may have an impact on its behavior).
Do not suppress the space between ifeq and ($(wildcard..., it is needed.
I replaced curly braces (obsolete) by parentheses.
I added parentheses to references to non-automatic variables ($I => $(I)) because it is strongly advised.
I replaced rm *gz.md5 by rm $(ALL) which seems better if you have some of your sources in sub-directories.
General remark: what you do is not inline with the make philosophy. make decides what should be done and what should not, based on the last modification time of files and a set of target-prerequisites dependency specifications. If you do not use this feature of make you should probably not use it at all. Any scripting language (bash, python, perl...) would probably be better.
If you do not want these partial md5 files, why don't you directly put the sums in checksums.md5? Example:
SOURCEDIR := .
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
CAT := checksums.md5
all: $(CAT)
$(CAT): $(SOURCES)
md5sum $^ > $#
clean:
rm -f $(CAT)
If checksums.md5 exists and is up-to-date (more recent than the sources), nothing will be done. Else, all md5sums will be recomputed and stored in checksums.md5.
If your problem is to avoid recomputing md5sums of files that did not change, you need to keep track of the last time you computed them and there is no better way than keeping these intermediate md5sum files. But you can put them all in a separate directory, if you wish:
SOURCEDIR := .
MD5DIR := .md5sums
SOURCES := $(shell find $(SOURCEDIR) -name '*.gz')
CAT := checksums.md5
ALL := $(addprefix $(MD5DIR)/,$(patsubst %,%.md5,$(SOURCES)))
all: $(CAT)
$(MD5DIR)/%.md5: %
mkdir -p $(dir $#) && \
md5sum $< > $#
$(CAT): $(ALL)
cat $^ > $#
clean:
rm -rf $(MD5DIR) $(CAT)
Notes:
Just for fun I used a different way of computing the md5sum file names ($(ALL)) using addprefix and patsubst.
The mkdir -p in the $(MD5DIR)/%.md5: % recipe is needed to create the destination directory before storing the md5sum file in it.
These destination sub-directories of $(MD5DIR) are needed if you have your sources also in sub-directories and some of them can have the same base name.

CMake Linking Path Substitute for Microsoft Asure Cross-Compiling

I am porting Microsoft Azure to OpenWrt (Atheros AR9330 rev 1#mips),
Follow the steps from https://github.com/Azure/azure-iot-sdk-c/blob/master/doc/SDK_cross_compile_example.md and https://github.com/Azure/azure-iot-sdk-c/issues/58
But I encounter a bug of the CMake script of Azure:
The libcurl would be linked by default path, for example:
in file umqtt/samples/mqtt_client_sample/CMakeFiles/mqtt_client_sample.dir/link.txt
.... -lcurl /home/gaiger/openwrt-cc/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libssl.so /home/gaiger/openwrt-cc/staging_dir/target- \\
mips_34kc_uClibc-0.9.33.2/usr/lib/libcrypto.so -lpthread -lm -lrt -luuid -Wl,-rpath
It is very obvious that the libcurl and libuuid have been adopted by default system path instead of the target system library path (but the openssl path is the target's ).
This bug has been reported to Microsoft Azure team https://github.com/Azure/iot-edge/issues/119, but it has not been fixed currently.
I found that if I substitute the -lcurl and -luuid as where they exist authentically (-lcurl -> home/gaiger/openwrt-cc/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libcurl.so, as for -luuid), the compilation would be passed. But the manual substitution is a toilsome work (for there are a lot link.txt files waiting to be modified), and it needs to be done again for next time compilation.
I have tried to modify my platform file, mips_34kc.cmake, to add the line (mentioned in the last post in https://github.com/Azure/iot-edge/issues/119 )
SET(CMAKE_EXE_LINKER_FLAGS "-Lhome/gaiger/openwrt-cc/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libcurl.so" CACHE STRING "" FORCE)
SET(MAKE_SHARED_LINKER_FLAGS "-Lhome/gaiger/openwrt-cc/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libcurl.so" CACHE STRING "" FORCE)
SET(CMAKE_C_FLAGS "-Lhome/gaiger/openwrt-cc/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libcurl.so" CACHE STRING "" FORCE)
But the link.txt did not changed.
And I tried to write a script to substitue -lcurl as home/gaiger/openwrt-cc/staging_dir/target-mips_34kc_uClibc-0.9.33.2/usr/lib/libcurl.so (use sed), it mess up the file only, and I do not know how to write a script which will seek the files recursively.
Could anyone give me a clue or help ? Thank you.
I have written a shell script to detour the bug.
# bin/bash
#Power by Gaiger Chen 撰也垓恪, to fix azure sdk error in linking stage
echo Back up file as link.txt in the same folders
find -name link.txt -exec cp {} {}.bak -f \
#find -name link.txt -exec rm {}.bak -f \;
#find . -ipath "*link.txt" -type f -exec cp {} {}.bak \;
#find . -ipath "*link.txt" -type f -exec rm {}.bak \;
FOUND_LINKINK_TXT=$(find -name link.txt)
OPENWRT_LIB_PATH=""
echo "$FOUND_LINKINK_TXT" | while read LINE_CONTENT
do
if [ -z "$OPENWRT_LIB_PATH" ]; then
OPENWRT_LIB_PATH=$(sed -rn 's/.* (.*)libssl.so .*/\1/p' "$LINE_CONTENT")
echo "$OPENWRT_LIB_PATH"
fi
echo fixing file: "$LINE_CONTENT".
sed -i "s|-lcurl|$OPENWRT_LIB_PATH/libcurl.so|g" "$LINE_CONTENT"
sed -i "s|-luuid|$OPENWRT_LIB_PATH/libuuid.so|" "$LINE_CONTENT"
done # while read LINE_CONTENT
FILE_NUM=$(echo "$FOUND_LINKINK_TXT" | wc -l)
echo "$FILE_NUM" files have been fixed.
More detail could be found in my blogger:
http://gaiger-programming.blogspot.tw/2017/07/build-and-exploit-microsoft-azure-sdk.html

How to prevent Makefile cleaning objects before linking (using -j option)

I'm trying to learn how to use linux makefiles.
I have the following two files:
makefile.config
# Project Configurations
# Project Name
PROJECT_NAME = myapp
# Project Version
PROJECT_VERSION = 0.1
# Program or Shared Library
IS_LIBRARY = no
# Source Files Directory
SRC_DIRECTORY = src
# Header Files Directory
INC_DIRECTORY = inc
# Library Header Files Directory
LIB_DIRECTORY = lib
# Build Output Directory
BIN_DIRECTORY = ../Executable
# Installation Directory Exec
INS_DIRECTORY = /usr/local/bin/
# Installation Directory Headers
INS_HEARERS_DIRECTORY = /usr/local/include/
# Installation Directory SO
INS_SO_DIRECTORY = /usr/local/lib/
# C Flags
CFLAGS = -O3 -D_GNU_SOURCE -Wfatal-errors
# C++ Flags
CXXFLAGS = $(CFLAGS)
# Linker Flags
LDFLAGS = $(shell dpkg-buildflags --get LDFLAGS)
# Linker Libraries
LDLIBS = -fno-inline
# Debug Yes / No
DEBUG = yes
# C Compiler
CC = gcc
# C++ Compiler
CXX = g++
Makefile
$(info Starting building process)
# include configurations
include makefile.conf
$(info - Makefile.conf loaded)
# find project files
H_FILES := $(shell find -L ./ -name '*.h' -exec dirname {} \; | sed 's/ /\\ /g' | uniq)
C_FILES := $(shell find ./ -name '*.c' -type f | sed 's/ /\\ /g' | uniq)
CXX_FILES := $(shell find ./ -name '*.cpp' -type f | sed 's/ /\\ /g' | uniq)
O_FILES := $(C_FILES:.c=.o)
O_FILES += $(CXX_FILES:.cpp=.o)
H_FILES := $(notdir $(H_FILES))
C_FILES := $(notdir $(C_FILES))
CXX_FILES := $(notdir $(CXX_FILES))
INCLUDES := $(H_FILES:%=-I%)
$(info - Project Files Loaded)
ifeq ($(DEBUG),yes)
$(info - Debug flag added [makefile.conf DEBUG = yes])
CFLAGS := -g3 $(CFLAGS)
endif
ifeq ($(IS_LIBRARY),yes)
$(info - Set Parameters for Shared Library build process)
ALL_PARAMETERS = lib$(PROJECT_NAME).so.$(PROJECT_VERSION) clean
ALL_TYPE = lib$(PROJECT_NAME).so.$(PROJECT_VERSION): $(O_FILES)
LIBFLAGS = -shared -Wl,-soname,lib$(PROJECT_NAME).so
CFLAGS := -fPIC $(CFLAGS)
CXXFLAGS := -fPIC $(CXXFLAGS)
else
$(info - Set Parameters for Application build process)
ALL_PARAMETERS = $(PROJECT_NAME) clean
ALL_TYPE = $(PROJECT_NAME): $(O_FILES)
LIBFLAGS =
endif
# Build Process
all: $(ALL_PARAMETERS)
$(ALL_TYPE)
#echo - [OUTPUT][CXX] $# #[$(BIN_DIRECTORY)]
#$(CXX) $(CFLAGS) $(INCLUDES) $(LDFLAGS) $(LIBFLAGS) -o $(BIN_DIRECTORY)/$# $^ $(LDLIBS)
%.o: %.c
#echo - [CC] $#
#$(CC) $(CFLAGS) -c $(INCLUDES) -o $# $< $(LFLAGS)
%.o: %.cpp
#echo - [CXX] $#
#$(CXX) $(CXXFLAGS) -c $(INCLUDES) -o $# $< $(LFLAGS)
# Clear Objects
clean:
$(info - Remove all .o [object] files)
#find . -name \*.o -type f -delete
# Clear Objects & Executables
cleanall:
$(info - Remove all .o [object] files)
#find . -name \*.o -type f -delete
$(info - Remove all files in $(BIN_DIRECTORY))
#find $(BIN_DIRECTORY) -name \*.* -type f -delete
# Install Project
install:
#cp -r $(BIN_DIRECTORY)/lib$(PROJECT_NAME).so.$(PROJECT_VERSION) $(INS_SO_DIRECTORY)
#cp -r $(LIB_DIRECTORY)/* $(INS_HEARERS_DIRECTORY)
#ln -s $(INS_SO_DIRECTORY)/lib$(PROJECT_NAME).so.$(PROJECT_VERSION) $(INS_SO_DIRECTORY)/lib$(PROJECT_NAME).so
#ldconfig
$(info - Installation completed)
# Uninstall Project
uninstall:
#rm $(INS_SO_DIRECTORY)/lib$(PROJECT_NAME).so
#rm $(INS_SO_DIRECTORY)/lib$(PROJECT_NAME).so.*.*
#rm $(INS_HEARERS_DIRECTORY)/$(PROJECT_NAME).h
#ldconfig
$(info - Uninstallation completed)
Everything works perfect ...well at least for what i'm using it for.. however when i try to execute the makefile with -j option (ex.)
$ make -j4
the procedure cleans the objects (.o) before linking them.
iikem#isca-lab:Source Code$ make -j4
Starting building process
- Makefile.conf loaded
- Project Files Loaded
- Debug flag added [makefile.conf DEBUG = yes]
- Set Parameters for Shared Library build process
- [CXX] src/isca-streamer.o
- [CXX] src/isca-streamer-pause.o
- [CXX] src/isca-streamer-thread-image.o
- [CXX] src/isca-streamer-initialize.o
- [CXX] src/isca-streamer-start.o
- [CXX] src/isca-streamer-stop.o
- [CXX] src/isca-streamer-thread-socket.o
- [CXX] src/isca-streamer-clear.o
- Remove all .o [object] files
- [CXX] src/isca-streamer-settings.o
- [OUTPUT][CXX] libisca-streamer.so.0.1 #[../Executable]
g++: error: src/isca-streamer.o: No such file or directory
g++: error: src/isca-streamer-initialize.o: No such file or directory
g++: error: src/isca-streamer-thread-image.o: No such file or directory
g++: error: src/isca-streamer-pause.o: No such file or directory
g++: error: src/isca-streamer-start.o: No such file or directory
g++: error: src/isca-streamer-stop.o: No such file or directory
Makefile:71: recipe for target 'libisca-streamer.so.0.1' failed
make: *** [libisca-streamer.so.0.1] Error 1
How can i fix this problem? (prevent cleaning objects step to execute before linking step)
You can't add clean as a prerequisite for your all target if you use -j, because it will be run in parallel with the linker and deleting files is a lot faster than linking them.
So you have to remove the clean target from your ALL_PARAMETERS variable, then you won't delete objects in the middle of your link line anymore.
I have no idea why you want to delete all the objects after every run: you don't even need make or makefiles at all if you're going to rebuild everything from scratch every time: just create a shell script. The entire point of using a makefile is to avoid rebuilding parts of the project that haven't changed.
But, if you really do want to do that then the simplest way is probably using recursive make; for example:
all: $(ALL_PARAMETERS)
$(MAKE) clean
will only ever make clean after all the prerequisites of all have completely built, even if you run with -j.

Resources