简体   繁体   中英

GCC linking a static library

I have seen questions like these on SO but everyone has different answers and directory structures that aren't working for me.

My makefile:

CC = g++
DEBUG = -g -std=c++11
TARGET = main
OBJECT_FILES = BingResultSet.o main.o
INC_PATH = -I HTTPClientLib/include
LIB_PATH = -L HTTPClientLib/lib/

start: clean BingResultSet.o main.o
    $(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)
    rm -f *.o

BingResultSet.o: BingResultSet.cpp BingResultSet.h
    $(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) -c BingResultSet.cpp

main.o: main.cpp
    $(CC) $(DEBUG) $(INC_PATH) $(LIB_PATH) -c main.cpp

clean:
    rm -f $(OBJECT_FILES) $(TARGET)

My file structure:

/Desktop/DataMiner/.cpp, .h, and makefile
/Desktop/DataMiner/HTTPClientLib/include/HTTPClient.h
/Desktop/DataMiner/HTTPClientLib/lib/HTTPClient.a

What's the correct way to link my static lib in my makefile?

Here's my $0.02:

  1. there was no static library involved. Assuming you meant the .o files
  2. you mix dependencies and build rules, instead, avoid repeating build rules:

     $(TARGET): $(OBJECT_FILES) $(CXX) $(DEBUG) $(INC_PATH) $^ -o $@ $(LIB_PATH) %.o: %.cpp $(CXX) $(DEBUG) $(INC_PATH) -c $< -o $@ 
  3. You used CC for a C++ compiler. That's strange. Use CXX

  4. You used LDFLAGS when you were just compiling
  5. You hardcoded the source and destination paths. Instead use the automatic variables ( $^ , $< for source; $@ for destination)

  6. You tried to hardcode header dependencies. That's error-prone and messes up source specification (you don't want $^ to list .h files in your command line...). Instead, use gcc -MM ¹ to generate the dependencies for you!

    Next, do a conditional include of those dependencies:

     .depends: $(CXX) -MM $(CXXFLAGS) -c *.cpp > $@ -include .depends 
  7. It's usually handy to keep the .o files so you can speed up builds. Of course, this was not a good plan until you generated the header dependencies automatically. If you insist, you can comment the .PRECIOUS target. Intermediate targets are automatically deleted by GNU Make

Here's the integrated offering I ended up with:

CXX = g++
TARGET = main
OBJECT_FILES = BingResultSet.o main.o
INC_PATH = -I HTTPClientLib/include
LIB_PATH = -L HTTPClientLib/lib/

CPPFLAGS = -g -std=c++11
CPPFLAGS+= $(INC_PATH)

# standard derived flags:
CXXFLAGS+=$(CPPFLAGS)
LDFLAGS+=$(LIB_PATH)

start: .depends $(TARGET)

$(TARGET): $(OBJECT_FILES)
    $(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)

%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

clean:
    rm -f .depends $(OBJECT_FILES) $(TARGET)

# to keep the .o files:
.PRECIOUS: $(OBJECT_FILES)

.depends:
    $(CXX) -MM $(CXXFLAGS) -c *.cpp > $@

-include .depends

On a very simple sample set of files you get:

$ make clean
rm -f .depends BingResultSet.o main.o main
$ make 
g++ -MM -g -std=c++11 -I HTTPClientLib/include -c *.cpp > .depends
g++  -I HTTPClientLib/include -c BingResultSet.cpp -o BingResultSet.o
g++  -I HTTPClientLib/include -c main.cpp -o main.o
g++  -I HTTPClientLib/include BingResultSet.o main.o -o main -L HTTPClientLib/lib/
$ cat .depends 
BingResultSet.o: BingResultSet.cpp BingResultSet.h
main.o: main.cpp BingResultSet.h
test.o: test.cpp

¹ (or similar, see man-page)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM