I'm writing a makefile like so:
LIB_DIR = $(shell pwd)/.linuxbrew/Cellar/boost/1.62.0/
FLAGS = -std=c++14
INC= -I$(LIB_DIR)include
LIB_PATH = -L$(LIB_DIR)lib
LIB = $(LIB_DIR)lib
LIBNAMES := filesystem-mt filesystem system-mt system
LIBS := $(foreach N,$(LIBNAMES),$(LIB)libboost_$N.a $(LIB)libboost_$N.dylib)
PATH = /Some/Path/
default:
g++ main.cpp $(FLAGS) $(INC) $(LIB_PATH) $(LIBS) -o assemble
./assemble $(PATH)
clean:
rm assemble
The problem is, once I include the variable 'LIB_DIR', it complains that g++ can't be found. I could use some help.
It's not LIB_DIR, but rather PATH that's killing you. Try commenting out that line. (I'm assuming g++ is not in /Some/Path/)
Try the below command:
yum groupinstall 'Development Tools'
The command install all development tools like make, gcc, etc.
Related
Here is my makefile.
# The intuitive "all" target will be our default.
.DEFAULT_GOAL := all
# Component dir's to search and invoke make.
# (Try preserving the order of directories)
COM := src_dir1 src_dir2 src_dir3
PROJ_DIR = $(shell pwd)
EXEC := anonymousforconfidentiality
CC := g++
CFLAGS := -g3
LIBS = `pkg-config --cflags --libs glib-2.0 gio-unix-2.0 bluez protobuf lrt`
.PHONY : clean compile link all
all: | clean compile link
link:
$(eval $#_ALLOBJECTS := $(shell find . -name '*.o'))
$(CC) $(CFLAGS) -o $(EXEC) $($#_ALLOBJECTS) $(LIBS)
compile:
for COMDIR in $(COM) ; do \
$(MAKE) INCLUDE_PATH=$(PROJ_DIR) -C $$COMDIR ; \
done
clean:
for COMDIR in $(COM) ; do \
rm -f $$COMDIR/bin/*.o ; \
done
rm -f $(EXEC)
I am not able to link the library 'lrt'. I make extensive use of POSIX real time such as mq_open(), mq_send(), mq_receive() etc... So it is imperative I link it.
Some of the variations I tried:
1. librt
2. lrt
3. rt
4. librt-dev
However I always get this error:
Package lrt was not found in the pkg-config search path.
Perhaps you should add the directory containing `lrt.pc'
to the PKG_CONFIG_PATH environment variable
No package 'lrt' found
I even tried to manually install "librt" but was unsuccessful in locating the package. Nor did apt-get find it.
I was assuming this lib comes prepackaged with Ubuntu normal kernel (no real time patch). Need help with resolution of this issue.
You probably want to link rt library. This is done with -lrt. No need to use pkg-config for it.
E.g.:
LIBS := `pkg-config --libs glib-2.0 gio-unix-2.0 bluez protobuf` -lrt
Pardon my question, I am a beginner to GCC. I have a framework project that holds source code for multiple subcomponents.
The structure is below:
Framework/
makefile //Master makefile in root
Component1/
src/
bin/
makefile
Component2/
src/
bin/
makefile
...
...
...
ComponentN/
src/
bin/
makefile
Now each makefiles in ComponentN/ each of directories will compile the code in its respective src/ and output .o to bin/ directory.
The root makefile however searches all the .o files recursively and links them all into one executable named 'framework'
Problem:
For code dependencies like glib,gdbus,gio I have to link them once when creating .o objects, in each of the component projects.
Plus I have to link the dependencies again when linking all the .o into one executable at root level.
Why do I have to do it twice? I am interested in understanding the internal mechanics.
As per request I am putting in makefile of the individual component libs that products *.o files
CC = gcc
CFLAGS = -g3
LIBS = `pkg-config --cflags --libs glib-2.0`
BINDIR = bin
OUTOBJ = $(addprefix $(BINDIR)/, objex.o)
$(BINDIR)/%.o : %.c
$(CC) -c $< $(CFLAGS) -o $# $(LIBS)
all: $(OUTOBJ)
$(OUTOBJ): | $(BINDIR)
$(BINDIR):
mkdir $(BINDIR)
.PHONY: clean
clean:
rm bin/*
Object files (.o) are created by compilation commands, e.g.
gcc -c -o foo.o foo.c ...
g++ -c -o baz.o baz.cpp ...
-c means compile; don't link. No linkage happens in the creation of
object files by the compiler. Any linkage options that you add to a compilation
command, e.g.
gcc -c -o foo.o foo.c -L/my/libs -lbar -lgum
are simply ignored.
Linkage options are acted on by a linkage command, which creates a program, or shared/dynamic
library, by linking together object files and libraries, e.g.
gcc -o prog foo.o baz.o -L/my/libs -lbar -lgum
gcc -shared -o libfoobaz.so foo.o baz.o -L/my/libs -lbar -lgum
So:
For code dependencies like glib,gdbus,gio I have to link them once when creating .o objects, in each of the component projects.
No you don't, and you can't.
Later
With sight of the problem makefile it is quite clear how to eliminate
the $(LIBS) reference from the compilation recipe, and what has been stopping you. The makefile defines:
LIBS = `pkg-config --cflags --libs glib-2.0`
which is a mistake. That makes $(LIBS) expand to the standard output of the
command:
pkg-config --cflags --libs glib-2.0
which is a single string containing both the compilation options required
for compiling source that #include-s the glib-2.0 API (on account of --cflags)
and also the linkage options required for linking a program or shared library
against libglib-2.0 (on account of --libs). On my system that is:
$ pkg-config --cflags --libs glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0
of which the compilation options alone would be output by:
$ pkg-config --cflags glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
and the linkage options alone would be output by:
$ pkg-config --libs glib-2.0
-lglib-2.0
But because both sets of options are available only together through the expansion
of $(LIBS) you cannot successfully compile without passing the
linkage option -lglib-2.0, which is redundant and ignored.
As your make tool is evidently GNU Make, the makefile (which BTW is not that bad!) would be better written as:
Makefile
CC := gcc
CFLAGS := -g3 $(shell pkg-config --cflags glib-2.0)
BINDIR := bin
SRCS := objex.c
OUTOBJ := $(addprefix $(BINDIR)/, $(SRCS:.c=.o))
.PHONY: all clean
all: $(OUTOBJ)
$(BINDIR)/%.o : %.c
$(CC) -c $< $(CFLAGS) -o $#
$(OUTOBJ): | $(BINDIR)
$(BINDIR):
mkdir -p $(BINDIR)
clean:
$(RM) $(OUTOBJ)
which dispenses with LIBS and runs from scratch like:
$ make
mkdir -p bin
gcc -c objex.c -g3 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -o bin/objex.o
Note a few other improvements:-
The use of immediate expansion (:=) wherever applicable in preference to unnecessary
recursive expansion (=). See 6.2 The Two Flavors of Variables
The use of direct shell substitution by make - $(shell command) - in preference to backtick-expansion in
recipe execution. See 8.13 The shell Function.
all, like clean is a phony target
and you need to tell make that it is, to avoid the booby-trap in which something creates a file called all in
the project directory without you noticing and make mysteriously stops detecting any work for it to do.
With your clean receipe:
clean:
rm bin/*
make clean will fail if ever run except following a successful build. The recipe
is replaced with $(RM) $(OUTOBJ), using GNU Make's predefined delete macro, which
won't fail.
Finally, remember that your linkage recipe, wherever it is, does need the library options for glib-2.0,
which you should provide in its makefile with:
LIBS := $(shell pkg-config --libs glib-2.0) # ...and any more library options required
for use in a recipe similar to:
prog: $(OBJS)
$(CC) -o $# $(LDFLAGS) $^ $(LIBS)
[1] Strictly, preprocessor options should appear in the definition of CPPFLAGS
(C PreProcessor Flags), not to be confused with CXXFLAGS (C++ compilation options).
[2] Strictly, linkage options other than libraries should appear in the definition
of LDFLAGS.
I'm trying to compile the following code with SDCC, in Debian using only VIM and a Makefile:
void main(void) {
}
Yes, that simple, it's not working yet. I'm using a Makefile like this :
# GNU/Linux specific Make directives.
# Declare tools.
SHELL = /bin/sh
CC = sdcc
LD = gplink
ECHO = #echo
MCU = 16f88
ARCH = pic14
CFLAGS = -m$(ARCH) -p$(MCU)
LDFLAGS = -c -r -w -m I /usr/share/sdcc/lib/$(ARCH)/
EXECUTABLE = t1
SOURCES = test2.c
OBJECTS = $(SOURCES:.c=.o)
CLEANFILES = test2.o test2.asm test2.map test2.lst
.SUFFIXES: .c .o
.PHONY: clean
# Compile
all: $(EXECUTABLE)
.c.o:
$(AT) $(CC) $(CFLAGS) -o $*.o -c $<
$(EXECUTABLE): $(OBJECTS)
$(AT) $(LD) $(LDFLAGS) $(OBJECTS) -o $(EXECUTABLE)
clean:
$(AT) rm -rf $(CLEANFILES)
After all of this the output after running the makefile is:
sdcc -mpic14 -p16f88 -o test2.o -c test2.c
gplink -c -r -w -m I /usr/share/sdcc/lib/pic14/ test2.o -o t1
make: *** [t1] Segmentation fault
I have tried more complex code with the same result,
I can't see what's wrong, anyone ?
I see several things that can be causing you problems:
When you compile for PICs using SDCC, you need the option --use-non-free because some PIC header files have a special Microchip Licence which is not GPL compatible. Furthermore, --use-non-free might not be available on Debian because of their freedom policy if you installed SDCC from repositories. You would need to install the latest SDCC from the official website.
On the linking stage, you should include the PIC libraries needed to run. Try executing sdcc -mpic14 -p16f88 --use-non-free -V test2.c. This way, SDCC links automatically and With -V (verbose) you can see the calls to assembler and linker and can see the libraries that are added on linkage.
I'm using opencv on mac, every time I compile the program, I have to type:
g++ -I /usr/local/include -L /usr/local/lib main.cpp
What can I do to avoid typing -I and -L params?
Create a Makefile:
CXXFLAGS=-I /usr/local/include -O3 -DSOMETHING
LDFLAGS=-L /usr/local/lib
LIBS=-lwhatever
main: main.o
$(LD) -o $# $* $(LDFLAGS) $(LIBS)
main.o: main.cpp
And then just type make at the command prompt:
$ make
trojanfoe is almost right, but the makefile doesn't use the conventional names. If it did, it would be even simpler:
CXXFLAGS=-I /usr/local/include -O3 -DSOMETHING
LDFLAGS=-L /usr/local/lib
LDLIBS=-lwhatever
With that makefile you can just type make main and make will use its implicit rules for compiling a C++ file
I am compiling one C file in Ubuntu but I am getting an error in including a header file. My Makefile is as follows:
obj-m := ov7725.o
CC = /opt/arm-linux-gnueabi/bin/arm-linux-gnueabi-gcc
EXTRA_CFLAGS +=-march=armv5
CFLAGS += -I /usr/local/arm/3.3.2/arm-linux/sys-include/linux
#LINUXKERNEL_INSTALL_DIR = /lib/modules/2.6.32-21-generic/build
#CFLAGS = -Wall -I $(LINUXKERNEL_INSTALL_DIR)
#export LINUXKERNEL_INSTALL_DIR CROSS_COMPILE CFLAGS PLATFORM
KDIR := /home/mayank/DM355SDK789311old/fs/fs/lib/modules/2.6.29-ridgerun-davinci1/build
#/lib/modules/2.6.32-32-generic-pae/build
PWD := $(shell pwd)
default:
# $(MAKE) -C $(KDIR) M=$(PWD) modules
make -C $(KDIR) ARCH=arm CROSS_COMPILE=/opt/arm-linux-gnueabi/bin/arm-linux- gnueabi- M=`pwd` modules
#all:
# $(CROSS_COMPILE) gpio_custom_dir_driver.c -o hello
clean:
rm -rf *o user_gpio
But even after including the line with CFLAGS in the makefile, I am getting an error for one header file not included which is present in the included directory.
Is there any other way, how can I include header files in a makefile?
Your CFLAGS and EXTRA_CFLAGS are not applied correctly. In makefile they are just common names for C compiler options/definitions and have to be added into command line invoking compiler (CROSS_COMPILE), but not through environment variables (as you tried to do with export - which is apparently wrong in makefile). You have to have something similar to the following in your makefile:
<target>:
$(CROSS_COMPILE) $(CFLAGS) $(EXTRA_CFLAGS) ....