LINUX.ORG.RU

Помогите написать Makefile

 , , , ,


0

1

Имею код на Vala.
hello.vala

void main() {
    var w = new World();

    stdout.printf(w.text() + "\n");
}
world.vala
class World {
    public string text() {
        return "hello world";
    }
}
Компилировать его нужно следующими командами:
valac -C hello.vala world.vala
gcc -c -o world.o world.c `pkg-config --cflags --libs glib-2.0 gobject-2.0`
gcc -c -o hello.o hello.c `pkg-config --cflags --libs glib-2.0 gobject-2.0`
gcc -o helloworld hello.o world.o `pkg-config --cflags --libs glib-2.0 gobject-2.0`
Не спрашивайте, почему не просто valac hello.vala world.vala -o helloworld. Помогите написать Makefile, с целями %.c и %.o. Я уже не первый час мучаюсь.

★★★★★

что именно не работает? (я не писал сборку vala-исходников в makefiles, но писал через автотулсы. думаю, в makefile должно быть намного проще, интересно что за проблемы вылезли)

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от waker

Сейчас у меня такой мейкфайл:

CGLAGS=$(shell pkg-config --cflags --libs xmlsec1-nss)

all: helloworld

%.c: %.vala
	valac -C $^

%.o: %.c
	gcc -c -o $^ $@ 

helloworld: %.o
	gcc -o $@ $^ $(CFLAGS)

clean:
	rm *.c *.o helloworld
С ним получаю: make: *** Нет правила для сборки цели «%.o», требуемой для «helloworld». Останов.

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

разве %.c не будет матчить *.c? может тебе надо %.vala?


...

%.vala:
    valac -C $^

%.o: %.vala:
    gcc -c -o $^ $@

...

upd: ах да, оно же компилит в .c

думаю, как тут быть.. наверняка должен быть простой способ.

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от waker

думаю, как тут быть.. наверняка должен быть простой способ.

Тоже так думаю, только с мейкфайлами у меня плохо.

CYB3R ★★★★★
() автор топика

Пример:

MODE :=debug
LANGUAGE :=c

SOURCE_TOP_DIR  :=.
# source
SOURCE_SUB_DIRS :=
#shared math gfx



BUILD_TOP_DIR :=bin/$(MODE)

SOURCE_EXT :=c
ifeq ($(LANGUAGE),cpp)
SOURCE_EXT :=cpp
endif

OBJECT_EXT :=o

COMPILER   :=$(CC)
ifeq ($(LANGUAGE),cpp)
COMPILER :=$(CXX)
endif

LINKER	   :=$(COMPILER)

COMPILER_FLAGS :=-pipe
ifeq ($(LANGUAGE),c)
COMPILER_FLAGS += $(CFLAGS) -std=c11
endif
ifeq ($(LANGUAGE),cpp)
COMPILER_FLAGS += $(CXXFLAGS) -std=c++11 -pthread #`sdl-config --cflags`
endif

LINKER_FLAGS   :=-s -pipe -L`gcc -print-file-name=`
ifeq ($(LANGUAGE),cpp)
LINKER_FLAGS += -std=c++14 -pthread
endif
LIBS           :=
#-lgcc -lc -lm -lpthread #-lGL -lGLU -lGLEW `sdl-config --libs`

ifeq ($(MODE),debug)
COMPILER_FLAGS += -Wall -ggdb
else
COMPILER_FLAGS += -O2
endif


SOURCE_DIRS  :=$(addprefix $(SOURCE_TOP_DIR)/, $(SOURCE_SUBDIRS)) $(SOURCE_TOP_DIR)
BUILD_DIRS   :=$(patsubst $(SOURCE_TOP_DIR)%, $(BUILD_TOP_DIR)%, $(SOURCE_DIRS))
SOURCE_FILES :=$(wildcard $(addsuffix /*.$(SOURCE_EXT), $(SOURCE_DIRS)))
OBJECT_FILES :=$(patsubst $(SOURCE_TOP_DIR)%.$(SOURCE_EXT), $(BUILD_TOP_DIR)%.$(OBJECT_EXT), $(SOURCE_FILES))


# example of define, info and eval
# define SOURCE_AND_OBJECT_FILES
# 	SOURCE_FILES := $$(wildcard $$(addsuffix /*.$(SOURCE_EXT), $$(SOURCE_DIRS)))
# 	OBJECT_FILES := $$(patsubst $$(SOURCE_TOP_DIR)%.$(SOURCE_EXT), $$(BUILD_TOP_DIR)%.$(OBJECT_EXT), $$(SOURCE_FILES))
# endef
# $(info $(call SOURCE_AND_OBJECT_FILES))
# $(eval $(call SOURCE_AND_OBJECT_FILES))



$(info [START: $(shell date -R)])

all: main
	@echo "[FINISH: `date -R`]"

main: $(OBJECT_FILES)
	$(info [$(LINKER)] $^ => $@)
	$(LINKER) $^ -o $(BUILD_TOP_DIR)/$@ $(LINKER_FLAGS) $(LIBS)

$(OBJECT_FILES): | $(BUILD_DIRS)
$(BUILD_DIRS):
	@echo "[mkdir] $@"
	@mkdir -p $@

$(BUILD_TOP_DIR)/%.$(OBJECT_EXT): $(SOURCE_TOP_DIR)/%.$(SOURCE_EXT)
	@echo "[$(COMPILER)] $< -> $@"
	$(COMPILER) -c $< -o $@ $(COMPILER_FLAGS)



.PHONY: mkdirs clean showvars rebuild


mkdirs:
	@echo [mkdir] -p $(BUILD_DIRS)
	@mkdir -p $(BUILD_DIRS)

clean:
	@echo cleaning...
	@echo [rm] $(OBJECT_FILES)
	@rm $(OBJECT_FILES)
	@echo [rm] $(BUILD_TOP_DIR)/main
	@rm $(BUILD_TOP_DIR)/main

showvars:
	@echo SOURCE_DIRS : $(SOURCE_DIRS)
	@echo SOURCE_FILES: $(SOURCE_FILES)
	@echo OBJECT_FILES: $(OBJECT_FILES)

rebuild: clean all

Bad_ptr ★★★★★
()
Ответ на: комментарий от arto

только хотел это написать - нельзя %.o в зависимость ставить

waker ★★★★★
()
Ответ на: комментарий от CYB3R

Может, можно, только как?

да хз.. может valac так умеет. или можно враппер сделать - отдельный скрипт, который компиляет .vala в .o

waker ★★★★★
()
Ответ на: комментарий от arto

Спасибо. Написал так:

CFLAGS=$(shell pkg-config --cflags --libs glib-2.0 gobject-2.0)

all: helloworld

%.c: %.vala
	valac -C $^

%.o: %.c
	gcc -c -o $@ $^ $(CFLAGS)

helloworld: world.o hello.o
	gcc -o $@ $^ $(CFLAGS)

clean:
	rm -fv *.c *.o helloworld
Вывод такой:
valac -C world.vala
world.vala:2.5-2.22: warning: method `World.text' never used
    public string text() {
    ^^^^^^^^^^^^^^^^^^
Compilation succeeded - 1 warning(s)
gcc -c -o world.o world.c -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lgobject-2.0 -lglib-2.0 
valac -C hello.vala
hello.vala:2.17-2.21: error: The name `World' does not exist in the context of `main'
    var w = new World();
                ^^^^^
hello.vala:2.9-2.23: error: var declaration not allowed with non-typed initializer
    var w = new World();
        ^^^^^^^^^^^^^^^
hello.vala:4.19-4.19: error: The name `w' does not exist in the context of `main'
    stdout.printf(w.text() + "\n");
                  ^
Compilation failed: 3 error(s), 0 warning(s)
Makefile:6: ошибка выполнения рецепта для цели «hello.c»
make: *** [hello.c] Ошибка 1
То есть для valac нужно передавать hello.vala world.vala вместе, а не отдельно.

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от waker

Скриптами-то и я могу. Но хочется сделать Makefile.

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

Вообще в сях для этого как раз и нужны ключ "-c" для gcc и заголовочные файлы. -c позволяет компилировать исходники по одному, при условии что подключены все необходимые .h. Без них непонятно, как выделять место на стеке под переменную w. В vala разве нет чего-то подобного?

Kiborg ★★★
()
CC=gcc
CFLAGS= `pkg-config --cflags --libs glib-2.0 gobject-2.0`
VC=valac
VCFLAGS= -C

SOURCE_VALA= hello.vala world.vala 
OUTPUT_VALA= hello.c world.c
OBJ= hello.o world.o
EXECUTABLE= helloworld


all:$(EXECUTABLE)

$(OUTPUT_VALA):$(SOURCE_VALA)
	$(VC) $(VCFLAGS) $(SOURCE_VALA)


$(OBJ):$(OUTPUT_VALA)
	$(CC)  $(OUTPUT_VALA) $(CFLAGS)


$(EXECUTABLE):$(OBJ)
	$(CC) -o $(EXECUTABLE) $(OBJ) $(CFLAGS)

clear:
	rm $(OUTPUT_VALA) $(EXECUTABLE) $(OBJ)


Dron ★★★★★
()
Ответ на: комментарий от Dron

gcc hello.c world.c `pkg-config --cflags --libs glib-2.0 gobject-2.0`
gcc hello.c world.c `pkg-config --cflags --libs glib-2.0 gobject-2.0`
gcc -o helloworld hello.o world.o `pkg-config --cflags --libs glib-2.0 gobject-2.0`

Может, я чего-то не понимаю?

CYB3R ★★★★★
() автор топика

Такой makefile ищет все файлы *.vala в каталогах DIRS, препроцессит и компилирует в каталог BIN. Это я по-быстрому переделал из другого проекта, сильно не присматривался, м.б. что-то пропустил. make -n показывает вроде все правильно

BIN = bin
DIRS = .

CGLAGS=$(shell pkg-config --cflags --libs xmlsec1-nss)

VSOURCE := $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.vala))
CSOURCE := $(addprefix $(BIN)/, $(VSOURCE:.vala=.c))
OBJS    := $(addprefix $(BIN)/, $(VSOURCE:.vala=.o))

target=helloworld


all:		$(target)

$(target):	$(OBJS)
		ld $(target) $(ldflags) $(OBJS)

$(CSOURCE): $(VSOURCE)
		valac $(VSOURCE)

$(BIN)/%.o: %.c
		cc -c $(ccflags) $< -o $@

Deleted
()
Ответ на: комментарий от CYB3R

Может, я чего-то не понимаю?

Да

$(OUTPUT_VALA):$(SOURCE_VALA)
$(VC) $(VCFLAGS) $>(SOURCE_VALA)


Это valac -C hello.vala world.vala

$(OBJ):$(OUTPUT_VALA)
$(CC) $(OUTPUT_VALA) $(CFLAGS)

Это gcc hello.c world.c `pkg-config --cflags --libs glib-2.0 gobject-2.0`

$(EXECUTABLE):$(OBJ)
$(CC) -o $(EXECUTABLE) $(OBJ) $(CFLAGS)

Это gcc -o helloworld hello.o world.o

Ну с $(CFLAGS) переборщил это да.

Dron ★★★★★
()
Последнее исправление: Dron (всего исправлений: 1)
Ответ на: комментарий от Dron

valac -C hello.vala world.vala

А -C откуда возьмётся?

gcc hello.c world.c

Выполняется дважды и не производит файлов .o.

gcc -o helloworld hello.o world.o

Не находит файлов .o, так как они не были произведены в предыдущем шаге.

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

А -C откуда возьмётся?

А приглядись получше.

Dron ★★★★★
()
Ответ на: комментарий от CYB3R
dron@gnu:~$ cat Makefile 
CC=gcc
CFLAGS= `pkg-config --cflags --libs glib-2.0 gobject-2.0`
VC=valac
VCFLAGS= -C

SOURCE_VALA= hello.vala world.vala 
OUTPUT_VALA= hello.c world.c
OBJ= hello.o world.o
EXECUTABLE= helloworld


all:$(EXECUTABLE)

$(OUTPUT_VALA):$(SOURCE_VALA)
	$(VC) $(VCFLAGS) $(SOURCE_VALA)


$(OBJ):$(OUTPUT_VALA)
	$(CC)  $(OUTPUT_VALA) 


$(EXECUTABLE):$(OBJ)
	$(CC) -o $(EXECUTABLE) $(OBJ) $(CFLAGS)

clear:
	rm $(OUTPUT_VALA) $(EXECUTABLE) $(OBJ)
dron@gnu:~$ 

Dron ★★★★★
()
Последнее исправление: Dron (всего исправлений: 1)
Ответ на: комментарий от Dron
CC = gcc
CFLAGS = $(shell pkg-config --cflags --libs glib-2.0 gobject-2.0)
VC = valac
VCFLAGS = -C

SOURCE_VALA = hello.vala world.vala 
OUTPUT_VALA = $(SOURCE_VALA:.vala=.c)
OBJ = $(SOURCE_VALA:.vala=.o)
EXECUTABLE = helloworld


all: $(EXECUTABLE)

$(OUTPUT_VALA): $(SOURCE_VALA)
	$(VC) $(VCFLAGS) $(SOURCE_VALA)


$(OBJ): $(OUTPUT_VALA)
	$(CC) -c $(OUTPUT_VALA) $(CFLAGS)

$(EXECUTABLE): $(OBJ)
	$(CC) -o $(EXECUTABLE) $(OBJ) $(CFLAGS)

clean:
	rm $(OUTPUT_VALA) $(EXECUTABLE) $(OBJ)

Вот так работает. А есть способ как-то вызывать gcc -c для каждого с-файла, как это происходит, если мы используем %.с?

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от Dron
$ make -n
valac -C hello.vala world.vala 
valac -C hello.vala world.vala 
gcc -c hello.c world.c -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lgobject-2.0 -lglib-2.0 
gcc -c hello.c world.c -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lgobject-2.0 -lglib-2.0 
gcc -o helloworld hello.o world.o -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lgobject-2.0 -lglib-2.0

И почему-то всё дважды.

CYB3R ★★★★★
() автор топика
Последнее исправление: CYB3R (всего исправлений: 1)
Ответ на: комментарий от CYB3R

И почему-то всё дважды.

Хрен его знает ::)

Dron ★★★★★
()
Ответ на: комментарий от CYB3R

Наверное, так как bmake также себя ведёт. Выполнять же оно будет по одному разу.

Dron ★★★★★
()
Ответ на: комментарий от CYB3R

Вывод такой:

для valac нужно передавать hello.vala world.vala вместе, а не отдельно

вывод странный, и видимо из него весь гимор с Makefile получается..

что-то сдаётся мне, что из world.vala вами недополучены world.h и world.vapi; и hello.с более корректно строить из hello.vala и world.vapi

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

что-то сдаётся мне, что из world.vala вами недополучены world.h и world.vapi

Верно, как это делать?

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

Из оф.туториала, раздел libraries (https://wiki.gnome.org/Projects/Vala/Tutorial#Using_Libraries):

Use the next command to generate test.c, test.h and test.vapi files. These are the C versions of the library to be compiled, and the VAPI file representing the library's public interface.

$ valac -C -H test.h --library test test.vala --basedir ./

там кстати как-раз пример с вашим helloword :-)

MKuznetsov ★★★★★
()
Последнее исправление: MKuznetsov (всего исправлений: 1)
Ответ на: комментарий от MKuznetsov

Интересно, а что делать с какими-нибудь рекурсивными зависимостями (класс А используется в классе Б, а класс Б в классе А)?

CYB3R ★★★★★
() автор топика
Ответ на: комментарий от CYB3R

а что делать с какими-нибудь рекурсивными зависимостями (класс А используется в классе Б, а класс Б в классе А)?

как и всегда, как и везде..предварительно отдельно и нерекурсивно описывать интерфейсы А и Б, то есть писанины меньше не будет

vala же не делает никаких особо чудесных вещей, а фактически только скрывает GObject и его производные в новоделе, сходном с с++/D/C#; те-же костыли припорошенные сахаром

MKuznetsov ★★★★★
()
Ответ на: комментарий от powerguy

Ты вообще не отличаешь autotools от Makefile?

CYB3R ★★★★★
() автор топика
20 декабря 2015 г.

Наконец-то я дописал это. Получилось говно. Синтаксис GNU Make говно. Встроенных функций дико не хватает, потому пришлось заюзать sed. Но всё-таки оно работает. Вот.

CYB3R ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.