Describe the bug
pcl_linemod_detection and pcl_train_linemod_template are failed build on Windows.
------ ビルド開始: プロジェクト: pcl_linemod_detection, 構成: Release x64 ------
Building Custom Rule C:/pcl-1.11.0/tools/CMakeLists.txt
linemod_detection.cpp
C:\pcl-1.11.0\tools\linemod_detection.cpp(117,1): warning C4996: 'pcl::PointCloud<pcl::PointXYZRGBA>::mapping_': rewrite your code to avoid using this protected field (It will be removed in PCL 1.12)
linemod_detection.obj : error LNK2001: 外部シンボル ""private: struct pcl::RGB __cdecl pcl::filters::Convolution<struct pcl::RGB,struct pcl::RGB>::convolveOneColDense(int,int)" (?convolveOneColDense@?$Convolution@URGB@pcl@@U12@@filters@pcl@@AEAA?AURGB@3@HH@Z)" は未解決です。
linemod_detection.obj : error LNK2001: 外部シンボル ""private: struct pcl::RGB __cdecl pcl::filters::Convolution<struct pcl::RGB,struct pcl::RGB>::convolveOneRowDense(int,int)" (?convolveOneRowDense@?$Convolution@URGB@pcl@@U12@@filters@pcl@@AEAA?AURGB@3@HH@Z)" は未解決です。
C:\pcl-1.11.0\build\bin\pcl_linemod_detection.exe : fatal error LNK1120: 2 件の未解決の外部参照
プロジェクト "pcl_linemod_detection.vcxproj" のビルドが終了しました -- 失敗。
------ ビルド開始: プロジェクト: pcl_train_linemod_template, 構成: Release x64 ------
Building Custom Rule C:/pcl-1.11.0/tools/CMakeLists.txt
train_linemod_template.cpp
C:\pcl-1.11.0\tools\train_linemod_template.cpp(227,1): warning C4996: 'pcl::PointCloud<pcl::PointXYZRGBA>::mapping_': rewrite your code to avoid using this protected field (It will be removed in PCL 1.12)
train_linemod_template.obj : error LNK2001: 外部シンボル ""private: struct pcl::RGB __cdecl pcl::filters::Convolution<struct pcl::RGB,struct pcl::RGB>::convolveOneColDense(int,int)" (?convolveOneColDense@?$Convolution@URGB@pcl@@U12@@filters@pcl@@AEAA?AURGB@3@HH@Z)" は未解決です。
train_linemod_template.obj : error LNK2001: 外部シンボル ""private: struct pcl::RGB __cdecl pcl::filters::Convolution<struct pcl::RGB,struct pcl::RGB>::convolveOneRowDense(int,int)" (?convolveOneRowDense@?$Convolution@URGB@pcl@@U12@@filters@pcl@@AEAA?AURGB@3@HH@Z)" は未解決です。
C:\pcl-1.11.0\build\bin\pcl_train_linemod_template.exe : fatal error LNK1120: 2 件の未解決の外部参照
プロジェクト "pcl_train_linemod_template.vcxproj" のビルドが終了しました -- 失敗。
To Reproduce
Build PCL with enable BUILD_tools on Windows.
Your Environment (please complete the following information):
Why does the CI declare explicitly -DBUILD_tools=OFF? Is it because of VTK being absent on Windows CI?
Seems like the issue originated due to #3971 and needs tools to link to the pcl_filters library
It is not necessary to always link explicitly against pcl_filters, as CMake will add it automatically when another module is added which depends on it.
https://github.com/PointCloudLibrary/pcl/pull/4086#issuecomment-626970603
This shows that #3971 isn't the cause. The issue has been there for longer.
Thanks to @SunBlack
609f9ac:

master:

Clearly, there's some issue pre-existing issue, but another issue has been introduced by #3972, because master has 2 errors related to pcl_modeler which aren't before. #3971 had a similar diff so it could have added a new error (currently unseen) on top of the existing one.
Sorry, seems I was already tired yesterday 609f9ac752a7e1bb2bf3f145a3b2dd61b03d39db is the last commit before #3972 and not before #3971. When I compile now 68aa839d087b5f56cd7b6e693480088aaface749 everything is fine

Thanks, this confirms the issue as related to addition of the a cpp file for the templates. Best of luck @PointCloudLibrary/testers-windows
I'm not sure, but I think the issue is, that we have a templates for a method, but we are using the specialization only for simple method.
Currently it looks so:
// convolution.h
template <typename PointIn, typename PointOut>
class Convolution
{
private:
inline PointOut
convolveOneRowDense (int i, int j);
}
// convolution.hpp
template <typename PointIn, typename PointOut> inline PointOut
Convolution<PointIn, PointOut>::convolveOneRowDense (int i, int j)
{
...
}
template<> pcl::RGB
Convolution<pcl::RGB, pcl::RGB>::convolveOneRowDense (int i, int j);
// convolution.cpp
template<>
pcl::RGB
Convolution<pcl::RGB, pcl::RGB>::convolveOneRowDense(int i, int j)
{
...
}
First of all: The header defines it as inline, but the specialization doesn't have this anymore.
Second: Is it really possible to implement a template specialization when the class is templated and not the method?
First of all: The header defines it as
inline
What happens if the inline in the header is removed?
Second: Is it really possible to implement a template specialization when the class is templated and not the method?
Yes. The rest of the methods are copied from the non-specialized interface.
cppreference, search for template<> void A<int>::h(int) {}
Assuming @SunBlack copied everything as is, we might be missing the template<> pcl::RGB in the function signature of the .cpp version
Oh sorry, the template<> is there - fixed post above.
It has to be something to do with compiler incompatibility since clang and gcc don't complain. Might be something trivial or something missing from MSVC
Second: Is it really possible to implement a template specialization when the class is templated and not the method?
Yes. The rest of the methods are copied from the non-specialized interface.
cppreference, search for
template<> void A<int>::h(int) {}
I discusses this now with a C++ guru at my work and he does not know a rule like this. The section in the documention starts also with When defining a member of an explicitly specialized class template outside the body of the class - so not sure if the standard really want this.
//Edit: Ok, a simple test case works with MSVC.
For me it works to partially undo the commit https://github.com/PointCloudLibrary/pcl/pull/3971/commits/02ad0b6868b89a033e3491d7530148059feccbbc. The inline declaration of the three functions can stay, I removed the convolution.cpp again. But I don't have an error due to multiple declarations of specializations of template member functions in 'convolution'. Although the commit should fix it.
Any progress on the root cause of the bug?
@SergioRAgostinho We can fix this by forcing inline on the templates, which are pretty big. Should we quick-fix this or wait it out a bit more? (2 issues since the release)
Let's quick patch with the inline qualifier for the time being and preserve the issue for Windows. Maybe @larshg can also chime in once the VTK 9.0 support stuff is done.
@OgreTransporter You also have to add inline to the specializations of the functions which were moved to cpp.
I don't have bandwidth to reverse both commits (that's a low priority for me) so PRs are welcome for a temporary patch.
@kunaltyagi I've created a PR #4151
Have the same problem,how to solve?
1>linemod_detection.cpp
2>match_linemod_template.cpp
3>train_linemod_template.cpp
2>E:\Develop\opensources\pcl\tools\match_linemod_template.cpp(122,13): warning C4477: “printf”: 格式字符串“%lu”需要类型“unsigned long”的参数,但可变参数 1 拥有了类型“size_t”
2>E:\Develop\opensources\pcl\tools\match_linemod_template.cpp(122,13): message : 请考虑在格式字符串中使用“%zu”
3>E:\Develop\opensources\pcl\tools\train_linemod_template.cpp(227,1): warning C4996: 'pcl::PointCloud
1>E:\Develop\opensources\pcl\tools\linemod_detection.cpp(117,1): warning C4996: 'pcl::PointCloud
1>linemod_detection.obj : error LNK2001: 无法解析的外部符号 "private: struct pcl::RGB __cdecl pcl::filters::Convolution
1>linemod_detection.obj : error LNK2001: 无法解析的外部符号 "private: struct pcl::RGB __cdecl pcl::filters::Convolution
1>E:\Develop\opensources\pcl\build20200527\bin\pcl_linemod_detection.exe : fatal error LNK1120: 2 个无法解析的外部命令
1>已完成生成项目“pcl_linemod_detection.vcxproj”的操作 - 失败。
2>match_linemod_template.obj : error LNK2001: 无法解析的外部符号 "private: struct pcl::RGB __cdecl pcl::filters::Convolution
2>match_linemod_template.obj : error LNK2001: 无法解析的外部符号 "private: struct pcl::RGB __cdecl pcl::filters::Convolution
2>E:\Develop\opensources\pcl\build20200527\bin\pcl_match_linemod_template.exe : fatal error LNK1120: 2 个无法解析的外部命令
2>已完成生成项目“pcl_match_linemod_template.vcxproj”的操作 - 失败。
3>train_linemod_template.obj : error LNK2001: 无法解析的外部符号 "private: struct pcl::RGB __cdecl pcl::filters::Convolution
3>train_linemod_template.obj : error LNK2001: 无法解析的外部符号 "private: struct pcl::RGB __cdecl pcl::filters::Convolution
3>E:\Develop\opensources\pcl\build20200527\bin\pcl_train_linemod_template.exe : fatal error LNK1120: 2 个无法解析的外部命令
Please apply the patch #4151 while we merge it and release 1.11.1 sometime later.
I have look a little into this, though I'm not that familiar with template stuff. But I can't get it work when using a .cpp file for the implementation part.
So it seems to inline the methods in the h/hpp files are the way to go here.
Please apply the patch #4151
@larshg Thanks for looking into it. It's quite weird because gcc and clang accept separating the specialized function definition from declaration. Apparently, MSVC also supported this in the olden days
All SO answers I find support my hypothesis that separating them into a cpp file shouldn't cause an issue.
Are we missing a library to link to these target? Can you also verify if we're supplying the respective libraries to be linked?
This is a really weird problem. Especially because it behaves differently with the same compiler on different systems.