matlab mex clang C++ 11 thread - >未定义的符号错误

use*_*504 5 matlab xcode symbols clang mex

目标:我想使用Xcode 4.6在Matlab mex文件(R2013a)中使用C++ 11的线程STL

我修改了〜/ .matlab/R2013a/mexopts.sh

        CC='clang++'   # was llvm-gcc-4.2
        CXX='clang++'   # was llvm-g++-4.2
        MACOSX_DEPLOYMENT_TARGET='10.8'   # was 10.5. C++11 is supported >=10.7
        CXXFLAGS="$CXXFLAGS -std=gnu++11 -stdlib=libc++"   # additional flags
Run Code Online (Sandbox Code Playgroud)

没有C++ 11功能的普通mex文件编译得很好.此外,编译器很好地检测到STL,但链接失败除外.

>> mex mextest.cpp

Undefined symbols for architecture x86_64:
"std::__1::__thread_struct::__thread_struct()", referenced from:                                      
    void* std::__1::__thread_proxy<std::__1::tuple<void (*)()> >(void*) in mextest.o                        
"std::__1::__thread_struct::~__thread_struct()", referenced from:                            
    void* std::__1::__thread_proxy<std::__1::tuple<void (*)()> >(void*) in mextest.o                        
"std::__1::__thread_local_data()", referenced from:                              
    void* std::__1::__thread_proxy<std::__1::tuple<void (*)()> >(void*) in mextest.o                      
"std::__1::__throw_system_error(int, char const*)", referenced from:                      
    _mexFunction in mextest.o                   
"std::__1::thread::join()", referenced from:                    
    _mexFunction in mextest.o                            
"std::__1::thread::~thread()", referenced from:                    
    _mexFunction in mextest.o    
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

    mex: link of ' "mextest.mexmaci64"' failed.

Error using mex (line 206)
Unable to complete successfully.
Run Code Online (Sandbox Code Playgroud)

实际的源代码如下所示.细节并不重要,因为它在Matlab R2013 WINDOWS版本中使用Visual Studio 2012 Express编译得很好.使用"clang ++ -std = gnu ++ 11 -stdlib = libc ++ clangtest.cpp"编译了一个等效的cpp.所以,至少,代码中没有逻辑错误(我不是说它是安全代码.它只是一个测试.)

#include "mex.h"
#include <thread>
#include <stdio.h>

int count_thread1 = 0;
int count_thread2 = 0;

void hello()
{
    count_thread2 = 0;
    for(int i=0; i<=10000; i++){
        for (int j=1;j<=20000;j++){
            count_thread2 = i-j-1;
        }
        count_thread2++;
        printf("2: %d , %d\n", count_thread1, count_thread2); // Not sure if printf is thread-safe in Matlab. But it works in this particular example
    }
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
    count_thread1 = 0;
    std::thread t(hello);
    for (int i=1;i<=10000;i++)
    {
        for (int j=1;j<=20000;j++){
            count_thread1 = -i+j-1;
        }
        count_thread1++;
        mexPrintf("1: %d , %d\n", count_thread1, count_thread2);
    }
    mexPrintf("\n");
    t.join();
    mexPrintf("Done\n");
}
Run Code Online (Sandbox Code Playgroud)

好像我必须替换一些包含目录和/或库目录.应修改哪种选项?

谢谢.

Mat*_* B. 5

该错误是由于编译反对-stdlib=libc++但链接反对-lstdc++.您可以通过以下两种方式之一修复它:

  1. 修复它mexopts.sh.最激烈有效的解决方案.位于~/.matlab/${MATLAB_VERSION}/mexopts.sh,它确定所有编译器选项.只需找到/替换所有stdc ++到c ++.

  2. 拼布解决方案:简单地添加-lc++到尾部CXXLIBS.我不确定链接对标准库的多个版本的影响是什么,但似乎有效.在mex调用中,添加参数CXXLIBS="\$CXXLIBS -lc++".

作为次要问题,我相信你完全覆盖了它的价值CXXFLAGS; 你必须$像我上面的库一样逃避符号.