Linking files through makefiles - c++

I have two directories at the same level. I want to use the header file created in one directory in the source file of the other directory. I want to achieve the same without providing relative or absolute path to the header file.
The directory structure is:
main_dir/
dir1/
main.cpp
Makefile.am
dir2/
abc.h
abc.cpp
Makefile.am
main.cpp needs abc.h. What should be written in makefiles of both the directories in order to link them?
Edit
Makefile.am of dir2
noinst_LIBRARIES = libabc.a
AM_CPPFLAG = -I$(main_dir)/dir2 \
$(APP_CFLAGS)
libabc_a_SOURCES = abc.h \
abc.cpp
Makefile.am of dir1
noinst_LIBRARIES = libmain.a
AM_CPPFLAG = -I$(main_dir)/dir1 \
$(APP_CFLAGS)
libmain_a_SOURCES = main.cpp
libmain_a_LIBADD = libabc.a
I get the error: No rule to make target 'libabc.a', needed by 'libmain.a'. Stop.

You can use the -I option with gcc or clang. (Note this is not directly related to makefiles)
Example: If the current directory is main_dir, and you're currently running the command:
gcc -c -o dir1/main.o dir1/main.cpp
you would need to change it to something like:
gcc -Idir2 -c -o dir1/main.o dir1/main.cpp

You already have
AM_CPPFLAG = -I$(main_dir)/dir1 \
$(APP_CFLAGS)
Simply add -I$(main_dir)/dir2 into it:
AM_CPPFLAG = -I$(main_dir)/dir1 \
-I$(main_dir)/dir2 \
$(APP_CFLAGS)
So now you can #include <abc.h> in your code.

Related

From one cpp give list of the head file and hpp file used

I want to list all header files and .hpp files related to this one .cpp file.
The list also needs to include the child header files, .h files and .hpp files. How can I do this?
I'm not sure what you mean by "head file".
But you might find the following useful. (I have in my makefile.)
.PHONY: depend .depends: *.hh $(CC) $(CC_FLAGS) -M *.cc > .depends
It generates lots of information in the file I named ".depends".
HelloWorld.cc is 10 lines.
Typical output of depend contribution:
HelloWorld.o: HelloWorld.cc /usr/include/stdc-predef.h \
/usr/include/c++/7/iostream \
...
/usr/include/c++/7/bits/basic_ios.tcc \
/usr/include/c++/7/bits/ostream.tcc /usr/include/c++/7/istream \
/usr/include/c++/7/bits/istream.tcc
total lines about 1870.
Using g++ v7.2.0, ubuntu 17.10 (64)

How to recompile source file every time while using cmake 2.8.2 in single build for c++11 and c++98 for shared library creation?

I have a project directory structure of:
Root
Source
Common
MyFolder
++ My 3 source files and header
When I am building my project it generates 3 to 4 shared libraries. Lib1 compiled using c++98 and others using c++11. Flags are added in CmakeList.txt which is at root.
I need my 3 source files to be compiled for Lib1 and for other Libs as as well. but here what happens is compiler is first compiling my source file for lib using c++11 and then it is trying to use same .o file for Lib1 as well. So for .o file which is generated using c++11 is throwing exception when same is used for c++98 compiled library.
So how do write this in CmakeList.txt such that compiler rather than trying to use same .o file will compile source file again for Lib1(c++98 compiled library)
Is there any flag I can specify so that it won't take precompiled .o file and will compile it again ?
Here flags are not being overridden for different shared libraries but actually same object file by make file is being used for different flags
This is sort of counter to how makefiles and cmake usually work.
Most users consider it really important that make performs an incremental build.
The usual way with makefiles is to do make clean which is supposed to remove any binaries and object files that were created.
However, sometimes I write cmake scripts that use globbing over the source directory to assemble the project. (That means, it says "just grab all *.cpp files in the /src folder and make an executable from them".) A makefile cannot check what files in a directory, so the make build will be broken after I add a new file, and make clean won't fix it -- the whole makefile will need to be regenerated by cmake.
Usually what I do is, I write a simple bash script, named rebuild.sh or something,
#!/bin/bash
rm -rf build
mkdir build
cd build
cmake ..
make -j3
./tests
And I put that in the root of my repository, and add /build to my .gitignore. I call that when I want to do a full rebuild -- it nukes the build directory, so its foolproof. When I want an incremental rebuild, I just type make again in the /build directory.
The rebuild.sh script can also serve a double purpose if you use travis-ci for continuous integration.
Most build system assume the compiled objects remain the same within the same pass. To avoid shooting your foot I would suggest telling the build system they were actually different objects, while still compiled from same source files.
I'm not familiar with cmake but this is how you do with make:
For example you have a a.cpp which you want to compile 2 times for different compiler options:
#include <stdio.h>
int main(int argc, char* argv[]) {
printf ("Hello %d\n", TOKEN);
return 0;
}
And the Makefile would looks like:
SRC := $(wildcard *.cpp)
OBJ_1 := $(patsubst %.cpp,%_1.o,$(SRC))
OBJ_2 := $(patsubst %.cpp,%_2.o,$(SRC))
all: pass1 pass2
pass1: $(OBJ_1)
gcc -o $# $(OBJ_1) -lstdc++
pass2: $(OBJ_2)
gcc -o $# $(OBJ_2) -lstdc++
%_1.o: %.cpp
gcc -DTOKEN=1 -c $< -o $#
%_2.o: %.cpp
gcc -DTOKEN=2 -c $< -o $#
clean:
rm -f $(OBJ_1) $(OBJ_2)
What I do here is generate two different list of object from the same source files, which you can even do the same for dependency(-MMD -MP flags).

Install C++ program with automake and autoconf

I've made a program in C++, but now I must install this program with autoconf and automake.
So, when I run command "./configure && make && make install", it must do the following:
compile program
create folder my_program inside /opt (example: /opt/my_program/) and in this folder I must also have all static libraries and source files
There must be symbolic link in /usr/local/bin for my_program
Libraries must be in /usr/local/lib (DONE - Thanks to #Galik )
Header files of my_program must be in /usr/local/include (DONE)
I've wrote this configure.ac script:
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([my_program], [0.1], [my_mail])
AC_CONFIG_SRCDIR([AbsAlgorithm.hpp])
AM_INIT_AUTOMAKE
# Checks for programs.
AC_PROG_CXX
AC_PROG_CC
# Checks for libraries.
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h sys/time.h unistd.h wchar.h wctype.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_CHECK_HEADER_STDBOOL
AC_C_INLINE
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MALLOC
AC_FUNC_MKTIME
AC_CHECK_FUNCS([gettimeofday memset mkdir])
LIBS="-ldl"
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
and this Makefile.am script:
AUTOMAKE_OPTIONS = foreign
AM_CXXFLAGS=-Wall -std=gnu++11 -DVERSION=\"$(VERSION)\" -DPROG="\"$(PACKAGE)\""
bin_PROGRAMS = algatorc
noinst_LIBRARIES = libalgatorc.a
libalgatorc_a_SOURCES = Timer.cpp
include_HEADERS = Timer.hpp TestSetIterator.hpp TestCase.hpp ETestSet.hpp EParameter.hpp Entity.hpp ParameterSet.hpp AbsAlgorithm.hpp Log.hpp JSON.hpp
algatorc_SOURCES = ParameterSet.cpp TestCase.cpp EParameter.cpp ETestSet.cpp TestSetIterator.cpp Entity.cpp Timer.cpp main.cpp JSON.cpp JSONValue.cpp
Now, when I run "./configure && make && make install" I don't get new folder called my_program in /opt. But, I now, I do have header files in /usr/local/include. I don't have lib files in /usr/local/lib. There is just one folder for python. I would like to have folder called my_program and inside that folder I would like to have static libs.
I am using Ubuntu 12.04 x64
I would appreciate any help. Thanks
Autotools is not really designed to put things in specific locations. The idea is that programs go in the programs directory $(bindir), libraries in the libraries directory $(libdir) etc and that the person installing everything gets to decide where those locations are.
So you should really only care about installing things relative to wherever the person running the installer wants them to be.
They do this by adding arguments to the configure script like:
configure --prefix=/opt/myprog
That will typically install programs in /opt/myprog/bin and libraries in /opt/myprog/lib etc...
You can add to the places that things get installed by setting special dir variables. For example to put libraries in a sub-directory of $(libdir) (default /usr/local/lib) you caan do:
myprog_librarydir = $(libdir)/myprog
And its not uncommon to do the same for the header files:
myprog_includedir = $(prefix)/include/myprog
That defines some destination folders you can refer to instead of the defaults:
myprog_include_HEADERS = \
Timer.hpp \
TestSetIterator.hpp \
TestCase.hpp \
ETestSet.hpp \
EParameter.hpp \
Entity.hpp \
ParameterSet.hpp \
AbsAlgorithm.hpp \
Log.hpp \
JSON.hpp
Those will now get installed into $(prefix)/include/myprog.
Similarly with the corresponding library:
myprog_library_LIBRARIES = libmyprog.a
libmyprog_a_SOURCES = \
ParameterSet.cpp \
TestCase.cpp \
EParameter.cpp \
ETestSet.cpp \
TestSetIterator.cpp \
Entity.cpp \
Timer.cpp \
JSON.cpp \
JSONValue.cpp
So basically you create a destination (installation) directory using:
mynamedir = $(prefix)/path/... whatever
That allows you to set destinations other than bin_, lib_ and include_ etc...
So instead of saying lib_LIBRARIES you can say myname_LIBRARIES.
Hope that helps.

dbus - how to set include paths

On my system dbus headers are placed in /usr/include/dbus-1.0/dbus/ and dbus-arch-deps.h is other location (what seems to be strange): /usr/lib/x86_64-linux-gnu/dbus-1.0/include/dbus/dbus-arch-deps.h In my program I include #include<dbus-1.0/dbus/dbus.h>but in every header file which include others path looks like this: #include<dbus/xxx.h> I can copy dbus-arch-deps.h to /usr/include/dbus-1.0/dbus/ but how to fix paths in dbus headers ?
Your system likely has pkg-config installed.
g++ $(pkg-config --cflags dbus-1) main.c
Pkgconfig contains a database of linker/compiler/etc. flags that are required to use specific libraries. See man pkg-config for more info.
First of all you need to install and configure it properly.
You should try this command :
sudo apt-get -y install dbus libdbus-1-dev libdbus-glib-1-2 libdbus-glib-1-dev
Now, here is the Makefile that you should write for compiling :
all:
g++ dbus.cpp -I/usr/include/dbus-1.0 \
-I/usr/lib/x86_64-linux-gnu/dbus-1.0/include \
-I/usr/include/glib-2.0 \
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ \
-ldbus-1 \
-ldbus-glib-1
Now, you may include files like dbus/dbus.h, dbus/dbus-glib.h, etc.
You don't need to copy files.
Simply add the path of where dbus is located to your include path when compiling using the I flag:
example:
g++ -Wall -I /usr/include/dbus-1.0/ -o main.o
By using the location of where dbus is located (in the standard location of /usr/include, you can reference the files like the following in your source code:
#include <dbus/xxx.h>
Similarly, if you have to link against dbus you'll have to append that path to the Libraries inclusion path like so:
g++ -Wall -I /usr/include/dbus-1.0/ -o main.o -L <dbus library path>
Where dbus library path is where the libraries ofdbus` live. To figure this out, consult the web, or search your system.
UPDATE:
To achieve that in Qt-Creator (which I've never used), perhaps the following can help:
How to add include path in Qt Creator?

Makefile for Unit Tests in C++

I'm struggling to write Makefiles that properly build my unit tests. As an example, suppose the file structure looks like this
src/foo.cpp
src/foo.hpp
src/main.cpp
tests/test_foo.cpp
tests/test_all.cpp
So, to build the executable test_all, I'd need to build test_foo.o which in turn depends on test_foo.cpp but also on src/foo.o.
What is the best practice in this case? One Makefile in the parent folder? One Makefile per folder? If so, how do I manage the dependencies across folders?
Common practice is a Makefile per directory. That's what I would have suggested before I read "Recursive Make Considered Harmfull" (http://miller.emu.id.au/pmiller/books/rmch/). Now I'd recommend one Makefile. Also check out the automatic dependency generation - now you don't even need to work out what your tests depends on. All you need is some targets.
The common practice is one Makefile for each folder. Here is a simple Makefile.am script for the root folder:
#SUBDIRS = src tests
all:
make -C ./src
make -C ./tests
install:
make -C ./src install
uninstall:
make -C ./src uninstall
clean:
make -C ./src clean
test:
make -C ./tests test
The corresponding Makefile.am for the src folder will look like this:
AM_CPPFLAGS = -I./
bin_PROGRAMS = progName
progName_SOURCES = foo.cpp main.cpp
LDADD = lib-to-link
progName_LDADD = ../libs/
Makefile.am for tests will look similar:
AM_CPPFLAGS = -I../src
bin_PROGRAMS = tests
tests_SOURCES = test_foo.cpp test_all.cpp
Use automake to generate Makefile.in files from the .am files. The configure script will use the .in files to produce the Makefiles. (For small projects you would like to directly hand-code the Makefiles).