expected unqualified-id on oneapi tbb12
230628-expected unqualified-id
eton@230628 在编译supra基于debian12 Qt5.15 tbb12 libtbb12/stable,now 2021.8.0-2 amd64
的时候遇到下面的问题。 一直找不到实际的问题原因,指导发现下面几个github的链接,原来是符号冲突导致的。
1. resolve solution
1. 添加QT_NO_KEYWORDS
到编译选项中;
TARGET_COMPILE_DEFINITIONS(SUPRA_GUI
PRIVATE ${SUPRA_Lib_DEFINES}
${CAMPVIS_DEFINITIONS} NODE_EDITOR_STATIC QT_NO_KEYWORDS)
ref:
2. 将qt中的关键字替换为宏定义
signal:
替换为Q_SIGNALS
slots:
替换为Q_SLOTS
emit
替换为Q_EMIT
因为上面的内容
It tells Qt not to define the moc keywords signals, slots, and emit, because these names will be used by a 3rd party library, e.g. Boost. Then to continue using Qt signals and slots with the no_keywords flag, simply replace all uses of the Qt moc keywords in your sources with the corresponding Qt macros Q_SIGNALS (or Q_SIGNAL), Q_SLOTS (or Q_SLOT), and Q_EMIT.
ref:
3. 重新编译,因为supra中涉及到使用第三方库NodeEdit,这个也使用了Qt所以也需要做setp02的替换。
for i in `find ./ -name "*.hpp"` ; do
sed s/signals:/Q_SIGNALS:/g -i $i && \
sed s/slots:/Q_SLOTS:/g -i $i && \
sed s/emit:/Q_EMIT:/g -i $i;
done
2. process step
1. g++ -E /usr/include/oneapi/tbb/flow_graph.h > a.h
查看实际生成的文件到底是否存在语法问题;
合并头文件得到的问题代码截取部分如下,其实可以看到是没有语法问题的。
namespace d1 {
# 190 "/usr/include/oneapi/tbb/profiling.h"
inline void create_itt_sync(void* , const char* , const char* ) {}
inline void call_itt_notify(notify_type , void* ) {}
inline void call_itt_task_notify(notify_type , void* ) {}
# 226 "/usr/include/oneapi/tbb/profiling.h"
struct event {
event(const std::string &) { }
void emit() { }
static void emit(const std::string &) { }
};
}
但是这里学习到了namespace的注入功能
# 20 "/usr/include/oneapi/tbb/detail/_namespace_injection.h"
namespace tbb {}
namespace oneapi {
namespace tbb = ::tbb;
}
目标是将::tbb
等价于::oneapi::tbb
这样就可以兼容以前没有oneapi时候对tbb的命名空间的使用了.
ref:
2. 分析C++中到底'qualified'是什么意思
有人做如下翻译,这样理解相对容易
非受限id(Unqualified-id)
广义化的标识符(identifier)。它可以是前面的任何一种或者析构函数的名称(比如Date或者List<T, T, N>)
受限id(qualified-id)
用一个类名或者名字空间对一个unqualified-id进行限定,或者使用全局作用域解析运算符::进行限定
这种名称可以是多次限定的
例子:::X,S::x,Array::y,::N::A :😒
ref: https://en.cppreference.com/w/cpp/language/qualified_lookup
3. search below info in bing.
oneapi/tbb/profiling.h:229:15: error: expected unqualified-id before ‘)’ token
get the resolution finally.
error message:
/usr/include/oneapi/tbb/profiling.h:229:15: error: expected unqualified-id before ‘)’ token
229 | void emit() { }
| ^
/usr/include/oneapi/tbb/profiling.h:231:22: error: expected unqualified-id before ‘const’
231 | static void emit(const std::string &) { }
| ^~~~~
/usr/include/oneapi/tbb/profiling.h:231:22: error: expected ‘)’ before ‘const’
231 | static void emit(const std::string &) { }
| ^~~~
| )
3. 当前问题产生的实际分析
-
Qt代码中signals, slots, emit其实都是宏定义的关键字,
"qobjectdefs.h"
中对与signals, slots, emit的解析最后都是empty,也就是最后macro在解析的时候如果遇到emit这个字符串,那么如果前面存在Qt的头引用,那么就会出现
# define emit
这样后面emit关键字变为‘NULL’这样就不符合C++的语法了,因为函数定义需要一个NAME ; -
Recurrence issues
创建如下文件:
$ cat abc.cc
void fun(){}
void emit(){}
void fun3(){}
利用g++ -c进行编译
$ g++ -Demit='' -c abc.cc
abc.cc:2:11: error: expected unqualified-id before ‘)’ token
2 | void emit(){}
| ^
- 问题完整的复现,finish.
Appendix
full error log.
FAILED: src/GraphicInterface/CMakeFiles/SUPRA_GUI.dir/SUPRA_GUI_autogen/mocs_compilation.cpp.o
/usr/bin/g++ -DHAVE_BEAMFORMER -DHAVE_BEAMFORMER_MINIMUM_VARIANCE -DHAVE_CUDA -DHAVE_CUDA_CUBLAS -DHAVE_CUFFT -DHAVE_DEVICE_IGTL_OUTPUT -DHAVE_DEVICE_METAIMAGE_OUTPUT -DHAVE_DEVICE_TRACKING_IGTL -DHAVE_DEVICE_TRACKING_SIM -DHAVE_DEVICE_ULTRASOUND_SIM -DNODE_EDITOR_STATIC -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -I/home/eton/00-src/build-supra-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/GraphicInterface -I/home/eton/00-src/supra/src/GraphicInterface -I/home/eton/00-src/build-supra-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/GraphicInterface/SUPRA_GUI_autogen/include -I/home/eton/00-src/supra/src/GraphicInterface/SUPRA_GUI -I/home/eton/00-src/build-supra-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/GraphicInterface/NodeEditor_install/include -I/home/eton/00-src/build-supra-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/GraphicInterface/NodeEditor/include -I/home/eton/00-src/supra/src/GraphicInterface/private -I/include -I/home/eton/00-src/supra/src/SupraLib -I/home/eton/00-src/supra/src/SupraLib/utilities/jsoncpp -I/usr/include/openigtlink -isystem /home/eton/Qt/5.15.2/gcc_64/include -isystem /home/eton/Qt/5.15.2/gcc_64/include/QtWidgets -isystem /home/eton/Qt/5.15.2/gcc_64/include/QtGui -isystem /home/eton/Qt/5.15.2/gcc_64/include/QtCore -isystem /home/eton/Qt/5.15.2/gcc_64/./mkspecs/linux-g++ -DQT_QML_DEBUG -fopenmp -g -fPIC -std=gnu++11 -MD -MT src/GraphicInterface/CMakeFiles/SUPRA_GUI.dir/SUPRA_GUI_autogen/mocs_compilation.cpp.o -MF src/GraphicInterface/CMakeFiles/SUPRA_GUI.dir/SUPRA_GUI_autogen/mocs_compilation.cpp.o.d -o src/GraphicInterface/CMakeFiles/SUPRA_GUI.dir/SUPRA_GUI_autogen/mocs_compilation.cpp.o -c /home/eton/00-src/build-supra-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/GraphicInterface/SUPRA_GUI_autogen/mocs_compilation.cpp
In file included from /usr/include/oneapi/tbb/spin_mutex.h:23,
from /usr/include/oneapi/tbb/flow_graph.h:26,
from /usr/include/tbb/flow_graph.h:17,
from /home/eton/00-src/supra/src/SupraLib/SupraManager.h:21,
from /home/eton/00-src/build-supra-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/GraphicInterface/SUPRA_GUI_autogen/EWIEGA46WW/../../../../../supra/src/GraphicInterface/parameterWidget.h:3,
from /home/eton/00-src/build-supra-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/GraphicInterface/SUPRA_GUI_autogen/EWIEGA46WW/moc_parameterWidget.cpp:10,
from /home/eton/00-src/build-supra-Desktop_Qt_5_15_2_GCC_64bit-Debug/src/GraphicInterface/SUPRA_GUI_autogen/mocs_compilation.cpp:6:
/usr/include/oneapi/tbb/profiling.h:229:15: error: expected unqualified-id before ‘)’ token
229 | void emit() { }
| ^
/usr/include/oneapi/tbb/profiling.h:231:22: error: expected unqualified-id before ‘const’
231 | static void emit(const std::string &) { }
| ^~~~~
/usr/include/oneapi/tbb/profiling.h:231:22: error: expected ‘)’ before ‘const’
231 | static void emit(const std::string &) { }
| ~^~~~~
| )