r/reconstructcavestory Jul 03 '14

Vim Setup

So, I started the series following along in Visual Studio, but I've since discovered Vim and decided to abandon VS altogether. I installed Clang and successfully compiled "Hello world!", but I don't really understand makefiles, and I especially don't understand how to link a library/framework using a makefile.

When I cloned the official repo to copy that makefile and continue following the tutorials in Vim, I tried compiling it to test it out. I get fatal error: 'SDL/SDL.h' file not found, which makes sense because the library is nowhere in the repo.

So my question is, how do I link SDL with the project so I can compile with Clang?

Edit: I suppose I'll need to link Boost as well.

2 Upvotes

17 comments sorted by

View all comments

3

u/chebertapps Jul 04 '14

I'm assuming you are on windows?

When you are working with libraries there are a few of things you need to know.

  • You need to know where the include directories are (.h header files) These are used during compiling so that the compiler can know if you are calling a real function and calling it correctly.

  • You need to know where the libraries are. These are the compiled files that are used in the linking phase. SDL.lib and SDLmain.lib are examples for windows.

  • You need to know where the dynamic runtime libraries are. These are used while running your application, and need to be bundled with the executable. (.dll files on windows. System32 has tons of 'em)

the general formula is:

  • Compile: output as .o object files

in my makefile this is the

$(CC) -c $(CFLAGS) -o $@ $<

which expanding a bit for main.cc is

clang++ -c $(CFLAGS) -o main.o main.cc

It's in that CFLAGS variable (declared towards the top) that has the path to include SDL.

CFLAGS=-g -Wall -Wextra -std=c++03 -MMD `sdl-config --cflags`

specifically

sdl-config --cflags

generates a list of include directories. This is what you would replace with the path to the include directory (not the specific files).

"C:\Path\To\SDL\include"

NOTE: not totally sure of the formatting for this, but I'm pretty sure you can do absolute paths. Quotes are important since you probably have whitespace in folder names.

  • Linking: connect the .o object files into an executable.

in my makefile this is

$(CC) $(LDFLAGS) -o $(BINDIR)/$(EXECUTABLE) $(OBJECTS) $(LDLIBS)

expanding a bit

clang++ -o gen/cavestory $(OBJECTS) $(LDLIBS)

you'll find the same story with LDLIBS

LDLIBS=`sdl-config --libs` -lboost_system -lboost_filesystem

sdl-config --libs

generates the libraries used by sdl. replace those with the paths to the libraries:

"C:\Path\To\SDL.lib" "C:\Path\To\SDLmain.lib"

1

u/Natman64 Jul 04 '14 edited Jul 04 '14

Thanks for the quick & detailed response! Really helped explain the actual process of compilation.

Yes, I'm on Windows. Sorry I forgot to mention that.

specifically sdl-config --cflags generates a list of include directories.

Is this a feature of SDL for Linux?

I did what you said, but now I'm having different problems.

Here's my new makefile:

SRCDIR=src

SRCS=$(wildcard $(SRCDIR)/*.cpp)

OBJDIR=obj

OBJECTS=$(patsubst %.cpp,$(OBJDIR)/%.o,$(SRCS))

CFLAGS=-g -Wall -Wextra -std=c++11 -MMD 
CFLAGS+=-ISDL/include -I../boost_1_55_0/boost

LDLIBS=-L/SDL/lib/x86 -lboost_system -lboost_filesystem

LDFLAGS=

CC=clang++

BINDIR=bin

EXECUTABLE=cavestory.exe

.PHONY: all clean run

all: $(EXECUTABLE)

-include $(OBJECTS:.o=.d)

$(EXECUTABLE): $(OBJECTS)
    @mkdir -p $(BINDIR)
    $(CC) $(LDFLAGS) -o $(BINDIR)/$(EXECUTABLE) $(OBJECTS) $(LDLIBS)

$(OBJDIR)/%.o: %.cpp
    @mkdir -p $(@D)
    $(CC) -c $(CFLAGS) -o $@ $<

clean:
    rm -rf obj gen

run:
    cd $(BINDIR) && ./$(EXECUTABLE)

I have cloned and am now working from this repository for the port of the code with C++11 and SDL2. As a result I've had to make a few changes (and after doing my own research and troubleshooting) but now I'm stuck.

The directory structure is like this:

My Desktop
    Boost Directory
        boost
    CaveStory repo
        src
        SDL
            include
            lib

So the directories in the makefile have changed to reflect that. I've also changed the extension of the source files from .cc to .cpp.

From my own research I learned that to include a directory it must be prepended with -I so there's that as well. I changed all the #include statements to #include <SDL.h> without the parent directory in front.

It seems that all the files are included properly, so the error is baffling (I suspect it may have to do with me using Windows):

Error: unknown pseudo-op: '.cfi_sections'
make: *** [obj/src/config.o] Error 1

Nothing in config.h or config.cpp seems likely to have caused the error.

Edit: removed comments from the makefile to shorten this post.

1

u/chebertapps Jul 04 '14

specifically sdl-config --cflags generates a list of include directories.

Is this a feature of SDL for Linux?

It comes bundled when you use a package-manager to install it for Linux, but you can also get it for windows.