2012-01-25 18 views
7

Tôi đang cố gắng viết hàm make để chạm/tạo tệp trống và/hoặc đặt quyền, người dùng và nhóm, nếu có thể, hoặc cảnh báo nếu không. Tuy nhiên, mọi kiểm tra có điều kiện trong hàm của tôi dường như được đánh giá là đúng.

Các yếu tố cần thiết của Makefile của tôi là

INSTALL_USER := fileUser 
INSTALL_GROUP := fileGroup 

.PHONY: test 
test: 
    $(call touchFile,~/test.ini) 

define touchFile 
$(eval fileName := $(strip $(1))) 
-touch $(fileName) 
-chmod -c 664 $(fileName) 

$(info filename info $(fileName)) 
$(info $(shell stat -c "%a %U:%G" $(fileName))) 

$(if ifeq "foo" "bar", @echo match is broken, @echo match works) 
$(if ifneq "foo" "bar", @echo match works, @echo match is broken) 

$(if ifneq ($(shell stat -c %a $(fileName)),664), $(warning Error - $(fileName) does not have expected permissions of 664)) 
-chgrp -c $(INSTALL_GROUP) $(fileName) 
$(if ifneq ($(shell stat -c %G $(fileName)),$(INSTALL_GROUP)), $(warning Error - $(fileName) does not belong to $(INSTALL_GROUP) group)) 
-chown -c $(INSTALL_USER) $(fileName) 
$(if ifneq ($(shell stat -c %U $(fileName)),$(INSTALL_USER)), $(warning Error - $(fileName) does not belong to $(INSTALL_USER) user)) 
endef 

Chạy make test đầu ra

filename info ~/test.ini 
664 myUserName:myGroup 
Makefile:7: Error - ~/test.ini does not have expected permissions of 664 
Makefile:7: Error - ~/test.ini does not belong to common group 
Makefile:7: Error - ~/test.ini does not belong to netserve user 
touch ~/test.ini 
chmod -c 664 ~/test.ini 
match is broken 
match works 
chgrp -c fileGroup ~/test.ini 
changed group of `/home/myUserName/test.ini' to fileGroup 
chown -c fileUser ~/test.ini 
chown: changing ownership of `/home/myUserName/test.ini': Operation not permitted 
make: [test] Error 1 (ignored) 

Tôi đã xem/thử như sau:

  • $ (nếu ...) được được đánh giá tại "compile-time", trước khi hàm được gọi với tham số. Tuy nhiên, mã số cứng ifeq "foo" "bar" cũng cho kết quả không hợp lệ. Ngoài ra, $(info ...) đánh giá chính xác $(fileName) tại "thời gian biên dịch".
  • documentation không thực sự đưa ra ví dụ, vì vậy ngoài $(if ifeq...), tôi cũng đã thử $(ifeq ...), dường như bị bỏ qua.
  • "Không hoạt động" if (ví dụ: ifeq không có $(if...)) bên trong một hàm cung cấp /bin/sh: ifeq: command not found.

Ai đó có thể giúp xác định lý do tại sao điều kiện của tôi không hoạt động như tôi mong đợi (hoặc tại sao tôi đang mong đợi điều sai)?

Lưu ý: Tôi biết vẫn còn lỗi để được giải quyết nếu tệp không tồn tại, nhưng điều đó không đáng kể so với rào cản này.

+1

Trang web GNU, mặc dù nó trông đẹp, rất gọn gàng như hầu như vô nghĩa, phải không. Họ sẽ cho bạn biết một chức năng tồn tại, và sau đó không cung cấp cho bạn bất kỳ ví dụ về cách sử dụng nó, để quấy rối bạn với nó. – Xennex81

Trả lời

31

$(if ...) conditional function đánh giá là true khi đối số đầu tiên được chuyển đến nó không trống. Trong trường hợp của bạn, điều kiện là văn bản theo nghĩa đen: ifeq "foo" "bar", nghĩa là, không trống.

ifeq/ifneq conditionals nằm trong chỉ thị thực tế chứ không phải chức năng. Chúng không thể được sử dụng bên trong định nghĩa biến và trong các hàm.

Trở lại với ví dụ của bạn, để chuỗi thử nghiệm cho sự bình đẳng trong các chức năng sử dụng điều kiện như filter and findstring:

$(if $(filter foo,bar),@echo match is broken,@echo match works) 
$(if $(filter-out foo,bar),@echo match works,@echo match is broken) 

BTW này cũng có thể được biến thành một hình thức inline để có thể đọc tốt hơn:

@echo match $(if $(filter foo,bar),is broken,works) 
@echo match $(if $(filter-out foo,bar),works,is broken) 
+0

giải thích tuyệt vời – anoop

+0

@anoop cảm ơn bạn! –

1

Dường như bạn hiểu nhầm cách hoạt động của $(if. Từ làm cho thông tin tài liệu:

$ (nếu ĐIỀU KIỆN, THEN-PART [, ELSE-PART]) ' Các `nếu' chức năng cung cấp hỗ trợ cho việc mở rộng điều kiện trong một bối cảnh chức năng

Đầu tiên đối số, CONDITION, trước tiên có tất cả trước và khoảng trắng theo sau bị tước, sau đó được mở rộng. Nếu nó mở rộng đến bất kỳ chuỗi không trống nào, thì điều kiện được coi là đúng. Nếu nó mở rộng thành một chuỗi rỗng, điều kiện được coi là là sai.

Trong tất cả các ví dụ của bạn, tình trạng của bạn là một cái gì đó giống như ifeq SOMETHING OTHERTHING - đó là một chuỗi không rỗng (từ ifeq không phụ thuộc vào những gì mà những thứ khác là), và do đó được coi là đúng.

4

Tôi gặp sự cố này và tôi thấy bạn có thể sử dụng kết quả của hàm "bộ lọc" trong phần "điều kiện" của hàm "if". Dưới đây là một ví dụ hữu ích cho việc mở một pdf hoặc trong Linux (với "tỏ ra"), hoặc trong OSX với "mở")

uname  :=$(shell uname -s) 
is_darwin :=$(filter Darwin,$(uname)) 
viewpdf :=$(if $(is_darwin), open, evince) 
+0

Cảm ơn! Tôi muốn có một ví dụ đơn giản nhất cho công cụ tạo của riêng tôi. – yoshi

0

nếu bạn muốn kiểm tra xem phiên bản hệ điều hành của bạn là linux hay khác và nếu nó là Linux sau đó bạn muốn in một số thông điệp sau đó u có thể làm theo các bước sau:

ifneq ($(TARGETOS), Linux) 
    target: server 
    @echo 
    @echo $(MSG) $(TARGETOS) 
else 
target: server 
    @echo $(MSG) $(TARGET) 
endif 

trước khi tôi thử với ifeq nhưng nó chỉ in phần khác. Hệ điều hành của tôi là Linux, ubuntu.

Nếu có ai tìm thấy câu trả lời này nên được sửa đổi, để họ có thể đưa ra câu trả lời tốt hơn cho điều này.

Các vấn đề liên quan