Andrew Moa Blog Site

使用xmake编译C/C++项目

原来习惯了在Windows下使用cmake+vcpkg编译C/C++程序,但是vcpkg有个缺点,每次更新都需要从github下载源码编译库文件。像qt那样的大型库,每次光是编译动不动就浪费一整天时间实在耗不起,更别说DNS导致的连接问题了。

先梳理下需求,对C/C++包管理器的要求主要以下3点:

  1. 支持gtk+、qt、wxWidgets、cgal、vtk等常用库。
  2. 支持跨平台和IDE集成,或者支持CMake。
  3. 及时更新。

能满足条件的除了vcpkg就只剩xrepo了。 xrepo是xmake自带的包管理器,xmake1是一个新兴的C/C++构建工具。这篇文章尝试使用xmake+repo替代cmake+vcpkg,看能否满足现阶段C/C++程序的编译需求。

1. 安装xmake

按照官方文档2的指导,这里用posershell命令直接下载安装:

irm https://xmake.io/psget.text | iex

在Windows下执行以上命令,自动安装在C:\Users\[用户名]\xmake路径下。

也可以使用其他方式安装,比如直接从Release 页面下载对应平台的安装包手动安装。

安装完xmake之后xrepo就可以使用了,查看xmake、xrepo的版本:

xmake --version
xrepo --version

cd8eda41c5999fbe3a3714490ad3369c.png

vscode可以安装以下拓展,用于查看和构建xmake项目。

2. 创建项目

可以直接使用xmake的create命令创建项目,默认为C++项目。

xmake create hello_cpp

f122d0c81fc444640af563890205868d.png

也可以增加-l开关指定项目的语言类型。

xmake create -l c hello_c

打开hello_c项目自动生成的xmake.lua文件,后面一大段注释告诉用户怎么配置、构建和安装项目。直接在项目文件夹中执行xmake命令即可编译。

使用vscode安装了拓展的话,也可以通过下方的按钮执行编译命令。

4d7371ad8f240c02d2c5e07b6c104cd2.png

阅读时长4分钟
Andrew Moa

使用pyinstaller打包exe程序

使用qt动态链接库编译出来的可执行程序会依赖一大堆动态链接库文件,想要将本机上编写的程序发布到其他人的计算机上,就需要将依赖的动态链接库文件和可执行程序一起打包发布。打包发布的方法有很多,原理都是一样的,通过压缩程序将可执行程序和依赖文件一起打包压缩成单独的可执行文件,用户执行该可执行文件时自动解压并运行。

常见的打包方案有WinRAR1、7-Zip2等,通过压缩软件的自解压模块制作带脚本的自解压程序,但这些方案有一个共同的缺点,没办法传递命令行参数。本文提供新的思路,通过pyinstaller打包功能,实现qt程序打包,并且通过python实现命令行参数传递。

1. 示例程序

编写一个CGAL程序,调用qt显示面网格。下面的代码参考CGAL文档3并做了一些调整,在程序启动时开启对话框接收文件输入,也可以通过命令行传入网格文件。

#include <CGAL/Simple_cartesian.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/draw_surface_mesh.h>
#include <fstream>
#include <QApplication>
#include <QFileDialog>

typedef CGAL::Simple_cartesian<double> Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Mesh;

int main(int argc, char *argv[])
{
  QApplication app(argc, argv);
  const std::string filename = (argc > 1) ? argv[1] : QFileDialog::getOpenFileName(nullptr, "Open a mesh file", "", "Supported formats (*.off *.stl *.obj *.ply);;OFF format (*.off);;STL format (*.stl);;OBJ format (*.obj);;PLY format (*.ply)").toStdString();
  if (filename.empty())
    return EXIT_FAILURE;

  Mesh sm;
  if (!CGAL::IO::read_polygon_mesh(filename, sm))
  {
    if (filename.substr(filename.find_last_of(".") + 1) == "stl")
      std::cerr << "Invalid STL file: " << filename << std::endl;
    else if (filename.substr(filename.find_last_of(".") + 1) == "obj")
      std::cerr << "Invalid OBJ file: " << filename << std::endl;
    else if (filename.substr(filename.find_last_of(".") + 1) == "ply")
      std::cerr << "Invalid PLY file: " << filename << std::endl;
    else if (filename.substr(filename.find_last_of(".") + 1) == "off")
      std::cerr << "Invalid OFF file: " << filename << std::endl;
    else
      std::cerr << "Invalid file: " << filename << "(Unknown file format.)" << std::endl;
    return EXIT_FAILURE;
  }

  // Internal color property maps are used if they exist and are called
  // "v:color", "e:color" and "f:color".
  auto vcm =
      sm.add_property_map<Mesh::Vertex_index, CGAL::IO::Color>("v:color").first;
  auto ecm =
      sm.add_property_map<Mesh::Edge_index, CGAL::IO::Color>("e:color").first;
  auto fcm = sm.add_property_map<Mesh::Face_index>(
                   "f:color", CGAL::IO::white() /*default*/)
                 .first;

  for (auto v : vertices(sm))
  {
    if (v.idx() % 2)
    {
      put(vcm, v, CGAL::IO::black());
    }
    else
    {
      put(vcm, v, CGAL::IO::blue());
    }
  }

  for (auto e : edges(sm))
  {
    put(ecm, e, CGAL::IO::gray());
  }

  put(fcm, *(sm.faces().begin()), CGAL::IO::red());

  // Draw!
  CGAL::draw(sm);

  return EXIT_SUCCESS;
}

cmake配置文件CMakeLists.txt编写如下,输出的可执行文件名称包含文件夹名、工具链名称、编译器命名和版本等。

阅读时长3分钟
Andrew Moa

Windows下编译rocblas-rocm-6.2.4

之前演示矩阵运算加速的时候本来想尝试一下AMD自家的ROCm,程序编译完运行结果碰到报错:

rocBLAS error: Cannot read D:\example\efficiency_v3\rocm\build\Release\/rocblas/library/TensileLibrary.dat: No such file or directory for GPU arch : gfx1150
 List of available TensileLibrary Files : 

查询官网文档,ROCm不支持Radeon 880M核显(AI H 365w处理器)1。除非自己编译rocblas,否则没法运行。

查了一下网上的教程文章234,没有适配这款核显的,自己开搞吧。

1. 下载工具和源码

需要用到的工具见下表,没有就去官网下载安装。

序号 软件/工具包 版本
1 Visual Studio Community 2022
2 AMD HIP SDK for Windows5 6.2.4
3 Python 3.13
4 Git for Windows 2.7.4
5 Strawberry Perl 5.40.0.1
6 CMake 3.30.1

我的机器上装了vcpkg,除了前两个从官网下载安装之外,后面的都是从vcpkg的downloads\tools目录提取的,将路径添加到环境变量即可。

# 配置工具包路径
$Env:HIP_PATH="C:\Program Files\AMD\ROCm\6.2"
$Env:GIT_BIN_PATH = "D:\vcpkg\downloads\tools\git-2.7.4-windows\bin"
$Env:PERL_PATH = "D:\vcpkg\downloads\tools\perl\5.40.0.1"
$Env:CMAKE_BIN_PATH = "D:\vcpkg\downloads\tools\cmake-3.30.1-windows\cmake-3.30.1-windows-i386\bin"

# 配置系统环境变量
$Env:PATH += ";$Env:HIP_PATH\bin;$Env:GIT_BIN_PATH;$Env:PERL_PATH\perl\site\bin;$Env:PERL_PATH\perl\bin;$Env:PERL_PATH\c\bin;$Env:CMAKE_BIN_PATH"

从Github上下载rocBLASTensile的源码,注意版本和本机安装的AMD HIP SDK版本要一致。这里还要下载补丁文件Tensile-fix-fallback-arch-build.patch,确保可以为不支持的显卡编译内容。

阅读时长8分钟
Andrew Moa