2010-09-02 33 views
63

Quiero programar usando Qt, pero no quiero usar compiladores especiales o IDE como Qt Creator y qmake. Quiero escribir con Kate y compilar con g ++.¿Puedo usar Qt sin qmake o Qt Creator?

¿Puedo compilar un programa que use Qt con g ++? ¿Cómo lo compilo con g ++?

+12

Entiendo que no desee utilizar Qt Creator, pero ¿por qué no utilizar qmake? Todo lo qmake hace es generar un Makefile para ti; si no usas qmake, tendrás que escribir el mismo Makefile y, lo que es peor, tendrás que mantener a mano un Makefile diferente para cada plataforma en la que quieras compilar. Con qmake solo tiene que crear un solo archivo .pro, en lugar de tener que recordar cómo un Makefile de MSVC difiere de un Makefile de gnu, etc. etc. –

+6

Porque quiero saber qué sucede durante la compilación en lugar de utilizar una herramienta automática. Es más fácil con qmake o Qt Creator, pero me gusta hacer esta tarea manualmente. – Squall

+2

¿Desea escribir sus archivos MAKE manualmente, en lugar de usar un generador como qmake, cmake o autotools? La única razón para esto es si desea aprender la sintaxis de Makefile. El resultado será una carga de mantenimiento, no portátil, etc. –

Respuesta

34

Claro que puedes. Aunque es más conveniente con qmake o CMake, puede hacerlo:

CXXFLAGS += -Ipath_to_your_qt_includes 
LDFLAGS += -Lpath_to_your_qt_libs 

LDLIBS += -lqt-mt (for Qt3) 

o

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

my_prog: my_prog.cpp 

(en un archivo MAKE)

Actualización - invocando moc:

Presupuesto de moc manpage :

Aquí es una regla makefile útil si sólo utiliza GNU make:

m%.cpp: %.h 
     moc $< -o [email protected] 

me nombraría personalmente la salida en lugar %.moc.cpp (que m%.cpp). A continuación, agrega la dependencia de my_prog en my_prog.moc.cpp

my_prog: my_prog.cpp my_prog.moc.cpp 

Del mismo modo para uic. La situación aquí es más complicada, ya que debe generar reglas para los encabezados y, y debe agregar una dependencia en un archivo de encabezado para asegurarse de que se genere antes de compilar las fuentes. Algo como esto podría funcionar:

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 
+2

Además, si usa la sintaxis extendida de Qt, como señales, ranuras y demás, debe ejecutar moc manualmente. Ese es el único compilador especial "obligatorio". – teukkam

+2

Y esta respuesta no muestra cómo ejecutar 'moc' (algo que ** necesita ** demostrar) –

+1

@teukkam, @Ken Bloom: ver edición – jpalecek

18

No es necesario utilizar QtCreator para escribir un programa Qt.

Tampoco tiene que usar qmake pero está solicitando problemas al no usarlo.

Para hacer algo remotamente interesante en Qt, inevitablemente terminarás subclasificando QObject. Todas estas subclases requieren la macro Q_OBJECT en su definición que habilita la sintaxis señal/ranura. Esta sintaxis no es C++ normal y no se puede compilar usando g ++. Los archivos que contienen definiciones de clase con Q_OBJECT se deben ejecutar a través de Qt's meta-object compiler que se llama moc. Esto significa que tiene que determinar qué archivos deben tener moc aplicado a ellos, luego ejecutar moc en ellos, y luego compilar el archivo cpp resultante con g++. Esta es la razón por la que Qt suministra qmake. Genera las reglas correctas en el Makefile para ti.

Los archivos del proyecto Qt. Pro son bastante sencillos de usar y seriamente recomiendo que los use. Recuerde, qmake es una herramienta de línea de comandos como g++. También, en realidad puede crear un archivo de proyecto esqueleto para usted mediante el suministro de la opción de modo -project para empezar sólo se puede hacer

qmake -project 
qmake 
make 

y ya está.En la práctica me parece que el archivo de proyecto generado puede faltar la declaración de las bibliotecas Qt adicionales que podrían estar utilizando lo que podría tener que añadir una línea como

QT += opengl 

si, por ejemplo, que ha incluido algo así como QGLWidget .

+2

para todos los fines y propósitos, Qt es bastante inútil sin QMake. Buena respuesta. –

+0

En realidad, puede decidir utilizar la extensión .qpp para los archivos que necesitan moc'ing. Esto le permite crear una regla de creación (o una regla de creación de Visual Studio personalizada). El archivo .cpp generado se compilará normalmente. – MSalters

+1

Esta respuesta es engañosa. Qmake es una herramienta de compilación y es independiente de moc. Puede llamar a moc con éxito y facilidad desde una herramienta de compilación diferente. He hecho esto en Visual Studio y SCons, por ejemplo. En ambos es fácil tener esto manejado de forma transparente para que pueda continuar de forma normal, como si moc no existiera. – JBentley

0

Algunos precompiladores son necesarios para Qt projcet, como moc, uic, ..., etc. Qt Creator + qmake son convenientes para hacer tales cosas y generar un makefile para compiladores g ++ o msvc.

5

Aquí es mi makefile para cualquier proyecto Qt sin utilizar qmake:

#--------------------------------------------------------------------------------- 
# 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 [email protected] ] || mkdir -p [email protected] 
    @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 [email protected]) 
    @$(LD) $(LDFLAGS) $(OFILES) -o [email protected] $(LIBS) 

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

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

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

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

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

Aquí, moctool es una sencilla herramienta que ayuda a los encabezados no QObject, aquí está el código fuente:

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

+0

Me doy cuenta de que esto es antiguo, pero esta respuesta es _exactamente_ lo que estoy tratando de hacer en mi proyecto actual. Sin embargo, estoy luchando por comprender algunas partes de la lógica. Primero, la línea 36: 'ifneq ($ (BUILD), $ (notdir $ (CURDIR)))' parece verificar si el archivo make se ejecutó desde el directorio de compilación, si no, parece llamar a otro '@make --no- print-directory -C $ (BUILD) -f $ (CURDIR)/Makefile' en la línea 71. ¿Por qué? Todo lo que ocurre después del 'else' en la línea 93 comenzando con el objetivo' all: 'es lo que esperaría, en su lugar. Espero que el OP responda ... – ph0t0n

Cuestiones relacionadas