Генерация и использование исходного файла с использованием CMake в CLion - PullRequest
0 голосов
/ 04 марта 2020

Я пытаюсь работать над проектом в CLion, используя Gtk +, но файл CMake, который я придумал, чтобы заставить его работать, кажется слишком сложным и плохим. Он также помещает сгенерированный исходный файл в папку binaries, поэтому я хочу знать, есть ли лучший способ сделать это.

Я написал Makefile, чтобы продемонстрировать, как я хочу, чтобы CMake вел себя:

CC ?= gcc
PKGCONFIG = $(shell which pkg-config)
CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-3.0)
LIBS = $(shell $(PKGCONFIG) --libs gtk+-3.0)

SRC = main.c labpresentapp.c labpresentappwin.c
GEN_SRC = resources.c

OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,$(SRC:.c=.o) $(GEN_SRC:.c=.o))

.PHONY=all clean

all: labpresentapp

resources.c: labpresentapp.gresource.xml window.ui app-menu.ui
        glib-compile-resources labpresentapp.gresource.xml --target=$@ --generate-source

$(OBJDIR)/%.o: %.c
        $(CC) -c -o $@ $(CFLAGS) $<

$(OBJS): | $(OBJDIR)

$(OBJDIR):
        mkdir $(OBJDIR)

labpresentapp: $(OBJS)
        $(CC) -o $(@F) $(OBJS) $(LIBS)

clean:
        rm -f $(SRC_GEN)
        rm -f $(OBJS)
        rm -rf $(OBJDIR)
        rm -f labpresentapp

Однако я не могу заставить CMake сделать это. Ниже моя последняя попытка:

cmake_minimum_required(VERSION 3.14)
project(LabPresentApp C)

set(LAB_PRESENT_APP_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LAB_PRESENT_APP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})

set(LAB_PRESENT_APP_VERSION_MAJOR 1)
set(LAB_PRESENT_APP_VERSION_MINOR 0)
set(LAB_PRESENT_APP_VERSION_PATCH 0)

set(CMAKE_C_STANDARD 11)

find_package(PkgConfig REQUIRED)

pkg_check_modules(MY_PKG REQUIRED IMPORTED_TARGET gtk+-3.0)

set(GLIB_FLAGS --target=resources.c)
set(GLIB_FLAGS ${GLIB_FLAGS} --generate-source)
set(GLIB_FLAGS ${GLIB_FLAGS} --sourcedir=${PROJECT_SOURCE_DIR})

add_custom_command(
        OUTPUT resources.c
        COMMAND glib-compile-resources ${PROJECT_SOURCE_DIR}/labpresentapp.gresource.xml ${GLIB_FLAGS}
        DEPENDS ${PROJECT_SOURCE_DIR}/labpresentapp.gresource.xml ${PROJECT_SOURCE_DIR}/app-menu.ui
                ${PROJECT_SOURCE_DIR}/window.ui
)

add_custom_target(generate_resources DEPENDS resources.c)

set(SOURCE_FILES main.c labpresentapp.c labpresentapp.h labpresentappwin.c labpresentappwin.h resources.c)

add_executable(${PROJECT_NAME} ${SOURCE_FILES})

add_dependencies(${PROJECT_NAME} generate_resources)

target_link_libraries(${PROJECT_NAME} PUBLIC PkgConfig::MY_PKG)

Это эмулирует большинство функций Makefile, но resources.c генерируется в двоичной папке.

Есть ли лучший способ выполнить sh функция Makefile в CMake?

1 Ответ

1 голос
/ 04 марта 2020

Поскольку ваш glib-compile-resources не указывает, где генерировать файл, он генерируется в текущем рабочем каталоге. Как Документация CMake гласит:

WORKING_DIRECTORY

Выполнить команду с заданным текущим рабочим каталогом. Если это относительный путь, он будет интерпретирован относительно каталога дерева сборки, соответствующего текущему исходному каталогу.

Если вы ожидаете файл в заданном месте, вам, вероятно, потребуется добавить WORKING_DIRECTORY директива к этому add_custom_command, чтобы закрепить местоположение в ${CMAKE_CURRENT_SOURCE_DIR}.

Лично я бы оставил поведение как есть и сделал бы строку с вашими источниками:

set(SOURCE_FILES main.c labpresentapp.c labpresentapp.h labpresentappwin.c labpresentappwin.h ${CMAKE_CURRENT_BINARY_DIR}/resources.c)

Я считаю это поведение правильным. Исходный каталог должен храниться в неизменном виде, а сгенерированные файлы должны go помещаться в двоичный каталог. Таким образом, он предотвращает случайное помещение сгенерированного файла в систему управления версиями и облегчает очистку (достаточно удалить двоичный каталог вместо очистки отдельных файлов во многих местах).

...