3

I need to compile fat binary file to be able use it on another linux machine. But there are some libraries missing so as I understand I should compile it with some -shared options. But I don't understand how to configure a Makefile for that. Currently my makefile looks like this:

CC = g++
CC_FLAGS = -std=c++11 -O2 -static -Wall

EXEC = cpp_server
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES:.cpp=.o)
LIBS = -lpthread -lmicrohttpd -lz

$(EXEC): $(OBJECTS)
    $(CC) $(OBJECTS) -o $(EXEC) $(LIBS)

%.o: %.cpp
    $(CC) -c $(CC_FLAGS) $< -o $@

clean:
    rm -f $(EXEC) $(OBJECTS)
Gerard Rozsavolgyi
  • 4,834
  • 4
  • 32
  • 39
Nikita
  • 1,465
  • 3
  • 15
  • 17
  • BTW, you might find [libonion](http://coralbits.com/libonion/) (or [Wt](https://www.webtoolkit.eu/wt)....) easier to use than `-lmicrohttpd` if you want some HTTP server library – Basile Starynkevitch May 21 '17 at 14:23
  • Well it's already working, but I need to compile this library into my binary file to be able execute it on computer where that library is not installed – Nikita May 21 '17 at 14:26
  • Notice that [fat binary](https://en.wikipedia.org/wiki/Fat_binary) has a *specific* meaning, which is not the one you want. So just speak of a binary (or a statically linked binary). – Basile Starynkevitch May 21 '17 at 14:35
  • 1
    In general, you cannot do something with Make if you don't know how to do it *without* Make. You must figure out how to build the binary using the command line, before you worry about wrapping the technique in a makefile. – Beta May 22 '17 at 00:59

1 Answers1

4

You'll better take advantage of the many built-in rules of GNU make. Run once make -p to learn them. So you should use CXX instead of CC and replace CC_FLAGS with CXXFLAGS.

You may want to build a statically linked executable. Then you should pass -static into your linking command, using LINKFLAGS

So try with

## untested Makefile for GNU make
# variables known to make
CXX= g++
CXXFLAGS= -std=c++11 -O2 -Wall -Wextra
LINKFLAGS= -static
LIBS= -lpthread -lmicrohttpd -lz
# this project needs:
MYEXEC= cpp_server
MYSOURCES= $(wildcard *.cpp)
MYOBJECTS= $(SOURCES:.cpp=.o)
.PHONY: all clean

all: $(MYEXEC)
$(MYEXEC): $(MYOBJECTS)
   $(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@
clean:
   rm -f $(MYEXEC) $(MYOBJECTS)

AFAIK you don't need anything more in your Makefile (provided you use a GNU make, not e.g. a BSD one). Of course you need appropriate TAB characters in your Makefile (so you need to use some editor able to insert them).

You could want to statically link only -lmicrohttpd (and dynamically link the other libraries; however, you might want to also statically link the C++ standard library, which depends upon the compiler and could change when the compiler changes; linking also the C++ library statically is left as an exercise). You could do that with removing the LINKFLAGS line and using

LIBS= -Bstatic -lmicrohttpd -Bdynamic -lz -lpthread

BTW the -shared linker option is need to build from position-independent code object files a shared library (not to use one). See this and that.

You may want to use make --trace (or remake -x, using remake) to debug your Makefile

If you want to understand what actual files are linked, add -v -Wl,--verbose to LINKFLAGS perhaps by running make 'LINKFLAGS=-v -Wl,--verbose' on your terminal.

You might want to make clean before anything else.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547