在Matlab mex文件中编译c ++ 11代码时出错

时间:2014-09-03 16:06:48

标签: c++ linux matlab c++11 mex

我已下载the following code

  

CVPR 2014交叉联合优化代码

     

cvpr2014-iou-code-1.0.zip

     

http://research.microsoft.com/en-us/downloads/e164fe21-ef2b-4e34-98c1-4868968abb06/

我得到的是一个包含两个文件夹的存档,一个名为src/,另一个名为matlab/。我正在运行Linux Fedora 19,我可以在src/编译代码就好了。当我尝试在matlab/中编译代码时出现问题。

自述文件说:

Matlab compilation
------------------
From within Matlab, configure the compiler using "mex -setup", then adjust the
paths in matlab\compile_windows.m or matlab/compile_linux.m scripts and run
either "compile_linux.m" or "compile_windows.m" in the "matlab" directory.

更具体地针对Linux:

Linux
=====

From within Matlab run "mex -setup", then edit the mexopts.sh file and modify
the settings

    CXXFLAGS='-std=c++11 -fopenmp -march=native -D_GNU_SOURCE'
    CXXLIBS="$RPATH $MLIBS -lm -lgomp"
    CXXOPTIMFLAGS='-Ofast -DNDEBUG'

This will enable OpenMP and C++11 and should work from G++ 4.7 onwards.

From the matlab/ directory, call compile_linux to build all mex files.

所以我打开matlab并运行mex -setup。我回答yes问题:

>> mex -setup

    Options files control which compiler to use, the compiler and link command
    options, and the runtime libraries to link against.

    Using the 'mex -setup' command selects an options file that is
    placed in /user/wok/home/.matlab/R2012b and used by default for 'mex'. An options 
    file in the current working directory or specified on the command line 
    overrides the default options file in /user/wok/home/.matlab/R2012b.

    To override the default options file, use the 'mex -f' command
    (see 'mex -help' for more information).

The options files available for mex are:

  1: /opt/matlab2012b/bin/mexopts.sh : 
      Template Options file for building gcc MEX-files


  0: Exit with no changes

Enter the number of the compiler (0-1):
1

Overwrite /user/wok/home/.matlab/R2012b/mexopts.sh ([y]/n)? 
y

/opt/matlab2012b/bin/mexopts.sh is being copied to 
/user/wok/home/.matlab/R2012b/mexopts.sh


**************************************************************************
  Warning: The MATLAB C and Fortran API has changed to support MATLAB 
           variables with more than 2^32-1 elements.  In the near future 
           you will be required to update your code to utilize the new 
           API. You can find more information about this at: 
           http://www.mathworks.com/help/techdoc/matlab_external/bsflnue-1.html
           Building with the -largeArrayDims option enables the new API. 
**************************************************************************

然后我编辑文件/user/wok/home/.matlab/R2012b/mexopts.sh,并按照自述文件中的说明进行操作:

    CXX='g++'
    CXXFLAGS='-ansi -D_GNU_SOURCE'
    CXXFLAGS="$CXXFLAGS -D_FILE_OFFSET_BITS=64"
    CXXFLAGS="$CXXFLAGS -fPIC -pthread"
    CXXLIBS="$RPATH $MLIBS -lm"
    CXXOPTIMFLAGS='-O -DNDEBUG'
    CXXDEBUGFLAGS='-g'

变为:

    CXX='g++'
    CXXFLAGS='-std=c++11 -fopenmp -march=native -D_GNU_SOURCE'
    CXXLIBS="$RPATH $MLIBS -lm -lgomp"
    CXXOPTIMFLAGS='-Ofast -DNDEBUG'
    CXXDEBUGFLAGS='-g'

完成此步骤后,我会打开matlab并修改compile_linux.m以添加Boost的路径:

% You need to have boost 1.49 or higher installed (package libboost-dev on
% most distributions)
%
% Tested on Ubuntu 13.10, Matlab R2012b, gcc 4.8.1

% TODO: this assumes that boost headers are available in /usr/include, as on
% most systems.  If you manually installed boost, please add -I/path/to/boost
mex -v -O ...
    -output mex_voc_optimize -I../src ...
    -I/user/wok/home/Softwares/Boost_1.54/include/boost ...
    mex_voc_optimize.cpp matlab_helpers.cpp ...
    -largeArrayDims

编辑:在Praetorian的第一条评论之后,我添加了-v标志。

最后我运行compile_linux,只是为了获得一长串错误,我已将其缩短并粘贴在下面:

>> compile_linux
-> mexopts.sh sourced from directory (DIR = $PREF_DIR)
   FILE = /user/wok/home/.matlab/R2012b/mexopts.sh
----------------------------------------------------------------
->    MATLAB                = /opt/matlab2012b
->    CC                    = gcc
->    CC flags:
         CFLAGS             = -ansi -D_GNU_SOURCE  -fexceptions -fPIC -fno-omit-frame-pointer -pthread
         CDEBUGFLAGS        = -g
         COPTIMFLAGS        = -O -DNDEBUG
         CLIBS              = -Wl,-rpath-link,/opt/matlab2012b/bin/glnxa64 -L/opt/matlab2012b/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++
         arguments          = 
->    CXX                   = g++
->    CXX flags:
         CXXFLAGS           = -ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread
         CXXDEBUGFLAGS      = -g
         CXXOPTIMFLAGS      = -O -DNDEBUG
         CXXLIBS            = -Wl,-rpath-link,/opt/matlab2012b/bin/glnxa64 -L/opt/matlab2012b/bin/glnxa64 -lmx -lmex -lmat -lm
         arguments          = 
->    FC                    = gfortran
->    FC flags:
         FFLAGS             = -fexceptions -fbackslash -fPIC -fno-omit-frame-pointer
         FDEBUGFLAGS        = -g
         FOPTIMFLAGS        = -O
         FLIBS              = -Wl,-rpath-link,/opt/matlab2012b/bin/glnxa64 -L/opt/matlab2012b/bin/glnxa64 -lmx -lmex -lmat -lm
         arguments          = 
->    LD                    = g++
->    Link flags:
         LDFLAGS            = -pthread -shared -Wl,--version-script,/opt/matlab2012b/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined
         LDDEBUGFLAGS       = -g
         LDOPTIMFLAGS       = -O
         LDEXTENSION        = .mexa64
         arguments          = 
->    LDCXX                 = 
->    Link flags:
         LDCXXFLAGS         = 
         LDCXXDEBUGFLAGS    = 
         LDCXXOPTIMFLAGS    = 
         LDCXXEXTENSION     = 
         arguments          = 
----------------------------------------------------------------


Warning: You are using gcc version "4.8.2".  The version
         currently supported with MEX is "4.4.6".
         For a list of currently supported compilers see: 
         http://www.mathworks.com/support/compilers/current_release/

-> g++ -c  -I../src -I/user/wok/home/Softwares/Boost_1.54/include/boost -I/opt/matlab2012b/extern/include -I/opt/matlab2012b/simulink/include -DMATLAB_MEX_FILE -ansi -D_GNU_SOURCE -fPIC -fno-omit-frame-pointer -pthread  -O -DNDEBUG  "mex_voc_optimize.cpp"

In file included from /usr/include/c++/4.8.2/cstdint:35:0,
                 from mex_voc_optimize.cpp:8:
/usr/include/c++/4.8.2/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
 #error This file requires compiler and library support for the \
  ^
In file included from ../src/lfp.h:18:0,
                 from ../src/voc.h:15,
                 from mex_voc_optimize.cpp:19:
../src/timing.h:15:2: error: ‘chrono’ in namespace ‘std’ does not name a type
  std::chrono::time_point<std::chrono::high_resolution_clock> start_time;
  ^
../src/timing.h: In member function ‘double timer::elapsed_this_period() const’:
../src/timing.h:20:8: error: ‘std::chrono’ has not been declared
   std::chrono::time_point<std::chrono::high_resolution_clock> end_time
        ^
../src/timing.h:20:32: error: ‘std::chrono’ has not been declared
   std::chrono::time_point<std::chrono::high_resolution_clock> end_time

,直到

../src/voc.h:418:31: note: ‘P’ declared here, later in the translation unit
    alpha[k_best] += P(j,k_best);
                               ^
../src/voc.h: In instantiation of ‘std::pair<double, double> voc::prediction_function<TFloat>::compute_objective_c(int) const [with TFloat = double]’:
../src/voc.h:328:56:   required from ‘double voc::prediction_function<TFloat>::compute_objective() const [with TFloat = double]’
mex_voc_optimize.cpp:250:39:   required from here
../src/voc.h:315:17: error: ‘P’ was not declared in this scope
     A_c += P(i,c);
                 ^
../src/voc.h:318:17: error: ‘P’ was not declared in this scope
     D_c += P(i,c);
                 ^

    mex: compile of ' "mex_voc_optimize.cpp"' failed.

Error using mex (line 206)
Unable to complete successfully.

Error in compile_linux (line 9)
mex -O ...

>> 

我尝试编辑代码以删除对chrono的每次调用(针对计时器),然后将unordered_map替换为map等,但这很痛苦。我希望能够在matlab/中编译mex文件,就像我可以编译src/中的c ++代码一样

1 个答案:

答案 0 :(得分:5)

感谢Praetorian的评论,我可以查明问题所在。我在mexopts.sh编辑了错误的行。实际上,CXXFLAGS出现在3个不同的地方,我在第一个地方编辑了旗帜,但是在第二个地方编辑它是必要和充分的(第一个地方是诱饵)。

参见例如:

$ grep -n CXXLIBS /user/wok/home/.matlab/R2012b/mexopts.sh
74:             CXXLIBS="$RPATH $MLIBS -lm"
129:            CXXLIBS="$RPATH $MLIBS -lm"
199:            CXXLIBS="$MLIBS -lstdc++"

所以我编辑了第129行的线。以下几行

        CXX='g++'
        CXXFLAGS='-ansi -D_GNU_SOURCE'
        CXXFLAGS="$CXXFLAGS -fPIC -fno-omit-frame-pointer -pthread"
        CXXLIBS="$RPATH $MLIBS -lm"
        CXXOPTIMFLAGS='-O -DNDEBUG'
        CXXDEBUGFLAGS='-g'

成为

        CXX='g++'
        CXXFLAGS='-std=c++11 -fopenmp -march=native -D_GNU_SOURCE'
        CXXFLAGS="$CXXFLAGS -fPIC -fno-omit-frame-pointer -pthread"
        CXXLIBS="$RPATH $MLIBS -lm -lgomp"
        CXXOPTIMFLAGS='-Ofast -DNDEBUG'
        CXXDEBUGFLAGS='-g'