0

I'm fairly new to C development, and especially to makefiles, so please bear with me. I have a functional C application that builds nicely (based on this project) with it's Makefile, but I want to be able to have it respond to http requests. Thus, Mongoose.

Functionally, the Makefile calls:

g++ -pthread -I./ -I../../dmx/include -I/usr/include/glib-2.0 -I/usr/include/gtk-3.0 -I/usr/lib/arm-linux-gnueabihf/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/atk-1.0  -g -c DMXController.c -o DMXController.o -Wno-deprecated-declarations
g++ -o DMXController.bin DMXController.o -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo -lgobject-2.0 -lglib-2.0 -lusb -lm -L../../dmx/lib -ldmx -L. -ldl -lpthread  -Wl,--no-whole-archive -rdynamic
rm DMXController.o 

This works fine without any of the Mongoose function calls, but breaks as soon as I add one in. I copied the mongoose.c and mongoose.h files into the immediate parent directory and added #include "mongoose.h", but I'm not really sure how to add the dependencies to the Makefile.

The Mongoose documentation says to build using the form cc app.c mongoose.c -pthread -o app, but how do I combine that with what I already have?

If I run my existing Makefile on my application code with mongoose function calls, the compile error is: undefined reference to 'mg_create_server' (or any other mongoose function that I may use).

The relevant-seeming parts of the application code follow.

#include <gtk/gtk.h>                        // GTK+3.0 graphics library
#include <dmx.h>                            // DMX interface library
#include "mongoose.h"                       // Mongoose Web server

// ...

int main( int argc, char *argv[] )
{
    // initialize mg
    struct mg_server *server = mg_create_server(NULL, NULL); // undefined reference
    mg_set_option(server, "document_root", ".");      // undefined reference
    mg_set_option(server, "listening_port", "8080");  // undefined reference

    // initialize DMX
    int error;
    error = initDMX(); // local function that works fine
    if ( error < 0 ) return ( error );

    // do stuff 
    for (;;) {
            mg_poll_server(server, 1000);   // undefined reference
    }

    // kill mg
    mg_destroy_server(&server); // undefined reference

    // kill DMX
    exitDMX(); // local function that works fine

    // die quietly
    return ( 0 );
}

Contents of the Makefile: (currently... I've been trying various things)

CC=g++
CFLAGS+=  -pthread

LDFLAGS+= -lgtk-3 -lgdk-3 -latk-1.0 -lgio-2.0 -lpangocairo-1.0 \
      -lgdk_pixbuf-2.0 -lcairo-gobject -lpango-1.0 -lcairo \
      -lgobject-2.0 -lglib-2.0 -lusb -lm \
      -L../../dmx/lib -ldmx -L.# -lmongoose -ldl -lpthread

INCLUDES+= -I. -I../../dmx/include \
       -I/usr/include/glib-2.0 -I/usr/include/gtk-3.0 \
       -I/usr/lib/arm-linux-gnueabihf/glib-2.0/include \
       -I/usr/include/pango-1.0 -I/usr/include/cairo \
       -I/usr/include/pixman-1 -I/usr/include/gdk-pixbuf-2.0 \
       -I/usr/include/atk-1.0

OBJS=DMXController.o
BIN=DMXController.bin

all: $(BIN)

%.o: %.c
    @rm -f $@
    $(CC) $(CFLAGS) $(INCLUDES) -g -c $< -o $@ -Wno-deprecated-declarations

%.bin: $(OBJS)
    $(CC) -o $@ $(OBJS) $(LDFLAGS) -Wl,--no-whole-archive -rdynamic
    @cp $@ ../bin

clean:
    for i in $(OBJS); do (if test -e "$$i"; then ( rm $$i ); fi ); done
    @rm -f $(BIN)

Thanks for the help!

James K.
  • 364
  • 1
  • 15
  • this looks a little odd: -L. -ldl -lpthread which is saying the next libraries (libdl.so and libpthread.so) will be found in the current directory. – user3629249 Dec 03 '14 at 06:06
  • this looks a little odd: -I./ -I../../dmx/include Normally the local directory is listed as -I. and you cannot be sure that the dmx directory will always be 2 directories above the current directory. so use an absolute path. – user3629249 Dec 03 '14 at 06:12
  • 1
    two key questions: 1) where is the mongoose.h file located? 2) where is the associated library(s) located? the answer to those questions will tell you what needs changing in your makefile – user3629249 Dec 03 '14 at 06:14
  • note: -I and -L must always end with a directory name. (. and ..) are relative directory names so -I. works well for the current directory – user3629249 Dec 03 '14 at 06:16
  • for -l (lower case 'L') if the library is in a standard location, then no preceding '-L' parameter is needed, otherwise a preceding '-L' parameter that contains the path to the library must be used. – user3629249 Dec 03 '14 at 06:17
  • for '-I' (capital I) the included file path is required (but never the actual file name). the -I is not needed for header files in the standard locations. (the current directory is considered a standard location, but it is best to actually always have a '-I.' parameter if there is other '-I' parameters (generally the '-I.' parameter should be before any other '-I' parameters). – user3629249 Dec 03 '14 at 06:19
  • The issue, though, is that it works with fine for all of the libraries *except* mongoose. If I add -lmongoose, it can't find -lmongoose. I'm presuming that's because mongoose itself isn't getting built. How do I build it, included (or linked or whatever the right term is) with the existing code. mongoose.h and mongoose.c are located in the same directory as the application c. What is "the associated library"? The mongoose documentation said I only needed the mongoose.c and mongoose.h files. – James K. Dec 03 '14 at 14:14
  • @user3629249 Having a `-L` option does not mean following `-l` switches will be searched with the specified directory, it simply adds a search path to the collection. – Chnossos Dec 03 '14 at 17:50
  • @JamesK. We need to know the content of your Makefile to properly help you. – Chnossos Dec 03 '14 at 17:51
  • @Chnossos: Makefile posted. – James K. Dec 03 '14 at 19:16

1 Answers1

0

A simple solution is to add to your Makefile :

LDFLAGS+=../mongoose.c

This will build mongoose and link it with your application

mpromonet
  • 11,326
  • 43
  • 62
  • 91
  • Cool. That works. But for the sake of the learning opportunity, why does it work? What does this flag actually do? I can't seem to find a useful reference on what the basic flags (-c -L -l etc) mean. – James K. Dec 07 '14 at 03:39
  • -c build an object file, -l link a library, -L give a path to search library. If you would like to use mongoose with -lmongoose, you should build this library, for instance using ar. Have a look at http://www.rapidtables.com/code/linux/gcc.htm is is more simple than https://gcc.gnu.org/onlinedocs/gcc/Invoking-GCC.html#Invoking-GCC – mpromonet Dec 07 '14 at 08:41