Running library makefile from application makefile - c

I have an application that uses my library. For both projects I have separate makefiles
My application (source code + Makefile) is in 'client' folder. At the same level I have the library folder 'mylib'.
The make file of the client application looks like this:
LIBS = -L../mylib -lmy
CFLAGS = -Wall -W -I../mylib
TARGET = clientapp
SOURCEDIR = .
SOURCES = $(wildcard $(SOURCEDIR)/*.c)
OBJECTS = $(SOURCES:.c=.o)
all: $(TARGET)
$(TARGET): $(OBJECTS)
$(CXX) $(CFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) $(LDFLAGS) -Wl,-rpath=../mylib
clean:
rm -f $(OBJECTS) $(TARGET)
Currently to make everything work I need first go to the library folder, call make there, then go to the client application folder and call make here.
What I want to do is to run everything in the client application's makefile.
I found that I need to use 'recursive make'.
But I can't make it build everything. The only library is built.
What is the right syntax for that?

Although recursive make is not the best solution in the long run, it is a viable option if you are just starting out.
At the top level you just have to create a new Makefile that only executes your two existing makefiles
.PHONY: all
all:
$(MAKE) -C mylib
$(MAKE) -C source
(the indents should be tabs, obviously)
This will execute both makefiles in their respective directories.
It is better to include the makefiles and be non-recursive, but that requires more knowledge of make. Take one step at a time.

Related

Trouble creating a transferable executable with SDL 1.2 and C

I've been having trouble compiling an executable with SDL 1.2 and C that will work on another machine. I'vee been compiling it from Ubuntu using a makefile. I'd like to be able to send a "bin.zip" to a classmate, with "SDL.dll" and "SDL_ttf.dll" inside as well as "prog" the executable that I compiled for them.
I would expect them to be able to run that "prog" from their own Ubuntu desktop (Virtual Machine, if that's relevant) and not need to install libsdl1.2debian and libsdl-ttf2.0-0 themselves first, since I included the DLLs.
Note that they can run it fine once they've installed those libraries.
My project structure, at compilation, is such:
2048-c
/bin (dlls and executable)
/include (".h" header files)
/lib ("SDL.lib", "SDL_ttf.lib", "SDLmain.lib")
/src (".c" source files)
"makefile"
My makefile looks like this:
CC=gcc
CFLAGS=-c -Wall `sdl-config --cflags`
LDFLAGS=`sdl-config --libs` -lSDL_ttf
SOURCES=src/main.c src/toolbox.c src/game.c
OBJECTS=$(SOURCES:.c=.o)
EXECUTABLE=bin/prog
.PHONY: clean
all: $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $#
.c.o:
$(CC) $(CFLAGS) $< -o $#
clean:
rm -f $(OBJECTS) $(EXECUTABLE)
Am I missing something obvious? Edit: (Yes, I was)
Yes, I was missing something obvious : DLLs are specifically for Windows
Now, as for getting an executable to work without installing the required libraries, I still haven't managed that (linking statically didn't pan out, in my case), but at least I learnt something.
If I give cross-compilation to Windows a try, I'll try to update this.

C Shared Library : No Such File or Directory Upon Execution

first off, this is a programming assignment so you are aware.
Anyhow, what I am trying to do is include a shared library I wrote (a linked list from a previous project) in with my own shell I am writing. The issue I incur is that when I compile using my Makfile, the compile is successful. Then when I try to run my executable (let's say it's called prog), I get the following:
[terminal]# ./prog
./prog: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
The following is my file structure for reference:
include
|_
common.h
List.h
Node.h
lib
|_
libmylib.a
libmylib.so
libsrc
|_
Makefile // This makefile builds the library correctly and puts it in lib via 'make install'
List.c
List.h
Node.c
Node.h
common.h
Makefile
prog.c
Here is my main Makefile
CC=gcc
CFLAGS=-g -Wall -Llib
LIBS=-lreadline -lncurses -lmylib
PROGS=library prog
all: $(PROGS)
library:
cd libsrc; make install
prog: prog.o
$(CC) $(CFLAGS) -o $# $< $(LIBS)
clean:
cd libsrc; make installclean
/bin/rm -f *.o $(PROGS) a.out core *.log
Any help or advice is appreciated, thanks!
The runtime dynamic linker does not know where to find your shared library.
Two options:
Set the LD_LIBRARY_PATH environment variable to include the absolute path to your lib directory:
LD_LIBRARY_PATH=/path/to/lib
export LD_LIBRARY_PATH
Hard-code the absolute path to your lib directory in the executable image by passing -R/path/to/lib to the linker (e.g. in your makefile, CFLAGS=... -Llib -R/path/to/lib.
The first option is flexible, in the sense that the shared library can be installed anywhere and even moved to another location, and the executable won't break as long as the environment variable is updated accordingly. But it does require the user (or system administrator) must set up the environment correctly.
The second option does not allow the shared library to be moved from its predefined installation directory, but removes the dependencies on a correctly setup environment.
Note that you won't need to do either if you install your shared library in a standard system-specific location (e.g. /usr/lib or /usr/lib64 on Unix/Linux) as the runtime linker will search such locations automatically.

Compiling C program that uses a library

I've made a C program that uses libsndfile to extract some data from audio files.
What possibilities are there to make the program as portable as possible, preferably without requiring root access when installing?
Libsndfile is not available at the target machines, so i need to somehow package it with my program. Is there a way to statically link the library? I've also looked at some Autotools tutorials, but I'm not sure how to proceed.
I can compile without a hitch on my dev machine, where I installed the libraries using the package manager: apt-get install libsnfile1-dev
The makefile is very simple:
CFLAGS=-std=c99 -Wall -pedantic -g
CLIBS= -lsndfile -lm
BIN=audiodecode
CC=gcc
MAIN=main.o
FILES=
OBJS=$(FILES) $(MAIN)
.PHONY: all
all: clean $(OBJS)
$(CC) $(CFLAGS) -o $(BIN) $(OBJS) $(CLIBS)
.PHONY: clean
clean:
rm -f *.o $(BIN)
A lot of packages bundle their dependencies. Examples: rsync (contains a bundled libpopt), gnupg (contains a bundled libz). Other dependencies commonly bundled are gettext or glib.
For inspiration look at how these popular open source projects do it.
Put the content of http://www.mega-nerd.com/libsndfile/files/libsndfile-1.0.25.tar.gz into a subdir and add apropriate rules to build the the subdir first.
Untested sample code:
OBJS += libsndfile/libsndfile.a
libsndfile/libsndfile.a:
cd libsdndfile && ./configure --enable-static && $(MAKE)
For Bonus points add a configure script, that check if the system has already installed libsndfile and link to it dynamically.

OpenWrt SDK custom package 'make' fails because of missing libpthread.so.0

So I wrote a program to run on a Tp-link device running OpenWrt Attitude Adjustment 12.09.
I wrote the makefiles successfully in the /OpenWrt-SDK../package/myprogram/src/Makefile and it all ran smoothly when I did a 'make'.
Now I added threads in my program so I configured the Makefile like this:
# build myprogram executable when user executes "make"
LDFLAGS=-pthread
myprogram: myprogram.o
$(CC) $(LDFLAGS) myprogram.o -o myprogram
myprogram.o: myprogram.c
$(CC) $(CFLAGS) -c myprogram.c
# remove object files and executable when user executes "make clean"
clean:
rm *.o myprogram
and when I 'make' inside the package/myprogram/src folder it compiles successfully and runs just fine on my PC.
Now when I go to the root OpenWrt-SDK directory to 'make' I get a missing dependencies error:
Package myprogram is missing dependencies for the following libraries:
libpthread.so.0
So what do I need to do to include these dependencies?
I went to my OpenWrt-SDK root and tried:
./scripts/feeds search libpthread
And I got this result:
./scripts/feeds search libpthread
Search results in feed 'trunk':
libpthread POSIX thread library
Should I install that or is that not it? I do not know if I am doing something else wrong.
I will appreciate any help! Thanks.
Under package definition add
DEPENDS:=+libpthread

Cross compiling source from windows to linux

This is my make file
EXE = signsrch
CFLAGS += -s -O2
PREFIX = /usr/local
BINDIR = $(PREFIX)/bin
SRC = $(EXE).c
all:
$(CC) $(CFLAGS) -c disasm.c
$(CC) $(CFLAGS) -c asmserv.c
$(CC) $(SRC) $(CFLAGS) -o $(EXE) *.o
install:
install -m 755 -d $(BINDIR)
install -m 755 $(EXE) $(BINDIR)/$(EXE)
.PHONY:
install
I want to cross compile it for my ubuntu and I tried:
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
but I get unknown type name errors with a bunch of âDWORDâ
Help?
We also need to see some code, but....
Windows has its own types for basic things above the vanilla C ones, as does Linux. It sounds like DWORD as a type is not known in Linux (likely). You'll probably have to create a mytypes.h file that redefines Windows standards like DWORD into Linux speak when building for a Linux platform. Linux has types.h that defines things like int32_t which is the equivalent. See this thread for more about this.
I've assumed you have a working cross compiler set up and you're fighting just with the port. If you haven't, that's your first job. You could have a windows based compiler that targets Linux (the cygwin option, mentioned in another post) or go for a Linux based compiler and targetting windows (crosstool will help here). Though since you seem to be targetting arm, I'm expecting that that Ubuntu install isn't the place you wish to build! :-)
to cross compile you need a toolchain for the target platform, not just a Makefile. Check this tutorial and also Cygwin

Resources