2008-11-13 29 views
19

Tôi đã tìm một đơn giản được khuyến nghị "tối thiểu" C++ makefile cho Linux, sẽ sử dụng g ++ để biên dịch và liên kết một tệp đơn và tệp h. Lý tưởng nhất là làm cho tập tin thậm chí sẽ không có tên tập tin vật lý trong nó và chỉ có một .cpp để .o chuyển đổi. Cách tốt nhất để tạo ra một makefile mà không cần lặn vào những nỗi kinh hoàng của autoconf là gì?tối thiểu C++ tạo tập tin cho linux

Các dir hiện chứa, ví dụ

t.cpp t.h

và tôi muốn có một makefile cho rằng được tạo ra. Tôi đã thử autoconf nhưng giả định của nó .h là gcc thay vì g ++. Vâng, mặc dù không phải là người mới bắt đầu, tôi đang học lại từ những năm trước để tiếp cận tốt nhất với thao tác dự án và vì thế tôi đang tìm kiếm các cách tự động để tạo và duy trì các makefiles cho các dự án nhỏ.

+0

Tạo nên điều tuyệt vời cho các dự án đơn giản (và để chơi cùng). Nhưng việc duy trì một dự án lớn trở nên khó thực hiện một cách chính xác (bạn có thể tránh né nó một cách dễ dàng nhưng đúng là khó). Sử dụng các công cụ 'như scons' để xây dựng file make của bạn –

+0

scons trông đẹp mắt. Chắc chắn dễ hơn Autoconf. – RichieHH

+1

OMake thật tuyệt vời và tiếp quản khi thực hiện giới hạn của nó. – bltxd

Trả lời

27

Nếu nó là một tập tin duy nhất, bạn có thể gõ

make t 

Và nó sẽ gọi

g++ t.cpp -o t 

này thậm chí không cần một Makefile trong thư mục, mặc dù nó sẽ bị lẫn lộn nếu bạn có t.cpp và tc và t.java, v.v.

Cũng là một Makefile thực tế:

SOURCES := t.cpp 
# Objs are all the sources, with .cpp replaced by .o 
OBJS := $(SOURCES:.cpp=.o) 

all: t 

# Compile the binary 't' by calling the compiler with cflags, lflags, and any libs (if defined) and the list of objects. 
t: $(OBJS) 
    $(CC) $(CFLAGS) -o t $(OBJS) $(LFLAGS) $(LIBS) 

# Get a .o from a .cpp by calling compiler with cflags and includes (if defined) 
.cpp.o: 
    $(CC) $(CFLAGS) $(INCLUDES) -c $< 
+1

điều này cũng không tạo bất kỳ phụ thuộc nào. –

+0

Makefile này gần như (nhưng không hoàn toàn) tương đương với "tất cả: t" và cho phép các quy tắc tích hợp tiếp quản ... –

+0

Nhưng tại sao bạn có quy tắc cụ thể cho t:? Nó đánh bại điểm của việc có một quy tắc cpp.o. – RichieHH

8

Bạn đã xem SCons chưa?

Đơn giản chỉ cần tạo một file SConstruct như sau:

Program("t.cpp") 

Sau đó gõ:

scons 

Xong!

+0

Mặc dù tôi thích nghịch với makefile (một ngôn ngữ của nó cho chính nó). Tôi nghĩ rằng đây là câu trả lời hay nhất, nhưng tôi nghĩ bạn cần phải mở rộng câu trả lời này một chút để giải thích tại sao sử dụng "SCons" tốt hơn là sử dụng Makefiles trực tiếp. Tôi bị thuyết phục nhưng không đủ ở đây để thuyết phục người khác. –

4

Giả sử không được cấu hình trước trên toàn hệ thống make cài đặt:

CXX = g++ 
CPPFLAGS =  # put pre-processor settings (-I, -D, etc) here 
CXXFLAGS = -Wall # put compiler settings here 
LDFLAGS =   # put linker settings here 

test: test.o 
    $(CXX) -o [email protected] $(CXXFLAGS) $(LDFLAGS) test.o 

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

test.cpp: test.h 
+0

Một lần nữa đây là một dòng cụ thể để kiểm tra. Tại sao? – RichieHH

+0

vì bạn luôn phải chỉ định * những gì * Makefile sẽ thực sự xây dựng. Với defs toàn cầu phù hợp, bạn có thể chỉ có thể nói "test:" trong tệp, nhưng tệp ở trên được đảm bảo hoạt động bất kể bất kỳ quy tắc hoặc macro toàn cục nào. – Alnitak

-1

Nếu vấn đề của bạn được vì autoconf nghĩ file .h là tập tin ac, hãy thử đổi tên nó để .hpp hoặc .h ++

16

Đây là một makefile generic từ mã của tôi snippets thư mục:

SOURCES=$(wildcard *.cpp) 
OBJECTS=$(SOURCES:.cpp=.o) 
DEPS=$(SOURCES:.cpp=.d) 
BINS=$(SOURCES:.cpp=) 

CFLAGS+=-MMD 
CXXFLAGS+=-MMD 

all: $(BINS) 

.PHONY: clean 

clean: 
    $(RM) $(OBJECTS) $(DEPS) $(BINS) 

-include $(DEPS) 

Chừng nào bạn có một nguồn cpp sản xuất một nhị phân, bạn không cần bất cứ điều gì nhiều hơn nữa.Tôi chỉ sử dụng nó với GNU, và thế hệ phụ thuộc sử dụng cú pháp gcc (cũng được hỗ trợ bởi icc). Nếu bạn đang sử dụng trình biên dịch SUN, bạn cần thay đổi "-MMD" thành "-xMMD". Ngoài ra, hãy đảm bảo rằng tab ở đầu dòng sau clean: không bị thay đổi thành khoảng trắng khi bạn dán mã này hoặc make sẽ cung cấp cho bạn lỗi phân tách bị thiếu.

0

SConstruct với tùy chọn gỡ lỗi:

env = Environment() 

if ARGUMENTS.get('debug', 0): 
    env.Append(CCFLAGS = ' -g') 

env.Program(source = "template.cpp") 
0

Florin có một điểm khởi đầu tốt. Tôi không thích gnu autoconf vì vậy tôi bắt đầu ở đó và lấy khái niệm xa hơn và gọi nó là MagicMakefile. Tôi có 3 phiên bản của nó từ đơn giản đến phức tạp hơn. Phiên bản mới nhất hiện có trên github: https://github.com/jdkoftinoff/magicmake

Về cơ bản, nó giả định bạn có bố cục chuẩn cho tệp nguồn của dự án và sử dụng hàm ký tự đại diện để tạo quy tắc makefile khi đang bay. phụ thuộc tập tin, biên dịch chéo, kiểm tra đơn vị, cài đặt và đóng gói.

[sửa] Tại thời điểm này, tôi sử dụng cmake cho tất cả các dự án của mình vì nó tạo tệp dự án hữu ích cho nhiều hệ thống xây dựng.

jeff koftinoff

+0

Rất tiếc! Xin lỗi vì các liên kết bị hỏng. Tôi chuyển nó đến github. https://github.com/jdkoftinoff/magicmake - đang được nói rằng tôi sử dụng CMake ngay bây giờ. – jdkoftinoff

1

Bạn đã nhìn OMake?

OMakeroot

open build/C 
DefineCommandVars() 
.SUBDIRS: . 

OMakefile

.DEFAULT: $(CXXProgram test, test) 

Sau đó trên Linux hoặc Windows, bạn chỉ cần gõ:

omake 

Như một phần thưởng, bạn sẽ tự động nhận được:

  • xây dựng song song với tùy chọn -j (giống như thực hiện).
  • MD5 tổng kiểm tra thay vì dấu thời gian (xây dựng trở nên linh hoạt đối với lỗi đồng bộ hóa thời gian).
  • Phụ thuộc tiêu đề C/C++ tự động và chính xác.
  • Phụ thuộc vào thư mục chính xác (điều gì đó mà đệ quy không cung cấp).
  • Tính di động (1 chuỗi xây dựng để loại trừ tất cả, miễn nhiễm với các vấn đề về kiểu đường dẫn).
  • Một ngôn ngữ lập trình thực (tốt hơn là tạo GNU).
+0

Nếu OMake có hỗ trợ tốt hơn cho các bản dựng ngoài nguồn và có thể tạo dự án Visual Studio, nó sẽ rất gần hoàn hảo. – JesperE

+0

Chúng tôi làm việc ngoài nguồn với OMake tại đây. Có một vài điều cần biết nhưng nếu không nó hoạt động (0.9.8.5). – bltxd

1

một GNU Makefile khá nhỏ, sử dụng quy tắc được xác định trước và tự động DEPS:

CC=c++ 
CXXFLAGS=-g -Wall -Wextra -MMD 
LDLIBS=-lm 
program: program.o sub.o 
clean: 
    $(RM) *.o *.d program 
-include $(wildcard *.d) 
0

Tôi đã săn bắn xung quanh cho những gì một Makefile tối thiểu có thể trông như khác hơn

some_stuff: 
    @echo "Hello World" 

tôi biết Tôi đến trễ bữa tiệc này, nhưng tôi nghĩ tôi cũng sẽ ném chiếc mũ của mình vào chiếc nhẫn. Sau đây là một dự án thư mục của tôi Makefile tôi đã sử dụng trong nhiều năm. Với một chút sửa đổi, quy mô sử dụng nhiều thư mục (ví dụ: src, obj, bin, tiêu đề, kiểm tra, v.v.).Giả sử tất cả các tiêu đề và tệp nguồn nằm trong thư mục hiện tại. Và, phải cung cấp cho dự án một tên được sử dụng cho tên nhị phân đầu ra.

NAME = my_project 

FILES = $(shell basename -a $$(ls *.cpp) | sed 's/\.cpp//g') 
SRC = $(patsubst %, %.cpp, $(FILES)) 
OBJ = $(patsubst %, %.o, $(FILES)) 
HDR = $(patsubst %, -include %.h, $(FILES)) 
CXX = g++ -Wall 

%.o : %.cpp 
     $(CXX) $(HDR) -c -o [email protected] $< 

build: $(OBJ) 
     $(CXX) -o $(NAME) $(OBJ) 

clean: 
     rm -vf $(NAME) $(OBJ) 
Các vấn đề liên quan