正确的方法是包含一个与预编译的二进制文件和手动编译的二进制文件不同的头文件

时间:2016-11-15 09:25:08

标签: c++ linux cmake include debian

所以我有一个使用OpenBLAS的程序,我使用cmake来制作它。

问题在于我希望它能够在两种不同情况下顺利编译:

  1. 对于Linux系统,比如说Debian,可以安装一个带有libopenblas的预编译apt-get install libopenblas,这对我的程序运行良好。这是因为我有include:

    #include <openblas/cblas.h>
    
  2. 现在这个选项适用于测试而不是真正的交易。如果与OpenBLAS的用户编译版本一起使用,我的程序的性能会更好,因为OpenBLAS对每台计算机的编译都是不同的(取决于处理器)。但是如果你想玩这个程序,这个预编译的版本是好的。

    1. 对于任何人自己编译的版本,OpenBLAS安装的结构是:

      ├── bin
      ├── include
      │   ├── cblas.h
      │   ├── f77blas.h
      │   ├── lapacke_config.h
      │   ├── lapacke.h
      │   ├── lapacke_mangling.h
      │   ├── lapacke_utils.h
      │   └── openblas_config.h
      └── lib
          ├── libopenblas.a -> libopenblas_haswellp-r0.2.19.a
          ├── libopenblas_haswellp-r0.2.19.a
          ├── libopenblas_haswellp-r0.2.19.so
          ├── libopenblas.so -> libopenblas_haswellp-r0.2.19.so
          └── libopenblas.so.0 -> libopenblas_haswellp-r0.2.19.so
      
    2. 如您所见,没有名为“openblas”的目录,这意味着我的包含应该是:

      #include <cblas.h>
      

      但是这很危险,因为文件cblas.h不仅适用于OpenBLAS,而且可以从其他BLAS实现中获得。这导致文件可用,但我需要的功能openblas_set_num_threads(int num_threads);不可用。因此,如果我默认将目录openblas添加到我的cmake的包含列表中,如果用户没有OpenBLAS的自定义安装,则可能包含错误的文件。

      所以我的问题是:你如何正确处理这个问题,如果如果预编译版本的OpenBLAS不存在,那么就做正确的包含openblas目录?

      如果您需要更多详细信息,请与我们联系。

1 个答案:

答案 0 :(得分:1)

所以我找到的解决方案是在找到本地编译库时在cmake中创建一个DEFINE

if(${foundOpenBLAS})
    message("I found OpenBLAS that you compiled.")
    TARGET_LINK_LIBRARIES(mylibs -L"${OpenBLASPath}/lib")
else()
    message("I couldn't find OpenBLAS that you compiled, so I'm assuming that you have it installed in your system.")
    add_definitions(-DOPENBLAS_FROM_SYSTEM)
endif()

现在在C ++代码中,我们这样做:

#ifdef OPENBLAS_FROM_SYSTEM
#include <openblas/cblas.h>
#else
#include "include/cblas.h"
#endif

第一个版本是找不到OpenBLAS的时候,它是默认的Debian包含的。另一种情况是,如果找到OpenBLAS。这将包括正确的文件。