我可以在没有qmake或Qt Creator的情况下使用Qt吗?


71

我想使用Qt进行编程,但是我不想使用特殊的编译器或IDE,例如Qt Creator和qmake。我想用Kate编写并用g ++进行编译。

我可以编译使用Qt和g ++的程序吗?如何使用g ++进行编译?


12
我可以理解,不想使用Qt Creator,但是为什么不使用qmake?qmake所做的只是为您生成一个Makefile。如果不使用qmake,则必须自己编写相同的Makefile,更糟糕的是,您必须为要在其下进行编译的每个平台手动维护一个不同的Makefile。随着QMAKE你只需要创造,而不必记住一个.pro文件,如何从GNU的Makefile,等等等等,一个MSVC的Makefile不同
杰里米Friesner

7
因为我想知道在编译过程中会发生什么,而不是使用自动工具。使用qmake或Qt Creator更加容易,但是我喜欢手动执行此任务。

5
如果您想了解make的工作原理,您仍然可以查看qmake生成的Makefile。
Jeremy Friesner 2010年

7
我们当中很多人甚至没有使用Makefiles-毕竟还有其他构建系统。SCons和bjam特别受欢迎。我开发了一个中型客户端应用程序,该应用程序最近开始使用Qt,并且没有办法将整个构建系统切换到qmake-尤其是当弄清依赖项并决定何时使用qmake时,qmake显得如此脆弱它必须重新生成您的Makefile。
泰德·米德尔顿

6
@JeremyFriesner一个更好的答案(迟了几年)可能是:我已经有了一个构建工具(make或其他方式),并且不希望有一个负责我的工具链的库。
Alec Teal 2014年

Answers:


40

你当然可以。尽管使用qmake或CMake更方便,但是您可以执行以下操作:

CXXFLAGS += -Ipath_to_your_qt_includes
LDFLAGS += -Lpath_to_your_qt_libs

LDLIBS += -lqt-mt (for Qt3)

要么

LDLIBS += -lQtCore -lQtGui (for Qt4, add what you need)

my_prog: my_prog.cpp

(在makefile中)

更新-调用moc

引用来自moc手册页

如果仅使用GNU make,这是一个有用的makefile规则:

m%.cpp: %.h
        moc $< -o $@

我个人将输出命名为%.moc.cpp(而不是m%.cpp)。然后添加my_progon的依赖项my_prog.moc.cpp

my_prog: my_prog.cpp my_prog.moc.cpp

对于uic同样如此。这里的情况更加复杂,因为您必须为头文件源文件生成规则,并且必须在头文件上添加依赖项以确保在编译源文件之前就生成了它。这样的事情可能会起作用:

my_prog: my_prog.o my_prog.moc.o my_prog.ui.o
        $(CXX)  $(LDFLAGS) -o my_prog $^ $(LDLIBS)

my_prog.o: my_prog.cpp my_prog.ui.h

3
另外,如果您使用Qt的扩展语法(例如信号,插槽和内容),则需要手动运行moc。那是唯一的“强制性”特殊编译器。
teukkam 2010年

2
而且此答案并没有告诉您如何运行moc(它非常需要演示的内容)
Ken Bloom

21

您当然不必使用QtCreator编写Qt程序。

您也不必使用,qmake但是通过不使用它来寻求麻烦。

要在Qt中做什至遥不可及的事情,您都不可避免地要继承子类QObject。所有这些子类都需要Q_OBJECT在其定义中使用宏,以启用信号/插槽语法。此语法不是常规的C ++,不能使用g ++进行编译。包含类定义的文件Q_OBJECT必须通过Qt的元对象编译器(称为)运行moc。这意味着您必须确定需要将哪些文件moc应用于它们,然后moc在它们上运行,然后使用以下命令编译生成的cpp文件g++。这就是Qt提供的原因qmake。它会在Makefile中为您生成正确的规则。

Qt .pro项目文件确实非常易于使用,我强烈建议您使用它们。记住,qmake就像一样是命令行工具g++。另外,它实际上可以通过提供-project选项为您创建一个骨架项目文件,因此,您可以开始

qmake -project
qmake
make

到此为止。在实践中,我发现生成的项目文件可能缺少我可能正在使用的任何其他Qt库的声明,因此您可能必须添加一行

QT += opengl

例如,如果您包含的内容QGLWidget


2
出于所有意图和目的,没有QMake的Qt几乎没有用。好答案。
圣哈辛托

3
这个答案是误导的。Qmake是一个构建工具,独立于moc。您可以通过其他构建工具轻松轻松地调用moc。例如,我已经在Visual Studio和SCons中做到了。两者都很容易将其透明处理,以便您可以像正常情况下一样继续进行moc。
JBentley '16

1
@JBentley:答案很明确,如果没有,qmake您将不必“确定需要将哪些文件moc应用于它们,然后对它们运行moc”。我目前在一家有自己的构建系统的公司工作,它在moc没有qmake
Troubadour

1
@Troubadour是的,但是您还说过“您正在通过不使用[qmake]来请求麻烦”,并且“我会严重建议您使用[.pro项目文件]”。我并不是说您的答案是错误的,只是误导。在问题的上下文中,“我可以在没有qmake或Qt Creator的情况下使用Qt吗?” ,则表示不使用qmake是困难和/或麻烦的。实际上,对此答案的第一位评论者得出的结论是:“如果没有QMakeQt将会毫无用处”。事实是,qmake只是几种合法且高度可用的替代方案之一。
JBentley'3

4
“ Q_OBJECT ...此语法不是常规C ++”。这只是一个宏,而且是完全有效的C ++。宏所做的只是声明一堆函数。moc编译提供了定义。
rfcoder89

7

这是我不使用qmake的任何Qt项目的makefile:

#---------------------------------------------------------------------------------
# Compiler executables
#---------------------------------------------------------------------------------
CC      :=  gcc
CXX     :=  g++

#---------------------------------------------------------------------------------
# Options for code generation
#---------------------------------------------------------------------------------
DEFINES :=  -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
CFLAGS  :=  -g -Wall $(DEFINES)
CXXFLAGS:=  $(CFLAGS)
LDFLAGS :=  -g -Wl

#---------------------------------------------------------------------------------
# Any extra libraries you wish to link with your project
#---------------------------------------------------------------------------------
LIBS    :=  -lQtGui -lQtCore -lpthread

#---------------------------------------------------------------------------------
# Some more include paths
#---------------------------------------------------------------------------------
INCPATHS:=  -I/usr/share/qt4/mkspecs/default -I/usr/include/QtGui -I/usr/include/QtCore

#---------------------------------------------------------------------------------
# Source folders and executable name
#---------------------------------------------------------------------------------
TARGET  :=  $(shell basename $(CURDIR))
BUILD   :=  build
SOURCES :=  source
INCLUDES:=  source include

#---------------------------------------------------------------------------------
# Source files
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------
export OUTPUT   :=  $(CURDIR)/$(TARGET)

export VPATH    :=  $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
                    $(foreach dir,$(INCLUDES),$(CURDIR)/$(dir))

CFILES      :=  $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES    :=  $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
HFILES      :=  $(foreach dir,$(INCLUDES),$(notdir $(wildcard $(dir)/*.h)))

#---------------------------------------------------------------------------------
# Use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
    export LD   :=  $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
    export LD   :=  $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

export OFILES   :=  $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(HFILES:.h=.moc.o)

export INCLUDE  :=  $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) $(INCPATHS)

#---------------------------------------------------------------------------------
.PHONY: $(BUILD) clean install uninstall
#------------------------------------------------------------------------------
$(BUILD):
    @[ -d $@ ] || mkdir -p $@
    @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile

#---------------------------------------------------------------------------------
clean:
    @echo clean ...
    @rm -fr $(BUILD) $(TARGET)

#---------------------------------------------------------------------------------
install:
    @cp -u $(TARGET) /usr/bin/$(TARGET)
    @echo installed.

#---------------------------------------------------------------------------------
uninstall:
    @rm -f /usr/bin/$(TARGET)
    @echo uninstalled.

#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
# Makefile targets
#---------------------------------------------------------------------------------
all: $(OUTPUT)

#---------------------------------------------------------------------------------
$(OUTPUT): $(OFILES)
    @echo built ... $(notdir $@)
    @$(LD) $(LDFLAGS) $(OFILES) -o $@ $(LIBS)

#---------------------------------------------------------------------------------
%.o: %.c
#---------------------------------------------------------------------------------
    @echo $(notdir $<)
    @$(C) $(CFLAGS) $(INCLUDE) -c $< -o $@

#---------------------------------------------------------------------------------
%.o: %.cpp
#---------------------------------------------------------------------------------
    @echo $(notdir $<)
    @$(CXX) $(CXXFLAGS) $(INCLUDE) -c $< -o $@

#---------------------------------------------------------------------------------
%.moc.cpp: %.h
#---------------------------------------------------------------------------------
    @echo $(notdir $<)
    @moctool $< $(DEFINES) $(INCLUDE) -o $@

#---------------------------------------------------------------------------------
%.moc.o: %.moc.cpp
#---------------------------------------------------------------------------------
    @echo $(notdir $<)
    @$(CXX) $(CXXFLAGS) $(INCLUDE) -c $< -o $@

#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

在这里,moctool是一个简单的工具,可帮助处理非QObject标头,这是其源代码:

https://github.com/Quent42340/EasyLib/blob/master/tools/moctool/source/main.cpp


1
我意识到这很旧,但是这个答案正是我要在当前项目中尝试做的。但是,我在努力理解一些逻辑。首先,第36行:ifneq ($(BUILD),$(notdir $(CURDIR)))似乎正在检查是否从生成目录执行了makefile,否则,似乎@make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile在第71行调用了另一个。为什么?elseall:目标开始的在线93之后发生的所有事情,都是我所期望的。我希望OP会回应...
ph0t0n

0

Qt项目需要一些预编译器,例如moc,uic等。Qt Creator + qmake可以很方便地执行此类操作并为g ++或msvc编译器生成makefile。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.