porting qmake pro file to mac - library issue
-
I have a QT project deployed and running on windows successfully. Now I need to tackle getting the project to compile and link on the mac - in this case using intel.
For windows, I needed to link to several external C++ packages, for this I used microsoft's portable vcpkg and I added a couple of environment variables so that qmake could link with or include the libraries.
On the Mac, I use homebrew as the package manager as it is very simple to setup and it seems to be much more up to date compared to the vcpkg port on the Mac. One thing I did notice though is that it creates dylib libraries. Are these like windows DLLs?
Anyhow, homebrew installs the non header only libraries in /usr/local/opt and the headers appear to be installed in /usr/local/include well links to the actual headers are stored there).
This is a list of my libraries installed via homebrew: range-v3 and magic-enum are header only libraries so they do not appear in the /usr/local/opt.
jcoffey@Johns-iMac main % brew list ==> Formulae fmt isl range-v3 gcc@11 libmpc spdlog geographiclib lz4 tinyxml2 gmp magic_enum xz howard-hinnant-date mpfr zstd
Here is a listing the libraries in opt - I see all except the header only librares there (which makes sense)
jcoffey@Johns-iMac main % ls /usr/local/opt fmt isl@0.25 pzstd gcc@11 isl@0.26 range-v3 geographiclib libmpc spdlog gmp lz4 tinyxml2
The project is a subdirs project and so I have a common.pri file (see below) containig common settings that are needed by individual subdir projects. This file also has references to environment variables - I expect I will need at the very least to add EXTLIBS_ROOT and VCPKG_ROOT to ~/.bash-profile (perhaps I should rename the latter HOMEBREW_ROOT) as persistent environment variables to my shell.
# Define expandable environment variables EXTLIBS = $$(EXTLIBS_ROOT) VCPKG = $$(VCPKG_ROOT) # Includes common configuration for all subdirectory .pro files. CONFIG += c++latest # disables all the APIs deprecated before Qt 6.0.0 DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 INCLUDEPATH += .. \ $${VCPKG}/installed/x64-windows/include \ $${EXTLIBS}/ait664/include CONFIG(debug, debug|release) { LIBS += -L$${VCPKG}/installed/x64-windows/debug/lib } else { LIBS += -L$${VCPKG}/installed/x64-windows/lib } WARNINGS += -Wall
Next we have the main project that I am trying to build (its one of the subdirs). This is the one that contains the 'win32' special blocks for debug and release. I'm not sure how to tacke the equivalent on the mac platform.
# include common project settings !include( ../common.pri ) { error( "Couldn't find the common.pri file!" ) } QT += core-private multimedia-private gui widgets printsupport opengl greaterThan(QT_MAJOR_VERSION, 4): QT += widgets DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 \ QCUSTOMPLOT_USE_OPENGL \ AUDIO_DECODER SOURCES += \ A664Worker.cpp \ ConstrainedSpinBox.cpp \ CustomAudioDevice.cpp \ LogItemDelegate.cpp \ MainWindow.cpp \ QWAMDelegate.cpp \ RtcpWorker.cpp \ RtpWorker.cpp \ SinkDevice.cpp \ SourceDevice.cpp \ main.cpp \ qcustomplot.cpp \ settingsdialog.cpp HEADERS += \ AITStructs.h \ A664Worker.h \ AppSettings.h \ ConstrainedSpinBox.h \ CustomAudioDevice.h \ FormatHelpers.h \ LogItemDelegate.h \ MainWindow.h \ QWAMDelegate.h \ RtcpWorker.h \ RtpWorker.h \ SinkDevice.h \ SourceDevice.h \ UICommon.h \ qcustomplot.h \ settingsdialog.h FORMS += \ MainWindow.ui \ SettingsDialog.ui # added support for light and dark themes RESOURCES += \ afdx.qrc win32 { # tweak the defines to ensure that we can build with warning level 4 DEFINES += _WIN32_WINNT=0x0601 WIN32_LEAN_AND_MEAN # Add library to support htonl, htons, ntohl, ntohs QMAKE_LIBS += ws2_32.lib CONFIG(debug, debug|release) { LIBS += -lfmtd -ltinyxml2 -lOpenGL32 LIBS += -L$$OUT_PWD/../util/debug/ -lutil PRE_TARGETDEPS += $$OUT_PWD/../util/debug/util.lib PRE_TARGETDEPS += $${VCPKG}/installed/x64-windows/debug/lib/fmtd.lib } else { LIBS += -lfmt LIBS += -L$$OUT_PWD/../util/release/ -lutil PRE_TARGETDEPS += $$OUT_PWD/../util/release/util.lib PRE_TARGETDEPS += $${VCPKG}/installed/x64-windows/lib/fmt.lib } LIBS += \ -L$${EXTLIBS}/ait664/lib \ -la664_api \ -ltinyxml2 \ -lOpenGL32 } # The following keeps the generated files at least somewhat separate from the source files. UI_DIR = uics MOC_DIR = mocs OBJECTS_DIR = objs
I need help to tweak the above files/environment to make it build on the mac.
-
@johnco3 You should just be able to create a separate conditional block (analogous to the
win32
block), but like so:macx { }
Put the mac specific
LIBS
andDEFINES
in there.If that doesn't work, please try to narrow the issue down. It's a lot to ask most forum participants to read multiple paragraphs of prose and hundreds of lines of build file. (But I understand! The flip side is when people criticize your post for not painting a complete enough picture!)
One way to narrow this in the manner I imagine is to post a specific error you are encountering.
-
@KH-219Design Thanks for your reply, I appreciate the sound advice. I was wondering why I was hearing crickets :). Normally I try to make a short example and customize the tags to get a quick reply, but I thought that I needed to explain everything.
I'm new to Mac development, and its confusing coming from a windows background, however Qt looks like it'll work from a cross platform point of view. I'll give the macx scope a try - do you have any advice or examples advice on how I should use or handle the environment variables that point to the homebrew directories?
-
Hi,
You can define the environnement variable in your
.zshrc
file (if you are using the current default on macOS).That said, it's a pretty standard path on macOS when using homebrew so you could simply define it as a variable in your
.pro
file. -
@johnco3 said in porting qmake pro file to mac - library issue:
how I should use or handle the environment variables that point to the homebrew directories?
I have a sample project (my own "living cheatsheet") that compiles a Qt GUI for mac (and other platforms). You don't have to take my word for it, you can look at the Github "Actions" (continuous integration) to see that the builds are succeeding.
My "cheatsheet" project:
- uses homebrew: https://github.com/219-design/qt-qml-project-template-with-ci/blob/master/tools/ci/provision_mac.sh#L10
- makes minor use of
macx
blocks inpro
/pri
files
For my baseline project, the only
macx
blocks I seem to need are the following "quality of life improvements":ios|macx { # the lines below suppress warnings generated by Qt's header files: we tell # Clang to treat Qt's (mac) Framework headers as "system headers": QMAKE_CXXFLAGS += -iframework $$[QT_INSTALL_LIBS] QMAKE_CXXFLAGS += -isystem $$[QT_INSTALL_LIBS]/QtCore.framework/Headers }
and
ios|macx { # Disable a couple that are more onerous to comply with on Mac QMAKE_CXXFLAGS += "\ -Wno-error=missing-noreturn \ -Wno-error=sign-conversion \ " }
(in the file https://github.com/219-design/qt-qml-project-template-with-ci/blob/master/compiler_flags.pri)
However, the baseline project does not link to anything from homebrew.
On another project (not public on github), here are some other snippets I have used:
macx { # MacOSX homebrew puts the mysql.h header elsewhere: QMAKE_CXXFLAGS += -isystem /usr/local/include/mysql }
macx { LIBS += -L/usr/local/lib -lmysqlclient }
Once your code compiles, you will very likely find yourself face-to-face with another common MacOS hurdle: the app bundle. Reference: https://developer.apple.com/go/?id=bundle-structure
In order to make a bundle that will launch (so you can actually launch your app), the Qt "magic" you will need is
macdeployqt
:https://github.com/219-design/qt-qml-project-template-with-ci/blob/master/build_app.sh#L91