18.1.1. OpenSHMEM 封装编译器

oshcc, oshcxx, oshc++, oshfort, shmemcc, shmemcxx, shmemc++, shmemfort — OpenSHMEM封装编译器

18.1.1.1. 语法

oshcc [--showme | --showme:compile | --showme:link] ...

oshcxx [--showme | --showme:compile | --showme:link] ...

oshc++ [--showme | --showme:compile | --showme:link] ...

oshfort [--showme | --showme:compile | --showme:link] ...

shmemcc [--showme | --showme:compile | --showme:link] ...

shmemcxx [--showme | --showme:compile | --showme:link] ...

shmemc++ [--showme | --showme:compile | --showme:link] ...

shmemfort [--showme | --showme:compile | --showme:link] ...

18.1.1.2. 选项

以下选项适用于所有包装器编译器:

  • --showme: 该选项有多个变体形式(见下文)。所有变体都不会调用底层编译器,而是显示如果未使用--showme时底层编译器将被调用的方式。基础--showme选项会输出编译程序时实际执行的命令行。

    注意

    如果在命令行传递了非文件名参数,--showme选项将不会显示任何额外标志。例如,"oshcc --showmeoshcc --showme my_source.c都会显示所有包装器提供的标志。但oshcc --showme -v只会显示底层编译器名称和-v参数。

  • --showme:compile: 输出原本会传递给底层编译器的编译标志。

  • --showme:link: 输出原本会传递给底层编译器的链接器标志。

  • --showme:command: 输出底层的编译器命令(可能包含一个或多个标记)。

  • --showme:incdirs: 输出一个以空格分隔(但未经修饰)的目录列表,这些目录是包装器编译器提供给底层编译器以指示相关头文件所在位置的。

  • --showme:libdirs: 输出一个以空格分隔(但不含其他修饰)的目录列表,这些目录是包装器编译器提供给底层链接器用于指示相关库文件位置的路径。

  • --showme:libs 输出一个以空格分隔(但不含其他修饰)的库名称列表,这些库是包装器编译器用于链接应用程序的。例如:mpi open-pal util

  • --showme:version: 输出Open MPI的版本号。

  • --showme:help: 输出简短的帮助信息。

有关可通过oshcc传递的其他选项,请参阅底层编译器的man手册页。

18.1.1.3. 描述

从概念上讲,这些命令的作用非常简单:透明地将编译/链接OpenSHMEM程序所需的编译器与链接器标志添加到用户命令行中,然后调用底层编译器实际执行该命令。

因此,这些命令常被称为"包装器"编译器,因为它们实际上并不直接编译或链接应用程序;它们仅负责添加命令行标志并调用后端编译器。

18.1.1.4. 背景

Open MPI 为多种语言提供了封装编译器:

  • oshcc, shmemcc: C语言

  • oshc++, oshcxx, shmemc++, shmemcxx`:: C++

  • oshfort, shmemfort: Fortran语言

针对各种语言的包装编译器是完全相同的;它们可以互换使用。提供不同的名称仅是为了保持向后兼容性。

18.1.1.5. Fortran 注意事项

OpenSHMEM的Fortran包装器编译器(oshfortshmemfort)能够编译并链接使用任意/全部OpenSHMEM Fortran绑定的应用程序。

但请注意,Fortran编译器可能需要额外的命令行选项来强制使用特定的Fortran方言。例如,在某些版本的IBM XLF编译器中,如果底层Fortran编译器是xlf90,则可能需要-qfixed选项来编译固定格式的Fortran源文件。

最后请注意,如果OpenSHMEM层未内置Fortran支持,oshfort将无法运行,并在使用时返回错误。

18.1.1.6. 概述

oshccshmemcc 是底层C编译器的便捷封装器。编译OpenSHMEM程序需要链接特定的OpenSHMEM库,这些库可能不在ld(1)的标准搜索目录中。此外,通常还需要包含可能不在标准位置的头文件。

oshccshmemcc 会将它们的参数连同 OpenSHMEM 程序所需的 -I-L-l 选项一起传递给底层的 C 编译器。

对于所有其他语言包装器编译器也是如此。

OpenSHMEM团队强烈建议使用包装编译器,而非手动链接到OpenSHMEM库。这种方式允许OpenSHMEM的具体实现变更时,无需强制修改用户Makefile中的链接指令。实际上,包装编译器所使用的标志和库的具体组合取决于OpenSHMEM的配置和构建方式;这些值在同一版本OpenSHMEM的不同安装中可能会发生变化。

事实上,由于这些包装器只是底层编译器的薄壳封装,几乎没有任何强有力的理由使用oshcc。当无法直接使用包装器时,应使用--showme:compile--showme:link选项来确定包装器原本会使用哪些编译标志。例如:

shell$ cc -c file1.c `shmemcc --showme:compile`

shell$ cc -c file2.c `shmemcc --showme:compile`

shell$ cc file1.o file2.o `shmemcc --showme:link` -o my_oshmem_program

18.1.1.7. 注意事项

可以使包装器编译器支持多库架构。也就是说,根据指定的编译器标志(例如在Linux上使用GNU编译器时,看到-m32与看到-m64可能会使用不同的库路径),所指定的库和包含文件可能会有所不同。这不是标准构建中的默认行为,但可以激活(例如,在提供32位和64位支持的二进制包中)。更多信息可以在这里找到

18.1.1.8. 文件

包装器编译器在调用底层编译器之前插入到命令行的字符串存储在由OpenSHMEM创建并安装到$pkgdata/NAME-wrapper-data.txt的文本文件中,其中:

  • $pkgdata 通常是 $prefix/share/openmpi

  • $prefix 是 OpenSHMEM 的顶级安装目录

  • NAME 是包装器编译器的名称(例如, $pkgdata/shmemcc-wrapper-data.txt

通常无需编辑这些文件,但可以通过检查它们来深入了解包装器在命令行中添加了哪些标志。

18.1.1.9. 环境变量

默认情况下,包装器使用配置OpenSHMEM时选择的编译器。这些编译器要么是由Open MPI的"configure"脚本自动发现的,要么是用户在调用configure之前通过CCCXX和/或FC环境变量指定的。此外,configure可能还选择了特定于编译器的其他参数。

这些值可以通过编辑包含此配置信息的文本文件(参见FILES部分)或通过设置形式为oshmem_value的特定环境变量来选择性覆盖。

有效的值名称包括:

  • CPPFLAGS: 调用预处理器(C或C++)时添加的标志

  • LDFLAGS: 调用链接器时添加的标志(适用于C、C++或Fortran)

  • LIBS: 调用链接器(C、C++或Fortran)时添加的库

  • CC: C编译器

  • CFLAGS: C编译器标志

  • CXX: C++ 编译器

  • CXXFLAGS: C++编译器标志

  • FC: Fortran编译器

  • FCFLAGS: Fortran编译器标志