簡體   English   中英

Makefile-通配符和配方構建

[英]Makefile - wildcard and recipe build

我有以下makefile

# See gcc/clang manual to understand all flags
CFLAGS += -std=c99 # Define which version of the C standard to use
CFLAGS += -Wall # Enable the 'all' set of warnings
CFLAGS += -Werror # Treat all warnings as error
CFLAGS += -Wshadow # Warn when shadowing variables
CFLAGS += -Wextra # Enable additional warnings
CFLAGS += -O2 -D_FORTIFY_SOURCE=2 # Add canary code, i.e. detect buffer overflows
CFLAGS += -fstack-protector-all # Add canary code to detect stack smashing

# We have no libraries to link against except libc, but we want to keep
# the symbols for debugging
LDFLAGS = -rdynamic

# external libs
# par défaut les chemins classiques

LDFLAGS += -I$(HOME)/local/include
LDFLAGS += -L$(HOME)/local/lib

# Default compiler
CC=gcc

# folders
SOURCE_FOLDER=src
TESTS_FOLDER=tests
PAQUET_FOLDER=paquet
SEND_RECEIVE_DATA_FOLDER=sendAndReceiveData
CLIENT_FOLDER=client
SERVER_FOLDER=server

# folder of sources
PAQUET_FULL_PATH=$(SOURCE_FOLDER)/$(PAQUET_FOLDER)
SEND_RECEIVE_DATA_FULL_PATH=$(SOURCE_FOLDER)/$(SEND_RECEIVE_DATA_FOLDER)
CLIENT_FULL_PATH=$(SOURCE_FOLDER)/$(CLIENT_FOLDER)
SERVER_FULL_PATH=$(SOURCE_FOLDER)/$(SERVER_FOLDER)

# sources files
# On prend tout
PACKET_SOURCES = $(wildcard $(PAQUET_FULL_PATH)/*.c)
SEND_RECEIVE_DATA_SOURCES = $(wildcard $(SEND_RECEIVE_DATA_FULL_PATH)/*.c)
CLIENT_SOURCES = $(wildcard $(CLIENT_FULL_PATH)/*.c)
SERVER_SOURCES = $(wildcard $(SERVER_FULL_PATH)/*.c)

# objects

PACKET_OBJECTS=$(PACKET_SOURCES:.c=.o)
SEND_RECEIVE_DATA_OBJECTS=$(SEND_RECEIVE_DATA_SOURCES:.c=.o)
CLIENT_OBJECTS=$(CLIENT_SOURCES:.c=.o)
SERVER_OBJECTS=$(SERVER_SOURCES:.c=.o)

# another things

# Default target
all: clean server client

client: $(CLIENT_OBJECTS) $(PACKET_OBJECTS); \
        $(CC) $(CFLAGS) $(CLIENT_OBJECTS) $(LDFLAGS);

server: $(SERVER_OBJECTS) $(PACKET_OBJECTS); \
        $(CC) $(CFLAGS) $(SERVER_OBJECTS) $(LDFLAGS);

$(PACKET_OBJECTS): $(PACKET_OBJECTS); \
        $(CC) $(CFLAGS) -lz $(PACKET_OBJECT) $(LDFLAGS);

tests: $(PACKET_OBJECTS) $(TESTS_OBJECTS); \
        $(CC) $(CFLAGS) -lcunit $(LDFLAGS);

.PHONY: clean

clean:
    @rm -f *.o

我收到此消息:

make:循環src / paquet / packet_implem.o <-src / paquet / packet_implem.o依賴項已刪除。 \\ gcc -std = c99 -Wall -Werror -Wshadow -Wextra -O2 -D_FORTIFY_SOURCE = 2 -fstack-protector-all -lz -rdynamic -I / home / jy95 / local / include -L / home / jy95 / local / lib ; /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:在函數_start': (.text+0x20): undefined reference to main的_start': (.text+0x20): undefined reference to 'collect2:錯誤:ld返回1退出狀態Makefile:71:目標'src / paquet / packet_implem.o'的配方失敗:*** [src / paquet / packet_implem.o]錯誤1

我想要的是 :

1)建立依存關系(PACKET_SOURCES)和(SEND_RECEIVE_DATA_SOURCES)
2)使用步驟1中的依賴關系構建客戶端和服務器
3)可執行文件“客戶端”將位於文件夾的根目錄。

我該如何糾正錯誤?

使用-c生成對象而不嘗試創建可執行文件,這樣您就不需要main

$(PACKET_OBJECTS): $(PACKET_OBJECTS); \
        $(CC) -c $(CFLAGS) -lz $(PACKET_OBJECT) $(LDFLAGS);

我認為您可能還需要SERVER_OBJECTS這樣的規則

.c.o:
        $(CC) -c $(CFLAGS) -lz $< -o $@

此規則中出現問題:

$(PACKET_OBJECTS): $(PACKET_OBJECTS); \
        $(CC) $(CFLAGS) -lz $(PACKET_OBJECT) $(LDFLAGS);

這表示,在擴大每個目標$(PACKET_OBJECTS)依賴於每一個目標的擴展$(PACKET_OBJECTS) 這給了很多依賴周期,特別是它給了目標文件一個元素周期,具體取決於它們自己。

實際上,此規則在其他幾個方面也存在問題:

  • 實際上,配方不會創建規則的任何指定目標
  • 相反,它嘗試將目標文件(請參閱下文) 鏈接到一個可執行文件中,為結果分配默認名稱(也許是a.out )。
  • 配方引用未定義的變量$(PACKET_OBJECT) 我想這可能是$(PACKET_OBJECTS)的拼寫錯誤。 相反,如果您的意思是$(PACKET_OBJECTS)指定的當前目標,則將其拼寫為$@
  • 對象文件不僅不必然彼此具有先決條件,而且彼此之間也不具有先決條件。 每個對象的依存關系應為其對應的來源。
  • 如果確實要使用此規則來構建目標文件,則該配方不需要指定要鏈接的庫(例如-lz ),並且可能不應該這樣做。

很有可能,您可以完全刪除該規則,從而變得更好。 您可能需要將-lz添加到您的LDFLAGS 否則,它將丟失。

另外,

  • 您可能想移動-I$(HOME)/local/include選項:它不屬於LDFLAGS,因此在此不起作用。 如果需要,則將其放到CPPFLAGS ,或者放到CFLAGS甚至是INCLUDES

  • 構建可執行目標的各種規則應提供指定要構建目標名稱的選項。 您可以將其拼寫為“ -o $@ ”,

  • clean目標作為all的前提是不尋常的。 如果運行make而不指定目標,它將始終從頭開始重建所有內容。 大多數人只喜歡按需這樣做。

  • 您的all目標不會構建名為“ all”的目標,因此也應將其聲明為.PHONY

很可能還有更多,但我會留給您整理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM