gmdev
gmdev

Reputation: 3155

Linking LLVM IR Libraries

I am following along with the LLVM Kaleidoscope Tutorial (Ch. 3), and am encountering errors (undoubtedly from my Makefile) after attempting to link LLVM IR libraries. My Makefile and project structure:

CPP=clang++
CFLAGS=-g -Wall -std=c++14
LDFLAGS:=$(shell llvm-config --cxxflags --ldflags --system-libs --libs core)

EXEC=comp.out
SRCS:=$(shell find src -type f -name '*.cpp')
OBJS:=$(patsubst %.cpp,%.o,$(SRCS))

all: $(EXEC)

$(EXEC): $(OBJS)
    $(CPP) $(CFLAGS) -o $@ $^

src/%.o: src/%.cpp
    $(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $<

src/ast/%.o: src/ast/%.cpp
    $(CPP) $(CFLAGS) $(LDFLAGS) -o $@ $<

.PHONY: clean
clean:
    rm -f $(shell find src -type f -name '*.o')
    rm -f $(EXEC)
.
└── src
    ├── main.cpp
    ├── [.cpp files]
    │
    ├── ast
    │   ├── [.cpp files]
    │   │
    │   └── include
    │       └── [.h files]
    │  
    └── include
        └── [.h files]

When Making, I get the error:

clang++ -g -Wall -std=c++14 -I/usr/local/Cellar/llvm/12.0.1/include -std=c++14 -stdlib=libc++   -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -L/usr/local/Cellar/llvm/12.0.1/lib -Wl,-search_paths_first -Wl,-headerpad_max_install_names -lLLVM-12 src/IMRep.cpp -o src/IMRep.o
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang-12: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [Makefile:19: src/IMRep.o] Error 1

From the error above, main.cpp is never compiled before compilation errors out. It only gets to the src/IMRep.cpp file (not sure if that matters). If I add the -c flag to make it:

src/%.o: src/%.cpp
    $(CPP) $(CFLAGS) $(LDFLAGS) -c $< -o $@

src/ast/%.o: src/ast/%.cpp
    $(CPP) $(CFLAGS) $(LDFLAGS) -c $< -o $@

I am able to run the program successfully despite the plethora of warning messages saying the linker inputs/arguments are unused. These warnings are expected because -c only compiles and doesn't link.

And in main.cpp:

#include <iostream>

int main(int argc, char *argv[])
{
    return 0;
}

So this question doesn't get flagged as a dupe:

[1]: main.cpp is included in OBJS
[2]: Added -c flag and receive many warnings about unused linker arguments/input (because -c is for compilation, not linkage)
[3]: I only use $< where there is one dependency and $^ where there are multiple
[4]: Can't apply the answer to this question
[5]: All files in SRCS and OBJS are the correct files. I verified this by making a 'verbose' rule and printing those values and make verbose

Which leads me to believe that I am not linking in these libraries correctly.

Upvotes: 1

Views: 795

Answers (1)

MadScientist
MadScientist

Reputation: 100836

Your question is, in fact, a duplicate of the #2 answer there.

When you want to create an object file you MUST use the -c option. That's what the -c option means.

If you don't want "a plethora of warning messages saying the linker inputs/arguments are unused" then, you know, don't add the linker inputs and arguments when you generate object files! Those arguments are for linking, not compiling.

Your .o rules should be:

src/%.o: src/%.cpp
        $(CPP) $(CFLAGS) -c $< -o $@

src/ast/%.o: src/ast/%.cpp
        $(CPP) $(CFLAGS) -c $< -o $@

Just to point out you don't need both of the above pattern rules. If you want the object files to live in the same directory as the source files you can just write:

%.o: %.cpp
        $(CPP) $(CFLAGS) -c $< -o $@

And, if you switched to using the standard make variables instead of using non-standard ones:

# CPP is the C preprocessor, not C++
CXX = clang++
# CFLAGS is flags for the C compiler, not C++
CXXFLAGS := -g -Wall -std=c++14 $(shell llvm-config --cxxflags core)

LDFLAGS := $(shell llvm-config --ldflags --system-libs --libs core)

then you wouldn't need to define your own pattern rule at all because make has a built-in rule which knows how to compile a C++ source file into an object file.

Upvotes: 2

Related Questions