Doxygen call graph is not correct even though the preprocessing is correct - doxygen

I have a function something like below. I run doxygen -d Preprocessor and check the preprocessed code and function2() is excluded. However, I still see the function2() in the call graph.
Configuration
Doxygen version: 1.9.1 (ef9b20ac7f8a8621fcfc299f8bd0b80422390f4b)
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
CALL_GRAPH = YES
HAVE_DOT = YES
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_ANON_NSPACES = YES
Function
void function(void)
{
function1();
#ifdef filtered
function2();
#endif
}

Related

Doxygen references inside a template class inside a namespace

In the following minimal example, I have a template class in a namespace. The description of each member refers to another member.
/// #brief My namespace
namespace template_test
{
template <int param_v>
class TemplateClass
{
public:
/// #brief \ref template_test::TemplateClass::func2() <- OK
int func1() { return 1; }
/// #brief \ref func1() <- unable to resolve
int func2() { return 2; }
};
class InstanceClass
{
TemplateClass<5> m_templ_class;
};
} // namespace template_test
At this example, I get the error
unable to resolve reference to 'func1()' for \ref command
One possible solution would be to always reference to entire signature including the namespace template_test::TemplateClass::... like at func1(). But I find this quite confusing and if you change the namespace once, you have to refactor the entire documentation.
I am particularly surprised by the following observations:
It works without problems if the template class is in the main namespace.
template <int param_v>
class TemplateClass
{
public:
/// #brief \ref func2() <- OK
int func1() { return 1; }
/// #brief \ref func1() <- OK
int func2() { return 2; }
};
/// #brief My namespace
namespace template_test
{
class InstanceClass
{
TemplateClass<5> m_templ_class;
};
} // namespace template_test
It works without problems if no template is used.
/// #brief My namespace
namespace test
{
class NoTemplateClass
{
public:
/// #brief \ref func2() <- OK
int func1() { return 1; }
/// #brief \ref func1() <- OK
int func2() { return 2; }
};
class InstanceClass
{
NoTemplateClass m_no_templ_class;
};
} // namespace test
How does this particular behavior occur when a template class is inside a namespace?
Is there an easier way than specifying namespace and class name for each reference?
Regarding this posting, EXTRACT_ALL is set to YES.
ETA:
As soon as I remove the
class InstanceClass
{
TemplateClass<5> m_templ_class;
};
it's possible to create the links to both functions within the TemplateClass.
Difference with default Doxyfile
# Difference with default Doxyfile 1.9.5 (2f6875a5ca481a69a6f32650c77a667f87d25e88)
PROJECT_NAME = ${PROJECT_NAME}
OUTPUT_DIRECTORY = ${DOCS_OUTPUT_DIRECTORY}
STRIP_FROM_PATH = ${PROJECT_SOURCE_DIR}
TOC_INCLUDE_HEADINGS = 0
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
CASE_SENSE_NAMES = YES
SORT_MEMBER_DOCS = NO
WARN_AS_ERROR = YES
WARN_LOGFILE = ${DOXYGEN_WARN_LOG_FILE}
INPUT = ${INPUTS}
FILE_PATTERNS = ${FILE_PATTERNS}
RECURSIVE = YES
EXCLUDE_PATTERNS = *.txt
EXAMPLE_RECURSIVE = YES
HTML_OUTPUT = _doxygen
HTML_EXTRA_STYLESHEET = ${SOURCE_DIR}/tools/doxygen/doxygen-awesome.css
USE_MATHJAX = YES
MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest
MATHJAX_EXTENSIONS = TeX/AMSmath \
TeX/AMSsymbols
SEARCHENGINE = NO
GENERATE_LATEX = NO
LATEX_CMD_NAME = latex
XML_OUTPUT = _doxygen/xml
MACRO_EXPANSION = YES
PREDEFINED = TSM_USE_VFC_UNITS
DIRECTORY_GRAPH = NO
DOT_IMAGE_FORMAT = svg
INTERACTIVE_SVG = YES
DOTFILE_DIRS = .
PLANTUML_JAR_PATH = /usr/share/plantuml/plantuml.jar
DOT_GRAPH_MAX_NODES = 350
As Albert wrote in the comments, it works without warning/error with Doxygen version 1.9.6. In this respect, this is the actual solution to the problem.

creating a Vulkan Instance in version 1.3.224 doesn't work and results in an Error VK_ERROR_INCOMPATIBLE_DRIVER on Apple M1

Hello I am new to Vulkan and c++.
I am following a tutorial on Vulkan for Visual-Studio and stuck at creating a Vulkan Instance. Through a lot of googling I found out that the error -9 (VK_ERROR_INCOMPATIBLE_DRIVER) is based on the Vulkan Version 1.3, me using MacOS and how it implements the MoltenVk or must be included or something else like that.
There it got too complicated for me.
I have tried to search through the documentations and now I don't really even understand what MoltenVk is or how I even tried to include Vulkan with cmake in my project.
I may found a solution on [here] and on stackoverflow (Why does vkCreateInstance return "VK_ERROR_INCOMPATIBLE_DRIVER" on MacOS despite vulkan supported GPU and up to date driver?) but I am not able to implement/understand it. Maybe somebody can explain it or tell me how to implement it?.
The Site said I should put something like that in
std::vector<const char*>
extNames.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME);
extNames.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
VkInstanceCreateInfo inst_info = {};
ins_info.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
inst_info.enabledExtensionCount = static_cast<uint32_t>(extNames.size());
inst_info.ppEnabledExtensionNames = extNames.data();
I have tried it that way and with some deviations in the vk_device.cpp file without any success.
My Project basically looks like this:
Project
--.vscode
--bin
->Project.exe
--build
--CMakeFiles
--libs
--SDL
--src
--Vk_base
->vk_base.h
->vk_device.cpp
->main.cpp
->CMakeList.txt
vk_base.h:
#include <vulkan/vulkan.h>
struct VulkanContext {
VkInstance instance;
};
VulkanContext* initVulkan();
vk_device.cpp:
#include "vk_base.h"
#include <iostream>
bool initVulkanInstance(VulkanContext* context) {
VkApplicationInfo appInfo = {};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "Vulkan App";
appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.pEngineName = "No Engine";
appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
appInfo.apiVersion = VK_VERSION_1_0;
VkInstanceCreateInfo createInfo = {VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO};
createInfo.pApplicationInfo = &appInfo;
createInfo.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; // MAC OS SPECIFIC
//createInfo.enabledExtensionCount = static_cast<uint32_t>(extNames.size()); // MAC OS SPECIFIC
//createInfo.ppEnabledExtensionNames = extNames.data(); // MAC OS SPECIFIC
VkResult creation_result = vkCreateInstance(&createInfo, 0, &context->instance);
std::cout << creation_result << std::endl;
return true;
}
VulkanContext* initVulkan() {
VulkanContext* context = new VulkanContext();
if (initVulkanInstance(context) != VK_SUCCESS) {
throw std::runtime_error("failed to create instance!");
}
return context;
}
main.cpp
#include <iostream>
#include <SDL.h>
#include "vk_base/vk_base.h"
bool handleMessage() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_QUIT:
return false;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) {
return false;
}
break;
}
}
}
int main() {
SDL_Init(SDL_INIT_VIDEO);
SDL_Window *_window;
_window = SDL_CreateWindow("Game Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 700, 500, SDL_WINDOW_RESIZABLE);
SDL_Event e;
bool quit = false;
while (!quit) {
while(SDL_PollEvent(&e) != 0){
if(e.type == SDL_QUIT){
quit = true;
}
}
}
VulkanContext* context = initVulkan();
SDL_DestroyWindow(_window);
SDL_Quit();
return 0;
}
and my Cmakefile to create the Project in the build folder with the command : cmake ../ -GXcode ( I have tried it with -GXcode and without)
CMakeLists.txt:
#project name
project(Project)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
set(SOURCE_FILES src/main.cpp src/vk_base/vk_device.cpp)
#find SDL2
add_subdirectory(libs/SDL)
#find Vulkan
find_package(Vulkan REQUIRED)
#vulkan executebl
add_executable(Project ${SOURCE_FILES})
target_include_directories(Project PUBLIC libs/SDL/include)
target_link_libraries(Project PUBLIC SDL2-static)
target_link_libraries(Project PUBLIC Vulkan::Vulkan)
target_link_libraries(Project PUBLIC ${Vulkan_LIBRARIES})
Thank you for reading and sry for my bad english:)
if there are misspellings in it, it is probably not the cause of the problem and just a typo from me on this thread :p
if you are not comfortable with C++, steer away from Vulkan. One will teach you exactly the wrong lessons about the other. Vulkan is low-level API, and shows you how you should not be programming C++ in 98 % of the time.
Apple does not support Vulkan. They have their own API Metal. MoltenVK is a library that attempts to translate Vulkan function calls to Metal calls.
This API translation does not match 1:1, so the MoltenVK wrapper is not a conformant Vulkan implementation. You need to waive that it is not conformant, and that you know of and will avoid triggering the limitations:
https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VK_KHR_portability_subset
https://github.com/KhronosGroup/MoltenVK/blob/master/Docs/MoltenVK_Runtime_UserGuide.md#known-moltenvk-limitations
You waive the Vulkan conformance by adding VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR bit to the Instance creation:
#ifdef __APPLE__
createInfo.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
#endif //__APPLE__
VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR is part of a Vulkan extension, so that extension needs to be enabled before using the bit, per standard Vulkan rules:
#ifdef __APPLE__
extNames.push_back( VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME );
#endif //__APPLE__
createInfo.enabledExtensionCount = static_cast<uint32_t>(extNames.size());
createInfo.ppEnabledExtensionNames = extNames.data();

Doxygen is not generating calls for functions out of scope

Is it possible to Doxygen to generate calls to a functions that are out of INPUT scope? (For C language)
I mean, lets assume following code:
#include <someHeader.h>
void func(void)
{
functionFromHeader();
}
I would like to have functionFromHeader listed in references field within the generated field, even if the someHeader.h is not listed in INPUT field in config file.
Is there any config that could generate such calls?
EDIT:
Version of doxygen: 1.8.15
Configuration elements changed due default config:
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_ALL = YES
EXTRACT_PRIVATE = YES
EXTRACT_STATIC = YES
EXTRACT_LOCAL_METHODS = YES
HIDE_UNDOC_MEMBERS = YES
STRICT_PROTO_MATCHING = YES
WARN_LOGFILE = warn.log
RECURSIVE = YES
SOURCE_BROWSER = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
GENERATE_TREEVIEW = YES
GENERATE_LATEX = NO
GENERATE_XML = YES
MACRO_EXPANSION = YES
INCLUDE_PATH = somePath
SKIP_FUNCTION_MACROS = NO
GENERATE_TAGFILE = YES
CLASS_DIAGRAMS = NO
HIDE_UNDOC_RELATIONS = NO
CALL_GRAPH = YES
CALLER_GRAPH = YES
DOT_PATH = .\graphviz\bin\
DOTFILE_DIRS = .\dots
DOT_GRAPH_MAX_NODES = 10000
MAX_DOT_GRAPH_DEPTH = 1
DOT_CLEANUP = NO

Preprocessor defines and macros for m68k?

We are failing a build under Debian's testing/build infrastructure for m68k:
config.h:29:3: error: #error "IS_LITTLE_ENDIAN is set, but __BYTE_ORDER__ does not equal __ORDER_LITTLE_ENDIAN__"
# error "IS_LITTLE_ENDIAN is set, but __BYTE_ORDER__ does not equal __ORDER_LITTLE_ENDIAN__"
The fix is easy, but I need to know the preprocessor defines for the platform. I don't have a machine with the architecture, so I can't dump them with gcc -dM -E - </dev/null | sort.
Could someone please provide the preprocessor output for the m68k?
If you're willing to kill time, you could build a cross-compiler for that platform. If you only care about that one specific flag, try adding this test to your configure.ac:
#include <stdint.h>
enum {
ENDIAN_UNKNOWN,
ENDIAN_BIG,
ENDIAN_LITTLE,
ENDIAN_BIG_WORD, /* Middle-endian, Honeywell 316 style */
ENDIAN_LITTLE_WORD /* Middle-endian, PDP-11 style */
};
int endianness(void)
{
union
{
uint32_t value;
uint8_t data[sizeof(uint32_t)];
} number;
number.data[0] = 0x00;
number.data[1] = 0x01;
number.data[2] = 0x02;
number.data[3] = 0x03;
switch (number.value)
{
case UINT32_C(0x00010203): return ENDIAN_BIG;
case UINT32_C(0x03020100): return ENDIAN_LITTLE;
case UINT32_C(0x02030001): return ENDIAN_BIG_WORD;
case UINT32_C(0x01000302): return ENDIAN_LITTLE_WORD;
default: return ENDIAN_UNKNOWN;
}
}

userfunc condition for detecting mobile device

Since TYPO3 7 the condition 'device' and 'useragent' are deprecated. No I'm looking for a userFunc to use as a condition for detecting mobile devices. My aim is to hide or to show some special pages on mobile devices.
I used the extension 'contexts_wurfl' for a while but I guess that there should be 'smaller solutions'.
Thanks for any help.
You can accomplish this with TypoScript using the PAGE Object.
The code below shows you how to execute your own code before executing something else (like the template engine/content rendering etcetera).
page.01 = USER_INT
page.01 {
userFunc = TYPO3\MyExt\Utility\MobileDeviceUtility->detectMobileDevice
}
And in code:
<?php
namespace TYPO3\MyExt\Utility;
class MobileDeviceUtility {
/**
* Is Mobile Device
*
* #return boolean
*/
static public function isMobileDevice() {
// calculates if the user agent is on a mobile device
return TRUE;
}
/**
* Detect Mobile Device
*
* #param string $content
* #param array $conf
* #return void
*/
static public function detectMobileDevice($content, array $conf = NULL) {
global $TSFE;
if (self::isMobileDevice()
&& (boolean) $TSFE->page['mycustom_device_checkbox']
) {
// do something
}
}
}
OR otherwise you should create your own condition [YourVendor\YourPackage\YourCondition = var1 = value1, var2 != value2, ...].
If you would like to avoid writing a custom user function the globalString function of Typo3 can still be used in the later versions of Typo3 to access the useragent and other information like this:
[globalString = IENV:HTTP_USER_AGENT = *<User-Agent>*]
# Statements here will only affect browsers with the useragent matching <User-Agent>
[else]
# Statements here will only affect browsers with the useragent not matching <User-Agent>
[end]
Detailed documentation for conditions using globalStringcan be found here.
A Full list of variables that can be used with the globalString function can be found here.
To execute different typoscript for mobile and stationary devices I found the following snippet to be working for Typo3 8.7 LTS and 9.5 LTS:
[globalString = IENV:HTTP_USER_AGENT = *Android*]||[globalString = IENV:HTTP_USER_AGENT = *iPhone*]||[globalString = IENV:HTTP_USER_AGENT = *Mobile*]||[globalString = IENV:HTTP_USER_AGENT = *Windows Phone*]
# Statements for mobile devices only
[else]
# Statements for stationary devices only
[end]