0

Okay, so I've compiled a simple logger I wrote into a library so I can include it with other projects. But when I try to include the header for that logger, it fails compilation.

Here is my Makefile linking the library:

CC= clang++
PROG= ./bin/tetris
OBJS= ./src/main.o ./src/Tetris.o ./src/states/BaseState.o ./src/states/MenuState.o \
    ./src/states/GameState.o
LIBS= allegro-5.0 allegro_dialog-5.0 allegro_font-5.0 allegro_ttf-5.0 allegro_color-5.0
CXXFLAGS= -g -Wall -std=c++11
LDFLAGS= $(shell pkg-config --static --libs ${LIBS}) -I./src/util -L./src/util/ -lsimplog

all: $(PROG)

$(PROG): $(OBJS)
    mkdir -p ./bin/
    $(CC) -o $(PROG) $(CXXFLAGS) $(OBJS) $(LDFLAGS)
    rm -f $(OBJS)

clean:
    rm -f $(PROG) $(TEST_PROG) $(OBJS)

The library is libsimplog.a and is located in the src directory of this project. I'm compiling it in a separate project folder, then copying here. simplog.h/simplog.c only exist in the project folder where I'm initially compiling this library. From what I understand, -L ./src/ -lsimplog in my compile flags should be linking this library. However, my #include "simplog.h" is still failing upon compilation:

fatal error: simplog.h: No such file or directory

I'm compiling the library in its own project folder, separate from this project. simplog.h/simplog.c exist in that project, not this one. The makefile for the other project that compiles this library is as follows:

CC = clang
CFLAGS = -Wall -c
LIB = libsimplog.a
SOURCE = simplog.c
OBJ = simplog.o

all:
    $(CC) $(CFLAGS) $(SOURCE)
    ar -cvq $(LIB) $(OBJ)

clean:
    rm -f $(LIB)
PseudoPsyche
  • 4,332
  • 5
  • 37
  • 58

2 Answers2

2

"-L" specifies the library path for the linker.

You need to tell the pre-processor that there is another include directory with -I./src/.

CXXFLAGS= -g -Wall -std=c++11 -I./src/ -L./src/ -lsimplog $(shell pkg-config --cflags ${LIBS})
kfsone
  • 23,617
  • 2
  • 42
  • 74
  • Tried this, but it still fails compilation with the same error. – PseudoPsyche Oct 29 '13 at 06:45
  • Ok, so relative to the tetris Makefile, simplog.h is in "./src"? – kfsone Oct 29 '13 at 06:48
  • Infact, your question makes it sound like there are two Makefiles. – kfsone Oct 29 '13 at 06:50
  • Well, the libsimplog.a is in ./src. simplog.h exists in its own project directory where I'm compiling libsimplog.a and copying it to this project. Updated the OP to make that more clear. – PseudoPsyche Oct 29 '13 at 06:51
  • The library / linking has nothing to do with including a header file - the two are utterly independent. Forget about the .a file for now. From the directory where you have the tetris Makefile, where you type "make" and it fails, can you do "ls ./src/simplog.h"? Or is it somewhere else? The include operation is going to be relative to that directory, the location of the library has no bearing on it. If you added -I./src/ to the compiler arguments, then the **compiler** is trying to access the file ${TETRIS_MAKEFILE_DIR}/src/simplog.h. – kfsone Oct 29 '13 at 06:54
  • No, simplog.h exists in a totally different project/directory not relative to this one. I thought I could merely compile the library from the sources, and include the library in another project without the need to link directly to simplog.h? – PseudoPsyche Oct 29 '13 at 06:58
  • Unfortunately not - header files are used by the compiler/pre-processor, long before object files / libraries are accessed. See [this answer to a different question](http://stackoverflow.com/questions/18579340/header-guards-do-not-seem-to-work/18580233#18580233) for an explanation of the compilation pipeline. – kfsone Oct 29 '13 at 07:00
  • Okay, so then what exactly would be the point of compiling my simplog.h into a library as opposed to just putting the header and source files in each project I want to use them in, and compile them into the project? – PseudoPsyche Oct 29 '13 at 07:05
  • Usually the ".h" file is a short "header" which provides prototypes of the functions available in the library, provides constant values that a library user might need, etc. The rest of the code is in the .cpp files you compile together into the library. This way you only have to compile the bulk of the library's code once so you don't have multiple copies of the functions scattered across your executables. – kfsone Oct 29 '13 at 07:10
  • I created a quick mock of how you might do it here: https://bitbucket.org/kfsone/two-projects. `cd proj1; make; cd ..; cd proj2 ; make ; ./proj2.exe` – kfsone Oct 29 '13 at 07:27
  • Okay, that makes sense. I placed my simplog.h in that directory and tried linking against it, but now I have another compilation error. `clang: error: linker command failed with exit code 1` And each reference to a function in that header in my code comes up with an `undefined reference to` error. What's up now? – PseudoPsyche Oct 29 '13 at 08:17
  • You're probably running into a dependency-ordering issue. You have linker settings in your CXXFLAGS (`CXXFLAGS= -g -Wall -std=c++11 -L ./src/ -lsimplog $(shell pkg-config --cflags ${LIBS}`). Move the `-L`, `-l` and `${LIBS}` into LDFLAGS and on your command line, `$(CC) -o $(PROG) $(LDFLAGS) $(CFLAGS) $(OBJS)` change the order to `$(CC) -o $(PROG) $(CXXFLAGS) $(OBJS) $(LDFLAGS)` (note: you have 'CFLAGS instead of CXXFLAGS' – kfsone Oct 30 '13 at 02:07
  • Still no dice. Updated my makefile in the OP to reflect my changes. – PseudoPsyche Oct 30 '13 at 07:52
  • Can you update it with the current error(s) you are getting? I'll take a look this evening. – kfsone Oct 30 '13 at 16:51
0

Did you try including I Flags for including header files ? eg :

    -I/usr/include/

From the man page of g++

   -I dir           Add the directory dir to the list of directories to 
be searched for header files.  Directories named by -I are searched  
before the standard system include directories. 
If the directory dir is a standard system include directory, 
the option is ignored to ensure that the default search order for
system directories and the special treatment of system headers are no   
defeated .If dir begins with "=", then the "=" will be replaced by the
sysroot prefix; see --sysroot and -isysroot.
Knight71
  • 2,927
  • 5
  • 37
  • 63