Skip to content

Commit

Permalink
[SystemZ][z/OS] Add z/OS customization file (llvm#111182)
Browse files Browse the repository at this point in the history
On z/OS, the location of the system libraries and side decks (aka
equivalent to libc, etc) are not in a predefined location. The system
does have a default location but sysadmins can change this and
frequently do. See the -mzos-hlq* options we have for z/OS.

To avoid every user needing to specify these -mzos-hlq* options, we
added support for a system install default config file that is always
read independent of the usual config file. The compiler will read this
customization config file before reading the usual config files.

The customization file is called clang.cfg and is located in:
- the etc dir within the compiler installation dir.
- or specified by the CLANG_CONFIG_PATH env var. This env var can either
be a directory or the fill path name of the file.
  • Loading branch information
perry-ca authored Jan 7, 2025
1 parent 8557a57 commit 57b80e8
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 1 deletion.
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,11 @@ class Driver {
/// \returns true if error occurred.
bool loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx);

/// Tries to load options from customization file.
///
/// \returns true if error occurred.
bool loadZOSCustomizationFile(llvm::cl::ExpansionContext &);

/// Read options from the specified file.
///
/// \param [in] FileName File to read.
Expand Down
37 changes: 36 additions & 1 deletion clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,34 @@ void Driver::CreateOffloadingDeviceToolChains(Compilation &C,
//
}

bool Driver::loadZOSCustomizationFile(llvm::cl::ExpansionContext &ExpCtx) {
if (IsCLMode() || IsDXCMode() || IsFlangMode())
return false;

SmallString<128> CustomizationFile;
StringRef PathLIBEnv = StringRef(getenv("CLANG_CONFIG_PATH")).trim();
// If the env var is a directory then append "/clang.cfg" and treat
// that as the config file. Otherwise treat the env var as the
// config file.
if (!PathLIBEnv.empty()) {
llvm::sys::path::append(CustomizationFile, PathLIBEnv);
if (llvm::sys::fs::is_directory(PathLIBEnv))
llvm::sys::path::append(CustomizationFile, "/clang.cfg");
if (llvm::sys::fs::is_regular_file(CustomizationFile))
return readConfigFile(CustomizationFile, ExpCtx);
Diag(diag::err_drv_config_file_not_found) << CustomizationFile;
return true;
}

SmallString<128> BaseDir(llvm::sys::path::parent_path(Dir));
llvm::sys::path::append(CustomizationFile, BaseDir + "/etc/clang.cfg");
if (llvm::sys::fs::is_regular_file(CustomizationFile))
return readConfigFile(CustomizationFile, ExpCtx);

// If no customization file, just return
return false;
}

static void appendOneArg(InputArgList &Args, const Arg *Opt) {
// The args for config files or /clang: flags belong to different InputArgList
// objects than Args. This copies an Arg from one of those other InputArgLists
Expand Down Expand Up @@ -1284,11 +1312,18 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) {
}

// Otherwise, use the real triple as used by the driver.
llvm::Triple RealTriple =
computeTargetTriple(*this, TargetTriple, *CLOptions);
if (Triple.str().empty()) {
Triple = computeTargetTriple(*this, TargetTriple, *CLOptions);
Triple = RealTriple;
assert(!Triple.str().empty());
}

// On z/OS, start by loading the customization file before loading
// the usual default config file(s).
if (RealTriple.isOSzOS() && loadZOSCustomizationFile(ExpCtx))
return true;

// Search for config files in the following order:
// 1. <triple>-<mode>.cfg using real driver mode
// (e.g. i386-pc-linux-gnu-clang++.cfg).
Expand Down
1 change: 1 addition & 0 deletions clang/test/Driver/Inputs/config-zos/clang.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-DABC=123
1 change: 1 addition & 0 deletions clang/test/Driver/Inputs/config-zos/def.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-DDEF=456
1 change: 1 addition & 0 deletions clang/test/Driver/Inputs/config-zos/tst/def.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-DDEF=456
17 changes: 17 additions & 0 deletions clang/test/Driver/config-zos.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// REQUIRES: shell
// REQUIRES: systemz-registered-target

// RUN: unset CLANG_NO_DEFAULT_CONFIG
// RUN: rm -rf %t && mkdir %t

// RUN: mkdir -p %t/testbin
// RUN: mkdir -p %t/etc
// RUN: ln -s %clang %t/testbin/clang
// RUN: echo "-DXYZ=789" >%t/etc/clang.cfg
// RUN: %t/testbin/clang --target=s390x-ibm-zos -c -### -no-canonical-prefixes %s 2>&1 | FileCheck -DDIR=%t %s
// RUN: %t/testbin/clang --target=s390x-ibm-zos -c -### -no-canonical-prefixes --no-default-config %s 2>&1 | FileCheck -check-prefix=NOCONFIG %s
//
// CHECK: Configuration file: [[DIR]]/etc/clang.cfg
// CHECK: "-D" "XYZ=789"
// NOCONFIG-NOT: Configuration file: {{.*}}/etc/clang.cfg
// NOCONFIG-NOT: "-D" "XYZ=789"
23 changes: 23 additions & 0 deletions clang/test/Driver/config-zos1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// REQUIRES: shell
// REQUIRES: systemz-registered-target

// RUN: unset CLANG_NO_DEFAULT_CONFIG

// RUN: export CLANG_CONFIG_PATH=%S/Inputs/config-zos
// RUN: %clang --target=s390x-ibm-zos -c -### %s 2>&1 | FileCheck %s
// CHECK: Configuration file: {{.*}}/Inputs/config-zos/clang.cfg
// CHECK: "-D" "ABC=123"

// RUN: export CLANG_CONFIG_PATH=%S/Inputs/config-zos/def.cfg
// RUN: %clang --target=s390x-ibm-zos -c -### %s 2>&1 | FileCheck %s -check-prefix=CHECK-DEF
// CHECK-DEF: Configuration file: {{.*}}/Inputs/config-zos/def.cfg
// CHECK-DEF: "-D" "DEF=456"

// RUN: export CLANG_CONFIG_PATH=%S/Inputs/config-zos/Garbage
// RUN: not %clang --target=s390x-ibm-zos -c -### %s 2>&1 | FileCheck %s -check-prefix=CHECK-ERR
// CHECK-ERR: error: configuration file '{{.*}}/Inputs/config-zos/Garbage' cannot be found

// The directory exists but no clang.cfg in it
// RUN: export CLANG_CONFIG_PATH=%S/Inputs/config-zos/tst
// RUN: not %clang --target=s390x-ibm-zos -c -### %s 2>&1 | FileCheck %s -check-prefix=CHECK-ERRDIR
// CHECK-ERRDIR: error: configuration file '{{.*}}/Inputs/config-zos/tst/clang.cfg' cannot be found

0 comments on commit 57b80e8

Please sign in to comment.