Qmake: Avoid file name conflicts in different folders without introducing libraries - qt

I have a project with some folders which happen to contain source files with the same names.
My source tree looks like this:
project.pro
foo/
conflict.h
conflict.cpp
bar/
conflict.h
conflict.cpp
some.h
other.h
files.h
main.cpp
Per default, qmake generates a Makefile which will produce a build tree like this:
conflict.o
main.o
target
Where conflict.o is the object file resulting for both foo/conflict.cpp and foo/conflict.h.
I can't to change their names because they are generated using an external tool and forcing different file names would imply to change their contents, so this is not an option.
I also don't want to use qmake SUBDIRS template because this would imply that (1) every subdir is built separately as a library and thus very much complicate the overall build process (in my eyes at least) and (2) in the top level directory I can't have any source files. Or am I wrong?
Can't I just tell qmake to write the object files into separate directories within the build directory? So my build tree will look like this:
foo/
conflict.o
bar/
conflict.o
main.o
target
Or are there any other solutions neither requiring to rename the source files nor introducing something complicated like static libraries? I just can't believe that Qt didn't solve this (in my eyes simple) problem for years. (I already hat this problem 4 years ago but could rename the files in that project, while here I can't.)
If it's important: I use Qt 4.8 on both Ubuntu with G++ and Windows with mingw32.

Are you tied to qmake? If not, an alternative could be to use cmake. I just verified your usecase with a simple CMakeLists.txt like
cmake_minimum_required (VERSION 2.6)
project (conflict)
add_executable(conflict foo/conflict.cpp bar/conflict.cpp main.cpp)
which even included a source file in the top level directory (main.cpp). This properly builds the executable - the object files are created in sub directories like
./CMakeFiles/conflict.dir/main.cpp.o
./CMakeFiles/conflict.dir/bar/conflict.cpp.o
./CMakeFiles/conflict.dir/foo/conflict.cpp.o
cmake also includes support for Qt4, to automatically pull in the required include paths and libraries. It might require some effort to migrate from qmake to cmake, but given the requirements you have I would give it a try.

Related

In Qt, when should you use RESOURCES vs. DISTFILES vs. OTHER_FILES

Within the .pro file, things are straightforward if you're including header files (use HEADERS), C++ files (use SOURCES) and Objective-C / Objective-C++ files (use OBJECTIVE_SOURCES), but it is less clear to me how other file types should be included.
e.g. looking at various examples that Qt provide, there is inconsistency about whether QML files should be DISTFILES, OTHER_FILES or contained within a .qrc file (i.e. RESOURCES). I've gone with putting QML files in a qml.qrc file.
My question has arisen because I'm including data files, such as audio .wav files, within a .qrc file (also as shown in Qt examples; e.g. Qt Quick Demo - Maroon in Trouble) but this has slowed compiling down to a crawl. And in the case of MinGW on Windows, it simply crashes with an out of memory error when it reaches 1GB. There must be a better way to include these!
Could you provide a guide as to when to use:
DISTFILES
OTHER_FILES
RESOURCES
Quoting from the qmake manual:
RESOURCES
Specifies the name of the resource collection files (qrc) for the target. [...]
DISTFILES
Specifies a list of files to be included in the dist target. This feature is supported by UnixMake specs only. [...]
OTHER_FILES
This seems in fact undocumented, at least I could not find anything. As far as I can tell all files listed here are only linked in project explorer (of Qt Creator for example) and are not treated in any way by qmake.
As for your example you might consider shipping the files as they are and not include them in any resource file, because they are compiled into the binary.
You may also take a look at compiling external resources and using them for your large files to keep the simplicity of Qt's resource system.
DISTFILES: Something special for unix you won't use in most cases. From the docs:
Specifies a list of files to be included in the dist target. This
feature is supported by UnixMake specs only.
OTHER_FILES: Files, that are part of you project, but not of the "build". This can be things like a readme, build hints, or any other stuff, that does not fit into any other categories
RESOURCES: .qrc-files, that will be compiled into the application.
Regarding the usage of those three with QML:
You can basicly use DISTFILES or OTHER_FILES for other files. In QtCreator the appear in a node as other files. These two are exchangeable for most developers. The Qt examples are local project, thus either they don't require a resource or have both, i.e. you can find the QML-files in for example OTHER_FILES and RESOURCES.
For QML files, you should always use RESOURCES, to make sure they are within your binary.
Speaking of DISTFILES , you can try it yourself.
Assuming you are using Qt on Windows. Here is a very simple qmake project file project.pro:
TEMPLATE = app
DISTFILES += "C:\Windows\explorer.exe"
qmake it, and you can find the following statements in generated Makefile.Debug and Makefile.Release:
DIST = C:\Windows\explorer.exe
...
dist:
$(ZIP) project.zip $(SOURCES) $(DIST) project.pro
...
The target dist is one of the standard targets. I learned it from makefile - What is the difference between make and make dist? - Stack Overflow.

Add QML files to Qt Creator project tree with CMake

I have a library called qml_components containing basic QML graphical elements. I'd like to add these files to the project tree, without building them. I've been able to regroup them in a variable, by doing the following:
CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
CMAKE_POLICY(SET CMP0003 NEW)
PROJECT(myApp)
FILE(GLOB QML_SRC "*.qml")
I then tried to add them to my library target:
# Add QML files to project tree without building/compiling them
ADD_CUSTOM_TARGET(myApp ${QML_SRC})
While researching I read that ADD_CUSTOM_TARGET could add the files to the sources without building them:
The SOURCES option specifies additional source files to be included in the custom target. Specified source files will be added to IDE project files for convenience in editing even if they have not build rules.
It doesn't seem to work. I think the probable cause is that I do not generate any binaries from this library, hence the failure when trying to link the sources to the TARGET.
I had forgotten to add the SOURCES keyword in the command...
ADD_CUSTOM_TARGET(myApp SOURCES ${QML_SRC})
I'm leaving this thread open as it could be of useful information to others.

Qt/CMake difficulty with new source files

I am using Qt in a way that the Qt-related files are in a separate subdirectory GUI, and I am using CMake file, the relevant part of it shown below. Basically this setup works, but when I add a new file (something like an own widget), the new file compiles OK, but in the linking phase the new object is not found. I used to delete the build subdirectory, and after that everything works fine. So, my question: do I wrong something with CMake? (I quess the symptoms are caused by some caching problem)
include_directories(${Qt5Widgets_INCLUDES} GUI/include main/include)
add_definitions(${Qt5Widgets_DEFINITIONS})
file(GLOB_RECURSE QOBJECT_HEADERS
"GUI/include/*.h"
)
file(GLOB_RECURSE QOBJECT_SOURCES
"GUI/*.cpp"
)
QT5_WRAP_CPP(hdr_moc ${QOBJECT_HEADERS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} -std=c++11 -Wall")
add_executable(simGUI main/sim_GUI.cpp ${QOBJECT_SOURCES}
${hdr_moc})
# Use the Widgets module from Qt 5.
target_link_libraries(simGUI Qt5::Widgets)
From CMake doc:
We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.
The typical approach is to list all files manually.

How to add library paths in Qt Creator like LIBPATH in Visual Studio?

Question
a) How do we add library paths where the project should look for depended libraries in Qt Creator?
b) How are the settings in project >> Run >> Build Environment related to similar in .pro file? Does the environment variable listed there applies to .pro file as well (well they don't) so what are they exactly?
Context/Details:
Visual Studio has a various environment variables for folders where a project looks for include files, library files or executable files etc. This is rather confusing in Qt Creator and I havne't seen good documentation on it.
The only thing which is obvious is INCLUDEPATHvariable which points to the directories where to look for the include files (.h)
However how do I set the library paths, the path where it should look for dependent libraries/dlls etc? I can specify the exact library with LIBS variable in .pro file, there don't seem to equivalent of LIBPATH variable where it should look for other libraries if not found in current folder.
I have worked around this be adding library path the following way basically using LIBS variable but dropping the library file name and that seems to work and add the path but I don't see this documented anywhere.
LIBS += -L"$$_PRO_FILE_PWD_/Xerces/bin/"
But what makes things more interesting is the settings in Projects >> select 'Run' from current configuration and expand the Run Environment settings.
''
Here there is LIB variable and LIBPATH variable but there are clearly not .pro environment available. It also says here that these settings are local to user and saved in .pro.user file which perhaps suggest it's a different way to set but it doesn't say how to set them in .pro file but it does suggest to set them there if want to apply for all users!
Likewise there are DEPENDPATH AND VPATH and it is not really clearly what they are used for.
I don't have enough Rep to add comments to your question, So am adding my comment in form of answer. I am pretty new to Qt and have been developing Qt GUI application on Linux.
I set this LD_LIBRARY_PATH environment variable with the path to my Qt libraries. Am not sure how much it will be helpful to you since you are using visual studio on windows.
in Projects property go to Build Environment and add a variable with the libs path, example NAME_LIBPATH. So in the .pro file add the following:
# your lib configuration
LIBS += -L$$(NAME_LIBPATH) \
-llibname

Copy file to destination directory in Qt Creator

I want to copy a data file from a directory in my source tree to the directory of the linked app so it's available at runtime, on Windows only. There appear to be two suggested techniques: use a post target dependency to issue a DOS copy command (Including resource files in Qt Creator build directory) or use an install step (Copy a file to the build directory after compiling project with Qt), but I cannot make either work in the way I would like.
The former requires me to use qmake path variables to generate my source and destination paths, but they contain backslash path separators, which the DOS copy command cannot handle.
The install solution forces other users of my project to set up a post build step in Qt Creator before it will work (one per configuration, in fact) and I would like to avoid this, as I want to make my project work with a default Qt Creator installation.
Is there any way to do this apparently simple task that can be wholly defined in the .pro file for the project? For example, is there a way to expand qmake path variables in a platform specific way?
Though these commands run ONLY after the executable is ACTUALLY linked, this solution doesn't require an external batch file. Note: this a Windows-only solution:
From our .pri file:
win32 {
...
# Copy the appropriate dll files into the target destination directory.
QMAKE_TBB_LIBDIR = $$quote($$PWD/MySource/MyLibs/$${PLATFORM_NAME}/vc9)
QMAKE_POST_LINK = copy /y $${replace(QMAKE_TBB_LIBDIR, /, \\)}\\*.dll > $${replace($$quote(DESTDIR), /, \\)}
...
}
This places a command in the Makefile that copies all the .dll files in MyLibs/x64 or MyLibs/Win32 into the destination directory.
However, if the executable did not need to be linked, then the .dlls are NOT copied.
The post build batch file would not have this limitation.

Resources