Linux下编译IFC++及Qt示例时遇TBB相关编译错误求助
解决IFC++ Qt示例编译时Qt宏与TBB的冲突问题
问题背景
在Linux环境编译IFC++主库时,手动在IfcPlusPlus/CMakeLists.txt末尾添加TBB依赖配置后主库编译成功:
find_package(TBB REQUIRED) target_link_libraries(IfcPlusPlus PUBLIC TBB::tbb)
但编译SimpleViewerExampleQt示例时,执行命令:
cmake -DIFCPP_SOURCE_DIR=../../ .. && make
出现TBB头文件的语法错误,核心是emit函数被Qt宏干扰;尝试添加target_compile_definitions(SimpleViewerExampleQt PUBLIC QT_NO_KEYWORDS)后,又出现Qt元对象系统的activate调用匹配错误。
核心原因
- Qt默认定义
emit宏,会将代码中所有emit替换为空,导致TBB头文件里的emit()函数变成(),触发语法错误。 - 全局启用
QT_NO_KEYWORDS会禁用Qt信号槽的所有关键字(emit/signals/slots),但示例依赖moc生成的代码依赖这些关键字逻辑,因此出现activate调用不匹配的问题。
解决方案
方案1:局部临时禁用emit宏(推荐)
无需全局修改Qt配置,仅在引入TBB相关头文件的代码块中临时取消emit宏定义,完成后恢复:
#pragma push_macro("emit") #undef emit // 引入会间接包含TBB的头文件,比如示例中的<execution> #include <execution> #pragma pop_macro("emit")
针对报错路径,修改IfcPlusPlus/src/ifcpp/model/StatusCallback.h,将<execution>的包含用上述代码包裹即可。
方案2:针对特定源文件单独禁用emit宏
在示例的CMakeLists.txt中,给依赖TBB的源文件单独添加QT_NO_EMIT编译定义(仅禁用emit宏,不影响signals/slots):
# 列出所有涉及TBB依赖的源文件 set(TBB_DEPENDENT_SOURCES src/main.cpp src/gui/TabReadWrite.cpp ) foreach(SOURCE ${TBB_DEPENDENT_SOURCES}) set_source_files_properties(${SOURCE} PROPERTIES COMPILE_DEFINITIONS "QT_NO_EMIT") endforeach()
方案3:在IFC++主库CMake中传递编译定义
修改主库的CMakeLists.txt,确保TBB依赖的同时,给引用主库的Qt项目自动传递QT_NO_EMIT定义:
find_package(TBB REQUIRED) target_link_libraries(IfcPlusPlus PUBLIC TBB::tbb) # 仅当引用项目为Qt项目时启用该定义 target_compile_definitions(IfcPlusPlus PUBLIC $<$<BOOL:${QT_FOUND}>:QT_NO_EMIT>)
验证
修改配置后重新执行示例编译命令,即可正常完成编译。
内容的提问来源于stack exchange,提问作者Makogan
相关产品推荐
相关产品推荐

