My project has the following structure:
And include my include directories like this
includedirs {
"ext/openssl-1.0.2f/include",
"ext/easyloggingpp/src",
"ext/pugixml/src",
"ext/sfml-2.3.2/include"
}
But in my cpp files I need to add the includes like this
#include "../../ext/openssl-1.0.2f/include/openssl/bio.h"
How can I include the file by just stating #include "openssl/bio.h"?
Here is an updated project structure:
The generated files are under the workspace directory
Partial of the openssl directory
Although you dont really mention it in your question I conclude from your tags that you are using premake.
I use the includedirs {"relativepath1", "relativepath2", ... } of premake. It adds the directories to your compilers include paths and you can include them like that:
#include <Header.h> || #include "Header.h"
Also see the documentation
Related
I want to import some of resources from another project without copying into my project directory. Environment variable ANOTHER_PROJECT_DIR stores path to another project.
I've tried to do something like this:
<file>%ANOTHER_PROJECT_DIR%/file</file>
or this:
<file>$$(ANOTHER_PROJECT_DIR)/file</file>
in my qrc file.
So is it possible to use system environment variables in Qt resource file and how can I do it?
It would be great to find crossplatform solution
qrc resource file is a static binary resource link. You cannot do it dynamically. However, you can do something like this from your code
#include <QProcessEnvironment>
...
somefunc(){
QString env = qgetenv("SOME_VAR");
QString filepath = env + "/path/to/file";
...
}
Rcc does not support such functionality. You can use qmake's "substitutes" (still undocumented?) feature instead.
test.pro
myqrc.input = myqrc.in
myqrc.output = myqrc.qrc
QMAKE_SUBSTITUTES += myqrc
myqrc.in
<file>$$(ANOTHER_PROJECT_DIR)/file</file>
Basically, "substitutes" is a builtin preprocessor capable of evaluating/expanding "qmake"-expressions (plus !!IF / !!ELSE / !!ENDIF conditional).
commonLib is a collection of Files used for some other Targets declared in sibling folders which are then added to the parent CMakeLists.txt via add_subdirectory(). commonLib contains foo.h and foo.ui (which is translated to ui_foo.h by AUTOUIC)
otherLib includes foo.h from commonLib.
It feels like I am missing something obvious.
Is it necessary to use something like target_link_libraries?
Can I add the autogen folder of commonLib to the include folders of otherLib? (with target_include_directories(commonLib PRIVATE ${AUTOGEN_FOLDER_OF_otherLib}) )
How do I make sure commonLib is autogen-ed before otherLib?
Please let me know if there is information missing for understanding the problem.
I am using cmake-converter to convert existing .sln files to CMakeLists.txt.
I assumed finding success with using target properties like:
* AUTOGEN_TARGET_DEPENDS
* AUTOGEN_BUILD_DIR
but I failed.
commonLib contains following code:
find_package(Qt5 REQUIRED COMPONENTS Widgets)
set_target_properties(${PROJECT_NAME} PROPERTIES
AUTOUIC ON
)
otherLib contains following code:
add_dependencies(${PROJECT_NAME}
commonLib
)
I expected CMake to successfully generate the ui_foo.h from commonLib (which it actually does in the folder commonLib_autogen/include_) and then use ui_foo.h for compilation with otherLib.
Resulting Errormessage is:
d:\path\to\otherLib\../otherLib/foo.h(6): fatal error C1083: Cannot open include file: 'ui_foo.h': No such file or directory [D:\build_dir_of\otherLib\otherLib.vcxproj]
The Problem was the use of
# include "ui_foo.h"
in the header (foo.h). Moving the include to the foo.cpp file and forward declaring the Ui::FooBar like this:
namespace Ui { class FooBar; }
resolved it.
This is a follow up of doxygen generated documentation with auto-generated links to qt project ,
also covered in the Blog here
Added tagfiles:
TAGFILES = qtcore.tags=http://doc.qt.io/qt-5/ qtgui.tags=http://doc.qt.io/qt-5/ \
qtwidgets.tags=http://doc.qt.io/qt-5/ qtxml.tags=http://doc.qt.io/qt-5/ \
qtnetwork.tags=http://doc.qt.io/qt-5/
GENERATE_TAGFILE = mytags
Crosscheck, as an example this here works: http://doc.qt.io/qt-5/qtcore.tags
Nevertheless I do not see any links for Qt classes (I would d expect QString to be a link)
What am I doing wrong? Btw, would something like \copydoc QString::toInt work then?
Have you checked the location of your .tags files?
A .tags file is like an index mapping symbols to documentation relative links. This is why you specify both the path to the tagfile and the actual documentation URL where symbols are documented (which, by the way, can also be a local path to Qt's docs).
In other words you should specify:
TAGFILES = path/to/a/tags/file=URL
You can find these .tags files inside Qt directory (usually in QT_DIR/doc/html).
It may be a good idea to copy them inside your project directory in order to avoid using an absolute path. So if you have the following project structure:
myproject/
Doxyfile
src/
doc/
html/
qt/
qt.tags
Then your Doxyfile should contain:
TAGFILES = doc/qt/qt.tags=http://doc.qt.io/qt-5/
All the references to Qt symbols inside your docs will be then linked in the html output generated by Doxygen.
Also, the GENERATE_TAGFILE tag is only useful if you want to link to your docs from another project.
(this is using Premake5 alpha binary available for download on website)
I'm trying to port my existing VS solution over to using premake5.
It uses MS style precompiled headers(stdafx.h/stdafx.cpp).
When I specify this is my test project:
pchheader "stdafx.h"
pchsource "stdafx.cpp"
It does set the project to using precompiled headers, but it is not setting stdafx.cpp to generate precompiled headers(/Yc). Instead all the files in the project are trying to use(/Yu) and nobody is generating the PCH. So it does not build..
I'm guessing this does works somehow, what black magic am I missing here?
Here is my entire premake5 file for reference
-- premake5.lua
solution "Cloud"
configurations { "Debug", "Release", "Final" }
platforms { "Win32_AVX2", "Win64_AVX2"}
location "premake"
flags{"MultiProcessorCompile", "ExtraWarnings", "FatalCompileWarnings", "FatalLinkWarnings", "FloatFast"}
startproject "Cloud"
vectorextensions "AVX2"
filter { "platforms:Win32" }
system "Windows"
architecture "x32"
filter { "platforms:Win64" }
system "Windows"
architecture "x64"
filter "configurations:Debug"
defines { "DEBUG" }
flags { "Symbols" }
filter "configurations:Release"
defines { "NDEBUG" }
flags{"Symbols"}
optimize "Speed"
filter "configurations:Final"
defines { "NDEBUG" }
flags{"LinkTimeOptimization"}
optimize "Speed"
group "app"
--primary executable
project "Cloud"
location "../src_test/cloud"
kind "ConsoleApp"
language "C++"
targetdir "..//%{cfg.buildcfg}"
pchheader "stdafx.h"
pchsource "stdafx.cpp"
vpaths{
{["src/pch/*"] = "../src_test/cloud/stdafx.*"},
{["src/*"] = "../src_test/cloud/**.cpp"},
{["module/*"] = "../src_test/cloud/Module*.h"},
{["core/*"] = "../src_test/cloud/Core*.h"},
{["headers*"] = "../src_test/cloud/*.h"},
--{["src_c/*"] = "../src_test/cloud/**.c"}
}
files { "../src_test/cloud/*.h", "../src_test/cloud/*.c", "../src_test/cloud/*.cpp", "../src_test/cloud/*.hpp" }
One related question: how do I disable precompiled header usage on specific files within a project? Some of my files will not build if the PCH is included, so I have manually disabled them in the existing solution/projects.
Thanks!
It's probably because pchsource requires a file path (like files) Since your stdafx.cpp is not in the same directory as your script, Premake does not find it. Try using pchsource "../src_test/cloud/stdafxcpp" instead, it should fix the problem.
Also I see that you don't add "../src_test/cloud/" as an include directory, so that means that your pch header will be included using relative path, right ? If so, you'll need to update pchheader to reflect that. Due to the way Visual Studio works, you need to set pchheader as it appears in your cpp files. E.g. if in your cpp files you have #include "../src_test/cloud/stdafx.h" you need to use this in Premake: pchheader "../src_test/cloud/stdafx.h".
And finally, to deactivate precompiled headers on certain files, you can use filters:
-- deactivate precompiled headers for C files
filter "files:**.c"
flags { "NoPCH" }
I am changing a script from premake 4 to premake 5 and I had some troubles to deactivate pch on a specific file with :
filter "files:myfile.cpp"
flags { "NoPCH" }
It was disabling pch on the whole project and not on a specific file.
But it was because pchsource and pchheader were defined after the filtering.
When we flag a file with no PCH, pchsource and pchheader have to be defined first.
I have a Qt widget C++ class that loads a ui file created in Qt Creator. The header and the source file for the class live in two separate directories. I have trouble instructing cmake/automoc to find the header for the class. cmake recognizes it needs to moc the C++ file but it cannot find the analogous header.
Is there something I can do to help cmake find the files?
Everything works fine if both the cpp and the header file are in the same directory. This only comes up when the headers are elsewhere.
My directory structure is
project
src
include
Foo
Bar.h
lib
Foo
Bar.cpp
forms
Bar.ui
In src/include/Foo/Bar.h I have:
// Bar.h
#include <QtWidgets/QWidget>
namespace Ui { class Bar; }
class Bar : public QWidget {
Q_OBJECT
...
}
In src/Foo/Bar.cpp file:
#include "Foo/Bar.h"
#include "moc_Bar.cpp"
#include "ui_Bar.h"
My CMakeLists.txt in src/lib/Foo is set up as follows:
# there is a project() call at the root that defines PROJECT_SOURCE_DIR
set(PUBLIC_HEADERS_DIR ${PROJECT_SOURCE_DIR}/src/include)
# Pick up public library headers
include_directories(${PUBLIC_HEADERS_DIR})
# Pick up private headers in library dir
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
# Set up Qt
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Core REQUIRED)
find_package(Qt5Gui REQUIRED)
find_package(Qt5Widgets REQUIRED)
include_directories(${Qt5Core_INCLUDE_DIRS})
include_directories(${Qt5Gui_INCLUDE_DIRS})
include_directories(${Qt5Widgets_INCLUDE_DIRS})
add_definitions(${Qt5Widgets_DEFINITIONS})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
# Set up Qt forms/resources
qt5_wrap_ui(UI_OUT_FILES forms/Bar.ui)
qt5_add_resources(RESOURCE_FILE resources.qrc)
# Library cpp and header files
set(CORE_CPP_FILES Bar.cpp)
set(LIB_CPP_FILES ${LIB_CPP_FILES} ${CORE_CPP_FILES} ${UI_OUT_FILES} ${RESOURCE_FILE})
set(LIB_HEADER_FILES ${PUBLIC_HEADERS_DIR}/Foo/Bar.h)
# Build library
add_library(Foo SHARED ${LIB_CPP_FILES} ${LIB_HEADER_FILES})
target_link_libraries(Foo ${Qt5Widgets_LIBRARIES})
When I run cmake, I get the following error:
AUTOGEN: error: /automoc/src/lib/Foo/Bar.cpp The file includes the moc file "moc_Bar.cpp", but could not find header "Bar{.h,.hh,.h++,.hm,.hpp,.hxx,.in,.txx}" in /automoc/src/lib/Foo/
You have to wrap your header files manually.
Put it into your CMakeLists.txt:
file(GLOB HEADERS_TO_MOC src/include/Foo/ *.h)
qt5_wrap_cpp(PROCESSED_MOCS
${HEADERS_TO_MOC}
TARGET Foo
OPTIONS --no-notes) # Don't display a note for the headers which don't produce a moc_*.cpp
target_sources(Foo PRIVATE ${PROCESSED_MOCS}) # This adds generated moc cpps to target
Real example of this approach
https://github.com/paceholder/nodeeditor/blob/master/CMakeLists.txt#L133
I find the workarounds for this can be simplified by just leaving AUTOMOC to its own devices. Here's what I do (which works for all of our supported CMake versions, currently 3.2...3.17):
Remove the #include "moc_Bar.cpp" line(s) from file(s) Bar.cpp
Add the external (to the current directory) header files as PRIVATE sources for the target:
set(CMAKE_AUTOMOC True)
target_sources(Foo PRIVATE
${CMAKE_SOURCE_DIR}/src/include/Foo/Bar.h
${CMAKE_SOURCE_DIR}/src/include/Foo/Baz.h)
AUTOMOC will create a Foo_autogen output directory when it MOCs the files in question. moc_Bar.cpp and moc_Baz.cpp will be created in a randomly-named ABDEADBEEF subdirectory, and a mocs_compilation.cpp file will be created with content like the following:
// This file is autogenerated. Changes will be overwritten.
#include "ABDEADBEEF/moc_Bar.cpp"
#include "ABDEADBEEF/moc_Baz.cpp"
That file gets compiled and linked in with the final output of the target.
With CMAKE_AUTOMOC globally set True, each target will also receive its own target_autogen directory, though nothing will be generated there in targets that don't have any MOC'able classes. Still, it may be better to set the AUTOMOC target property only on the target(s) that need it:
set_property(TARGET Foo PROPERTY AUTOMOC ON)
The AUTOMOC process can even be told to avoid scanning certain source files (headers, actually), to avoid it doing unnecessary work at build time. To do that, set the SKIP_AUTOMOC property directly on the relevant files:
set_property(SOURCE Bar.h PROPERTY SKIP_AUTOMOC ON)
That will prevent moc from being run in an attempt to generate a moc_Bar.cpp for that header, if one isn't needed. (moc will typically recognize that it isn't needed and quickly skip over the header anyway, but perhaps projects with very large headers or a large number of non-Qt headers might see some benefits from not scanning all of them unnecessarily.)