Repository: visit-dav/visit
Pull request #20388: Cleanup build visit modules
Author: login: biagas
Created: 2025-05-12T23:26:17Z | Merged: 2025-05-22T19:07:21Z

### Description

Resolves #20383, parts of #20386.
Removed `gpl` license and tags from `modules.xml`

Reduced tags in `modules.xml` to only use grouped items and limit groups to 
* `required` (built by default, individual libs in this group can be disabled with `--no-<name>`, e.g. `--no-python`), 
* `optional` (built when requested either individually or via `--optional`), and 
* `extras` (only built when individually requested).

Libraries should only be listed in one of the groups.

Reduced code duplication where possible.


### Type of change

* ~~[ ] Bug fix~~
* ~~[ ] New feature~~
* ~~[ ] Documentation update~~
* [X] Other
build system cleanup

### How Has This Been Tested?

I ran build_visit with various options to ensure correct behavior. I used `--download-only` for quicker testing.

`--no-thirdparty --cmake` : only cmake was downloaded
`--no-python`:  everything in required was downloaded except python
`--optional`: all required and all optional were downloaded
`--optional --no-moab --llvm --mesagl`   All required, all optional except moab, llvm and mesagl were downloaded.
`--hdf5 --silo`: all required, hdf5 and silo were downloaded.


### Checklist:

- [X] I have commented my code where applicable.
- [X] I have updated the release notes.
- [X] I have made corresponding changes to the documentation.
- ~~[ ] I have added debugging support to my changes.~~
- ~~[ ] I have added tests that prove my fix is effective or that my feature works.~~
- ~~[ ] I have confirmed new and existing unit tests pass locally with my changes.~~
- ~~[ ] I have added new baselines for any new tests to the repo.~~
- ~~[ ] I have NOT made any changes to [*protocol* or *public interfaces*][3] in an RC branch.~~



Linked issue #20383: Remove duplicate tags from build_visit  modules.xml
In modules.xml there is an `<optional>` tag and `<group name="optional">` tag.
Both lists should contain the same items, but sometimes when new libraries are added that doesn't happen.
We should look into modifying build_visit script and/or bv_xml_parser.sh so that only one list is needed.
Similar for `<required>` and `<group name="required">` tags.
Linked issue comments: user: login: markcmiller86
created_at: 2025-05-07T19:07:17Z
body: Just wanna capture here some relevant observations from 30 mins looking at the code...
 
1. `<optional>` form is parsed into `xmlp_optlibs` shell variable in `bv_xml_parser.sh`.
2. In `build_visit`, `optlibs` is set to contents of `xmlp_optlibs` shell variable which then drives all build logic via `$"bv_${optlibs[$bv_i]}_XXX` function calls
3. Above two observations mean I was incorrect in that `<optional>` stuff is IGNORED. It isn’t. Your attempt to remove it confirms that.
 
But, then what is the `<group name=”optional”>` stuff for?
 
Well, looking more at `build_visit`, it looks like `xmlp_grouplibs_name` (which is the stuff `<group name=”optional”…>` winds up getting associated with) is used to drive dependency evaluation logic in two places…I think this is to ensure that the command-line arguments to build_visit don’t wind up specifying a set of incompatable dependences.
 
I believe, as I think your original email was aimed at, these two containers for optional information can be combined into one…but the `build_visit` logic for one or the other would have to be adjusted so that the same container is being used in both item 2 in the list above and in the dependency evaluation stuff.
author_association: MEMBER
user: login: biagas
created_at: 2025-05-08T23:14:39Z
body: One piece of functionality  that the two 'optional' lists provide is the ability to have an optional library that is not built unless by specific request (--mesagl --osmesa --mpich).

Any ideas of providing that same functionality without two 'optional' lists?
Or is it okay that '--no-mesagl' and '--no-mpich will need to be added for builds that don't want them?
author_association: CONTRIBUTOR
user: login: brugger1
created_at: 2025-05-12T17:08:49Z
body: I agree that the 2 lists are confusing.

Here are my observations when I added support for building `meson, ninja, xcb, xkbcommon`. I added them to both lists. I wanted them to all be optional so I added coding like the following to all 4 `bv_*.sh` files following the convention I saw in `bv_mesag.sh`.
```
function bv_xcb_initialize
{
    export DO_XCB="no"
}
```
It turns out this doesn't actually appear to turn them off.

I then looked for `bv_mesagl.sh` in `modules.xml` and noticed that it was in the `<optional>` list and not in the `<group name="optional" comment="All optional libraries" enabled="no">` list. I noticed that other libraries that are optional such as `uintah` were also missing from that list.

Based on this I believe that the second list actually controls what libraries are built when `-optional` is specified and not what is in the `bv_*.sh` file. I don't know if this is a bug, but as it currently stands, the second list is needed to control what libraries are part of the `optional` group. I don't know if the first list is needed. Maybe its just a convenient way to specify the list of all the optional modules or maybe its needed to form the list of all the `bv_*.sh` files to process. The other possibility is that it just grabs all the `bv_*.sh` files in the directory and processes them.
author_association: COLLABORATOR
user: login: biagas
created_at: 2025-05-12T17:19:05Z
body: @brugger1 Thank you for adding your observations.  I made similar discoveries. In summary:
1) `optional` and `required` are used to specify all possible libraries.
2) `required` group controls what gets built with `--required` (on by default)
3) `optional` group controls which optional libraries are built with `--optional`.

I have made progress removing the simple 'optional' and 'required' tags, but still need a mechanism for ensuring libraries that should only be built by specific request are still known to the scripts. Think MesaGL, MPICH.
 I'm considering `extra_libs` (or similar) as a new group.

author_association: CONTRIBUTOR
user: login: JustinPrivitera
created_at: 2025-05-12T20:35:23Z
body: > I'm considering `extra_libs` (or similar) as a new group.

the `bonus` list idea makes its return!
author_association: MEMBER

Diff:
diff --git a/src/doc/building_visit/Common_Build_Scenarios.rst b/src/doc/building_visit/Common_Build_Scenarios.rst
index 4bfe97607b1..65711aca868 100644
--- a/src/doc/building_visit/Common_Build_Scenarios.rst
+++ b/src/doc/building_visit/Common_Build_Scenarios.rst
@@ -79,7 +79,7 @@ Uintah reader.
        PAR_COMPILER_CXX=/usr/tce/packages/mvapich2/mvapich2-2.3-gcc-4.9.3/bin/mpicxx \
        PAR_INCLUDE=-I/usr/tce/packages/mvapich2/mvapich2-2.3-gcc-4.9.3/include \
        PAR_LIBS=-lmpl \
-   ./build_visit3_0_1 --required --optional --mesagl --uintah --parallel \
+   ./build_visit3_0_1 --required --optional --mesagl --parallel \
    --no-visit --thirdparty-path /usr/workspace/wsa/visit/visit/thirdparty_shared/3.0.1/toss3 \
    --makeflags -j16
 
@@ -260,7 +260,7 @@ Uintah reader.
        PAR_COMPILER_CXX=/opt/cray/pe/craype/2.5.15/bin/CC \
        PAR_INCLUDE=-I/opt/cray/pe/mpt/7.7.3/gni/mpich-gnu/7.1/include \
        PAR_LIBS="-L/opt/cray/pe/mpt/7.7.3/gni/mpich-gnu/7.1/lib -Wl,-rpath=/opt/cray/pe/mpt/7.7.3/gni/mpich-gnu/7.1/lib -lmpich" \
-    ./build_visit3_0_1 --required --optional --mesagl --uintah --parallel \
+    ./build_visit3_0_1 --required --optional --mesagl --parallel \
     --no-visit --thirdparty-path /project/projectdirs/visit/thirdparty_shared/3.0.1 \
     --makeflags -j8
 
diff --git a/src/doc/dev_manual/CreatingABuildVisItModule.rst b/src/doc/dev_manual/CreatingABuildVisItModule.rst
index d4bf70007e3..e99ae4222e9 100644
--- a/src/doc/dev_manual/CreatingABuildVisItModule.rst
+++ b/src/doc/dev_manual/CreatingABuildVisItModule.rst
@@ -17,6 +17,7 @@ Here is a list of all the functions that will be defined (listed in order of app
 
 bv_foo_initialize
     Initialize any variables controlled by command line options.
+    Only libraries in the ``required`` category should have `DO_FOO` set to `yes` in this function.
 
 bv_foo_enable
     Enables the module (sets `DO_FOO` to `yes`).
@@ -69,7 +70,13 @@ See ``bv_qt.sh`` as an example of allowing system or also an alternate (already
 ``bv_qt_system_qt`` and ``bv_alt_qt_dir`` were added and other functions were modified to support this for qt.
 
 
-Once ``bv_foo.sh`` has been updated appropriately, add the module name to ``bv_support/modules.xml`` under the appropriate categories.
+Once ``bv_foo.sh`` has been updated appropriately, add the module name to ``bv_support/modules.xml`` under the appropriate group.
+The `required` group in ``bv_support/modules.xml`` is for libraries that are required for basic functioning of _VisIt.
+The `optional` group is for most i/o and other non-required support libraries.
+The `explicit` group is for any library (and its dependencies) that should be explicitly requested.
+This could be libraries that are mutually exclusive such as `mesagl` and `osmesa`, or libraries that may not be needed on many systems such as `mpich`, `xcb` or `xkbcommon`.
+The `explicit` group should also be used for any library that has proven to have a problematic build system.
+
 Then run the build_visit script to ensure that your module builds and installs correctly, and that the host profile entry is correct.
 
 
diff --git a/src/resources/help/en_US/relnotes3.5.0.html b/src/resources/help/en_US/relnotes3.5.0.html
index c9272952ded..a6eafed82ab 100644
--- a/src/resources/help/en_US/relnotes3.5.0.html
+++ b/src/resources/help/en_US/relnotes3.5.0.html
@@ -120,6 +120,7 @@
   <li>Fixed a bug where cloning and checking out VisIt could fail silently without providing error messages.</li>
   <li>Added support for building <code>anari</code> to <code>build_visit</code> to allow building VisIt with ANARI renderingsupport.</li>
   <li>Updated VTK build script, <code>bv_vtk.sh</code>, to enable ANARI rendering module in VTK.</li>
+  <li>The following command-line options were removed from the main build_visit script: <code>--all-io, --dbio-only, --nonio and  --advanced</code>.  This was done to simplify maintenance and addition of new modules.  <code>--optional</code> still turns on most optional libraries. <code>--no-thirdparty</code> still turns off the required libraries. Otherwise individual libraries can be enabled/disabled by <code>--</code> or <code>--no</code> syntax e.g. <code>--mpich --no-python</code>.  Please run <code>build_visit --help</code> for more information on available options.</li>
 </ul>
 
 <a name="Dev_changes"></a>
diff --git a/src/tools/dev/scripts/build_visit b/src/tools/dev/scripts/build_visit
index 58216288a13..a3505991035 100755
--- a/src/tools/dev/scripts/build_visit
+++ b/src/tools/dev/scripts/build_visit
@@ -14,6 +14,14 @@
 #   Please visit https://visit-help.llnl.gov to send feedback if you run into
 #   problems so that this script can be improved in the future.
 #
+#   Modifications:
+#     Kathleen Biagas, Mon May 12, 2025
+#     Add support for 'explicit' group (explicitlibs), to make it easier to
+#     list them separately from 'reqlibs' and 'optlibs' when needed.
+#     Where possible, perform work on all groups instead of duplicating the
+#     same code for 'reqlibs', 'optlibs' and 'explicitlibs'.
+#
+# *****************************************************************************
 
 # To create your own modular file, see the docs at
 # //https://visit-sphinx-github-user-manual.readthedocs.io/en/develop/dev_manual/CreatingABuildVisItModule.html
@@ -62,6 +70,7 @@ declare -a reqlibs
 declare -a reqlibs_state
 declare -a optlibs
 declare -a optlibs_state
+declare -a explicitlibs
 declare -a grouplibs_name
 declare -a grouplibs_deps
 declare -a grouplibs_comment
@@ -280,6 +289,7 @@ do
     #copy xmlcontents to global variables
     reqlibs=(`echo "${reqlibs[@]} ${xmlp_reqlibs[@]}" | xargs -n 1 | sort -u | xargs`)
     optlibs=(`echo "${optlibs[@]} ${xmlp_optlibs[@]}" | xargs -n 1 | sort -u | xargs`)
+    explicitlibs=(`echo "${explicitlibs[@]} ${xmlp_explicitlibs[@]}" | xargs -n 1 | sort -u | xargs`)
 
     for (( bv_i = 0; bv_i < ${#xmlp_grouplibs_name[*]}; ++bv_i ))
     do
@@ -304,49 +314,14 @@ do
 done
 
 
-#import functions that that install required visit libraries
-for (( i = 0; i < ${#reqlibs[*]}; ++i ))
-do
-    . "${bv_PREFIX}/bv_${reqlibs[$i]}.sh"
-    verify_required_module_exists ${reqlibs[$i]}
-done
-
-#import functions that support optional visit dependencies
-#import functions that that install required visit libraries
-for (( i = 0; i < ${#optlibs[*]}; ++i ))
-do
-    . "${bv_PREFIX}/bv_${optlibs[$i]}.sh"
-    verify_optional_module_exists ${optlibs[$i]}
-done
-
-
-###################### Grouping libraries
-# The arrays listed below help group VisIt's set of libraries.
-# For example: --all-io uses the iolibs array to determine which modules to enable
-#options = no change, enable, disable
+#import functions that install libraries
 for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
 do
-    group_name=${grouplibs_name[$bv_i]}
-
-    for group_dep in `echo ${grouplibs_deps[$bv_i]}`;
+    for lib in `echo ${grouplibs_deps[$bv_i]}`;
     do
-        #echo "checking $group_name and $group_dep"
-        if [[ "$group_dep" == no-* ]]; then
-            group_dep=${group_dep/no-}
-        fi
-        declare -F "bv_${group_dep}_enable" &>/dev/null
-
-        if [[ $? != 0 ]] ; then
-            error "library ${group_dep} in ${group_name} not valid"
-        fi
-
-        declare -F "bv_${group_dep}_disable" &>/dev/null
-
-        if [[ $? != 0 ]] ; then
-            error "library ${group_dep} in ${group_name} not valid"
-        fi
+        . "${bv_PREFIX}/bv_${lib}.sh"
+        verify_module_exists ${lib}
     done
-
 done
 
 function check_default_args
@@ -424,6 +399,7 @@ function bv_write_unified_file
 
     echo "declare -a reqlibs" >> $OUTPUT_bv_FILE
     echo "declare -a optlibs" >> $OUTPUT_bv_FILE
+    echo "declare -a explicitlibs" >> $OUTPUT_bv_FILE
     echo "declare -a grouplibs_name" >> $OUTPUT_bv_FILE
     echo "declare -a grouplibs_deps" >> $OUTPUT_bv_FILE
     echo "declare -a grouplibs_comment" >> $OUTPUT_bv_FILE
@@ -466,6 +442,7 @@ function bv_write_unified_file
     echo "  parseXmlModuleContents \$license" >> $OUTPUT_bv_FILE
     echo "  reqlibs=(\`echo \"\${reqlibs[@]} \${xmlp_reqlibs[@]}\" | xargs -n 1 | sort -u | xargs\`)" >> $OUTPUT_bv_FILE
     echo "  optlibs=(\`echo \"\${optlibs[@]} \${xmlp_optlibs[@]}\" | xargs -n 1 | sort -u | xargs\`)" >> $OUTPUT_bv_FILE
+    echo "  explicitlibs=(\`echo \"\${explicitlibs[@]} \${xmlp_explicitlibs[@]}\" | xargs -n 1 | sort -u | xargs\`)" >> $OUTPUT_bv_FILE
 
     echo "for (( bv_i = 0; bv_i < \${#xmlp_grouplibs_name[*]}; ++bv_i ))" >> $OUTPUT_bv_FILE
     echo "do" >> $OUTPUT_bv_FILE
diff --git a/src/tools/dev/scripts/bv_support/bv_main.sh b/src/tools/dev/scripts/bv_support/bv_main.sh
index 0017d998a42..d1261aeeeef 100644
--- a/src/tools/dev/scripts/bv_support/bv_main.sh
+++ b/src/tools/dev/scripts/bv_support/bv_main.sh
@@ -285,13 +285,19 @@ function check_opengl_context()
 }
 
 
-# ************************************************************************** #
-#                       Section 1, setting up inputs                          #
-# --------------------------------------------------------------------------- #
-# This section sets up the inputs to the VisIt script.  This is where you can #
-# specify which compiler to use, which versions of the third party libraries, #
-# etc.  Note that this script is really only known to work with gcc.          #
-# *************************************************************************** #
+# *************************************************************************** 
+#                       Section 1, setting up inputs                          
+# --------------------------------------------------------------------------- 
+# This section sets up the inputs to the VisIt script.  This is where you can 
+# specify which compiler to use, which versions of the third party libraries, 
+# etc.  Note that this script is really only known to work with gcc.          
+#
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Process all groups in one loop when feasible, instead of duplicating
+#   logic for 'reqlibs' and 'optlibs' separately.
+#
+# *************************************************************************** 
 
 
 function initialize_build_visit()
@@ -498,18 +504,15 @@ function initialize_build_visit()
     #
     # OPTIONS
     #
-    #initialize required libraries..
-
-    for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
-    do
-        initializeFunc="bv_${reqlibs[$bv_i]}_initialize"
-        $initializeFunc
-    done
+    #initialize all libraries..
 
-    for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
-        initializeFunc="bv_${optlibs[$bv_i]}_initialize"
-        $initializeFunc
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            initializeFunc="bv_${lib}_initialize"
+            $initializeFunc
+        done
     done
 
     export DO_HOSTCONF="yes"
@@ -531,9 +534,6 @@ function initialize_build_visit()
     export DO_PARADIS="no"
     export PREVENT_ICET="no"
     verify="no"
-    export DO_OPTIONAL="yes"
-    export DO_OPTIONAL2="no"
-    export DO_MORE="no"
     export DO_DBIO_ONLY="no"
     export DO_ENGINE_ONLY="no"
     export DO_SERVER_COMPONENTS_ONLY="no"
@@ -610,19 +610,15 @@ function initialize_build_visit()
     fi
     export VISIT_FILE=${VISIT_FILE:-"visit${VISIT_VERSION}.tar.gz"}
 
-    for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
-    do
-        initializeFunc="bv_${reqlibs[$bv_i]}_info"
-        $initializeFunc
-    done
-
-    for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
-        initializeFunc="bv_${optlibs[$bv_i]}_info"
-        $initializeFunc
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            initializeFunc="bv_${lib}_info"
+            $initializeFunc
+        done
     done
 
-
     WRITE_UNIFIED_FILE=""
     VISIT_INSTALLATION_BUILD_DIR=""
     DO_SUPER_BUILD="no"
@@ -700,11 +696,44 @@ function strip_quotes
     echo "${str}"
 }
 
+
+# *************************************************************************** 
+# Function: bv_enable_group
+#
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Modified to test for actual group names and return early if possible.
+#   Don't allow 'explicit' group to be 'enabled'. Print message and exit if so.
+#   Remove test for 'dbio-only'.
+#
+#   Kathleen Biagas, Monday May 19, 2025
+#   Allow --no-thirdparty as a way to disable required group. This preserves
+#   the purpose of the option even though the '--no-thirdparty' group no
+#   longer exists.
+#
+# *************************************************************************** 
+
 function bv_enable_group
 {
     local name=${1/--}
     local match=0
 
+    # don't want to allow enablement of 'explicit' group.
+    if [[ "$name" == "explicit" ]] ; then
+        info "Libraries in group 'explicit' cannot be enabled via '--explicit'. Each desired 'explicit' library should be added separately, e.g. '--llvm --osmesa'."
+        exit
+    fi
+
+    if [[ "$name" == "no-thirdparty" ]] ; then
+        name="no-required"
+    fi
+
+    # can terminate early if $name isn't 'optional' or 'required'.
+    if [[ "$name" != "optional" && "$name" != "required" &&
+          "$name" != "no-required" ]] ; then
+        return 0
+    fi
+
     for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
         #replace | with space
@@ -714,22 +743,20 @@ function bv_enable_group
         do
             if [[ "$group" == "$name" ]]; then
                 echo "executing group $name"
-                if [[ "$group" == "dbio-only" ]]; then
-                    DO_DBIO_ONLY="yes"
-                fi
                 match=1
                 for group_dep in `echo ${grouplibs_deps[$bv_i]}`;
                 do
-                    if [[ "$group_dep" == no-* ]]; then
-                        group_dep=${group_dep/no-}
-                        #info "disabling $group_dep"
-                        initializeFunc="bv_${group_dep}_disable"
-                        $initializeFunc
-                    else
-                        #info "enabling $group_dep"
-                        initializeFunc="bv_${group_dep}_enable"
-                        $initializeFunc
-                    fi
+                    info "bv_enable_group enabling $group_dep"
+                    initializeFunc="bv_${group_dep}_enable"
+                    $initializeFunc
+                done
+            elif [[ "no-$group" == "$name" ]]; then
+                match=1
+                for group_dep in `echo ${grouplibs_deps[$bv_i]}`;
+                do
+                   info "bv_enable_group disabling $group_dep"
+                   initializeFunc="bv_${group_dep}_disable"
+                   $initializeFunc
                 done
             fi
         done
@@ -738,99 +765,83 @@ function bv_enable_group
     return $match
 }
 
+# *************************************************************************** 
+# Function: enable_dependent_libraries
+#
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Process all groups in one loop, instead of duplicating
+#   logic for 'reqlibs' and 'optlibs' separately.
+#
+# *************************************************************************** 
+
 function enable_dependent_libraries
 {
     local depends_on=""
 
-    for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
-        $"bv_${reqlibs[$bv_i]}_is_enabled"
-
-        #if not enabled then skip
-        if [[ $? == 0 ]]; then
-            continue
-        fi
-
-        #enabled library, check dependencies..
-        depends_on=$("bv_${reqlibs[$bv_i]}_depends_on")
-
-        #replace commas with spaces if there are any..
-        depends_on=${depends_on//,/ }
-
-        for depend_lib in `echo $depends_on`;
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
         do
-            $"bv_${depend_lib}_is_enabled"
+            $"bv_${lib}_is_enabled"
+
+            #if not enabled then skip
             if [[ $? == 0 ]]; then
-                error "ERROR: library ${depend_lib} was not set ${reqlibs[$bv_i]} depends on it, please enable"
-                #echo "library ${depend_lib} was not set but another library depends on it, enabling it"
-                #$"bv_${depend_lib}_enable"
+                continue
             fi
-        done
-    done
-
-    for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
-    do
-        $"bv_${optlibs[$bv_i]}_is_enabled"
 
-        #if not enabled then skip
-        if [[ $? == 0 ]]; then
-            continue
-        fi
+            #enabled library, check dependencies..
+            depends_on=$("bv_${lib}_depends_on")
 
-        #enabled library, check dependencies..
-        depends_on=$("bv_${optlibs[$bv_i]}_depends_on")
+            #replace commas with spaces if there are any..
+            depends_on=${depends_on//,/ }
 
-        #replace commas with spaces if there are any..
-        depends_on=${depends_on//,/ }
-
-        for depend_lib in `echo $depends_on`;
-        do
-            $"bv_${depend_lib}_is_enabled"
-            if [[ $? == 0 ]]; then
-                error "ERROR: library ${depend_lib} was not set ${optlibs[$bv_i]} depends on it, please enable"
-                echo "library ${depend_lib} was not set but another library depends on it, enabling it"
-                $"bv_${depend_lib}_enable"
-            fi
+            for depend_lib in `echo $depends_on`;
+            do
+                $"bv_${depend_lib}_is_enabled"
+                if [[ $? == 0 ]]; then
+                    error "ERROR: library ${depend_lib} was not set ${lib} depends on it, please enable"
+                    #echo "library ${depend_lib} was not set but another library depends on it, enabling it"
+                    #$"bv_${depend_lib}_enable"
+                fi
+            done
         done
     done
 }
 
+# *************************************************************************** 
+# Function: initialize_module_variables
+#
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Process all groups in one loop, instead of duplicating
+#   logic for 'reqlibs' and 'optlibs' separately.
+#
+# *************************************************************************** 
 #TODO: enable this feature and remove this from ensure..
 function initialize_module_variables
 {
     info "initializing module variables"
-    for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
-    do
-        $"bv_${reqlibs[$bv_i]}_is_enabled"
 
-        #if not enabled then skip
-        if [[ $? == 0 ]]; then
-            continue
-        fi
-
-        declare -F "bv_${reqlibs[$bv_i]}_initialize_vars" &>/dev/null
-
-        if [[ $? == 0 ]]; then
-            info "initialize module variables for ${reqlibs[$bv_i]}"
-            $"bv_${reqlibs[$bv_i]}_initialize_vars"
-        fi
-    done
-
-    for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
-        $"bv_${optlibs[$bv_i]}_is_enabled"
+        groupname=${grouplibs_name[$bv_i]}
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            $"bv_${lib}_is_enabled"
 
-        #if not enabled then skip
-        if [[ $? == 0 ]]; then
-            continue
-        fi
+            #if not enabled then skip
+            if [[ $? == 0 ]]; then
+                continue
+            fi
 
-        declare -F "bv_${optlibs[$bv_i]}_initialize_vars" &>/dev/null
+            declare -F "bv_${lib}_initialize_vars" &>/dev/null
 
-        if [[ $? == 0 ]]; then
-            info "initialize module variables for ${optlibs[$bv_i]}"
-            $"bv_${optlibs[$bv_i]}_initialize_vars"
-        fi
+            if [[ $? == 0 ]]; then
+                info "initialize module variables for ${lib}"
+                $"bv_${lib}_initialize_vars"
+            fi
+        done
     done
 }
 
@@ -873,133 +884,99 @@ function build_library
     $"bv_${build_lib}_build"
 }
 
+# *************************************************************************** 
+# Function: build_libraries_serial
+#
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Process all groups in one loop, instead of duplicating
+#   logic for 'reqlibs' and 'optlibs' separately.
+#
+# *************************************************************************** 
+
 function build_libraries_serial
 {
-    info "building required libraries"
-    for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
-    do
-        $"bv_${reqlibs[$bv_i]}_is_enabled"
-
-        if [[ $? == 0 ]]; then
-            continue
-        fi
-
-        $"bv_${reqlibs[$bv_i]}_is_installed"
-
-        if [[ $? == 0 ]]; then
-            cd "$START_DIR"
-            build_library ${reqlibs[$bv_i]}
-        else
-            info "${reqlibs[$bv_i]} already installed, skipping"
-        fi
-    done
-
-    info "building optional libraries"
-    for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
-        $"bv_${optlibs[$bv_i]}_is_enabled"
+        groupname=${grouplibs_name[$bv_i]}
+        info "Building ${groupname} libraries"
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            $"bv_${lib}_is_enabled"
 
-        if [[ $? == 0 ]]; then
-            continue
-        fi
+            if [[ $? == 0 ]]; then
+                continue
+            fi
 
-        $"bv_${optlibs[$bv_i]}_is_installed"
+            $"bv_${lib}_is_installed"
 
-        if [[ $? == 0 ]]; then
-            cd "$START_DIR"
-            build_library ${optlibs[$bv_i]}
-        else
-            info "${optlibs[$bv_i]} already installed, skipping"
-        fi
+            if [[ $? == 0 ]]; then
+                cd "$START_DIR"
+                build_library ${lib}
+            else
+                info "${lib} already installed, skipping"
+            fi
+        done
     done
 }
 
+# *************************************************************************** 
+# Function: build_libraries_parallel
+#
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Process all groups in one loop, instead of duplicating
+#   logic for 'reqlibs' and 'optlibs' separately.
+#
+# *************************************************************************** 
+
 function build_libraries_parallel
 {
     #launch all non dependent libraries in parallel..
-    info "building parallel required libraries"
-    for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
-    do
-        $"bv_${reqlibs[$bv_i]}_is_enabled"
-
-        if [[ $? == 0 ]]; then
-            continue
-        fi
-
-        $"bv_${reqlibs[$bv_i]}_is_installed"
-        if [[ $? == 0 ]]; then
-
-            depends_on=$("bv_${reqlibs[$bv_i]}_depends_on")
-            if [[ "$depends_on" == "" ]]; then
-                (cd "$START_DIR" && build_library ${reqlibs[$bv_i]}) &
-            fi
-        else
-            info "${reqlibs[$bv_i]} already installed, skipping"
-        fi
-    done
-
-    wait
 
-    #load the serial ones..
-    for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
-    do
-        $"bv_${reqlibs[$bv_i]}_is_enabled"
-
-        if [[ $? == 0 ]]; then
-            continue
-        fi
-
-        $"bv_${reqlibs[$bv_i]}_is_installed"
-
-        if [[ $? == 0 ]]; then
-            cd "$START_DIR"
-            build_library ${reqlibs[$bv_i]}
-        else
-            info "${reqlibs[$bv_i]} already installed, skipping"
-        fi
-    done
-
-    info "building parallel optional libraries"
-    for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
-        $"bv_${optlibs[$bv_i]}_is_enabled"
+        groupname=${grouplibs_name[$bv_i]}
+        info "Building parallel ${groupname} libraries"
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            $"bv_${lib}_is_enabled"
 
-        if [[ $? == 0 ]]; then
-            continue
-        fi
-        $"bv_${optlibs[$bv_i]}_is_installed"
-        if [[ $? == 0 ]]; then
+            if [[ $? == 0 ]]; then
+                continue
+            fi
 
-            depends_on=$("bv_${optlibs[$bv_i]}_depends_on")
-            if [[ "$depends_on" == "" ]]; then
-                (cd "$START_DIR" && build_library ${optlibs[$bv_i]}) &
+            $"bv_${lib}_is_installed"
+            if [[ $? == 0 ]]; then
+                depends_on=$("bv_${lib}_depends_on")
+                if [[ "$depends_on" == "" ]]; then
+                    (cd "$START_DIR" && build_library ${lib}) &
+                fi
+            else
+                info "${lib} already installed, skipping"
             fi
-        else
-            info "${optlibs[$bv_i]} already installed, skipping"
-        fi
-    done
+        done
 
-    wait
+        wait
 
-    #load serial
-    for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
-    do
-        $"bv_${optlibs[$bv_i]}_is_enabled"
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            $"bv_${lib}_is_enabled"
 
-        if [[ $? == 0 ]]; then
-            continue
-        fi
+            if [[ $? == 0 ]]; then
+                continue
+            fi
 
-        $"bv_${optlibs[$bv_i]}_is_installed"
+            $"bv_${lib}_is_installed"
 
-        if [[ $? == 0 ]]; then
-            cd "$START_DIR"
-            build_library ${optlibs[$bv_i]}
-        else
-            info "${optlibs[$bv_i]} already installed, skipping"
-        fi
+            if [[ $? == 0 ]]; then
+                cd "$START_DIR"
+                build_library ${lib}
+            else
+                info "${lib} already installed, skipping"
+            fi
+        done
     done
-
 }
 
 # *************************************************************************** #
diff --git a/src/tools/dev/scripts/bv_support/bv_qwt.sh b/src/tools/dev/scripts/bv_support/bv_qwt.sh
index 8bb4accb0c2..ced3f9de80b 100644
--- a/src/tools/dev/scripts/bv_support/bv_qwt.sh
+++ b/src/tools/dev/scripts/bv_support/bv_qwt.sh
@@ -1,6 +1,6 @@
 function bv_qwt_initialize
 {
-    export DO_QWT="yes"
+    export DO_QWT="no"
     export USE_SYSTEM_QWT="no"
     export USE_ALT_QWT="no"
     add_extra_commandline_args "qwt" "system-qwt" 0 "Use Qwt found on system"
diff --git a/src/tools/dev/scripts/bv_support/bv_xml_parser.sh b/src/tools/dev/scripts/bv_support/bv_xml_parser.sh
index 382b92c0bed..ed2dff60e6c 100755
--- a/src/tools/dev/scripts/bv_support/bv_xml_parser.sh
+++ b/src/tools/dev/scripts/bv_support/bv_xml_parser.sh
@@ -1,5 +1,13 @@
 #!/bin/bash
 
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Added 'explicitlibs' group.
+#   Removed 'parseXmlModules' as it was used to separately parse the non-group
+#   'required' and 'optional' tags that are no longer used.
+#    All libraries are listed in only one of the groups: 'required', 'optional'
+#    or 'explicit' and are parsed in the 'parseXmlGroupModules' function.
+
 declare -a xmlp_filecontents
 declare -a xmlp_licenses
 declare -a xmlp_licenses_range
@@ -7,6 +15,7 @@ declare -a xmlp_alllibs
 declare -a xmlp_tmp_array
 declare -a xmlp_reqlibs
 declare -a xmlp_optlibs
+declare -a xmlp_explicitlibs
 declare -a xmlp_grouplibs_name
 declare -a xmlp_grouplibs_deps
 declare -a xmlp_grouplibs_comment
@@ -104,37 +113,6 @@ function readXmlModuleFile
     return 1
 }
 
-function parseXmlModules
-{
-    local startReading=0
-    local x=0
-    local startPattern=$1
-    local endPattern=$2
-    local lstart=$3
-    local lend=$4
-
-    xmlp_tmp_array=()
-    #find required tag and parse all its parameters..
-    for (( i=$lstart; i < $lend; ++i ))
-    do
-        if [[ ${xmlp_filecontents[$i]} == *$endPattern* ]]; then
-            startReading=0
-        fi
-
-        if [[ $startReading == 1 ]]; then
-            #remove everything to first string..
-            local tmp="${xmlp_filecontents[$i]}"
-            tmp=`echo $tmp | sed -e s/^.*=\"// -e s/\".*$//`
-            xmlp_tmp_array[$x]="$tmp"
-            let x++
-        fi
-
-        if [[ ${xmlp_filecontents[$i]} == *$startPattern* ]]; then
-            startReading=1
-        fi
-    done
-}
-
 function parseXmlGroupModules
 {
     local startReading=0
@@ -259,9 +237,11 @@ function parseXmlModuleContents
     local lstart=-1
     local lend=-1
     local i=0
+    local groupname=""
 
     xmlp_reqlibs=()
     xmlp_optlibs=()
+    xmlp_explicitlibs=()
     xmlp_grouplibs_name=()
     xmlp_grouplibs_deps=()
     xmlp_grouplibs_comment=()
@@ -299,38 +279,42 @@ function parseXmlModuleContents
 
     #echo "parsing license $license, start=$lstart, end=$lend"
 
-    #parse required
-    parseXmlModules "<required>" "</required>" $lstart $lend
-    xmlp_reqlibs=( "${xmlp_tmp_array[@]}" )
-
-    #parse optional
-    parseXmlModules "<optional>" "</optional>" $lstart $lend
-    xmlp_optlibs=( "${xmlp_tmp_array[@]}" )
-
-    #parse any groups
+    #parse all groups
     parseXmlGroupModules $lstart $lend
 
-    if [[   ${#xmlp_reqlibs[*]} == 0 || 
-                ${#xmlp_optlibs[*]} == 0 ]]; then
-        echo "Required and Optional Modules not present in module files"
-        return 0
-    fi
+    for (( i = 0; i < ${#xmlp_grouplibs_name[*]}; ++i ))
+    do
+        groupname=${xmlp_grouplibs_name[$i]}
+        if [[ $groupname == "required" ]] ; then
+            xmlp_reqlibs=( ${xmlp_grouplibs_deps[$i]} )
+        elif [[ $groupname == "optional" ]] ; then
+            xmlp_optlibs=( ${xmlp_grouplibs_deps[$i]} )
+        elif [[ $groupname == "explicit" ]] ; then
+            xmlp_explicitlibs=( ${xmlp_grouplibs_deps[$i]} )
+        fi
+        #echo "group name: $groupname"
+        #echo "group deps: ${xmlp_grouplibs_deps[$i]}"
+    done
 
     #for (( i = 0; i < ${#xmlp_reqlibs[*]}; ++i ))
     #do
     #    echo "required: ${xmlp_reqlibs[$i]}"
     #done
 
-    #for (( i = 0; i < ${#xml_optlibs[*]}; ++i ))
+    #for (( i = 0; i < ${#xmlp_optlibs[*]}; ++i ))
     #do
     #    echo "optional: ${xmlp_optlibs[$i]}"
     #done
 
-    #for (( i = 0; i < ${#xmlp_grouplibs_name[*]}; ++i ))
+    #for (( i = 0; i < ${#xmlp_explicitlibs[*]}; ++i ))
     #do
-    #    echo "group names: ${xmlp_grouplibs_name[$i]}"
-    #    echo "group deps: ${xmlp_grouplibs_deps[$i]}"
-    #done
+    #    echo "extra: ${xmlp_explicitlibs[$i]}"
+
+    if [[   ${#xmlp_reqlibs[*]} == 0 || 
+                ${#xmlp_optlibs[*]} == 0 ]]; then
+        echo "Required and Optional Modules not present in module files"
+        return 0
+    fi
     return 1
 }
 
diff --git a/src/tools/dev/scripts/bv_support/helper_funcs.sh b/src/tools/dev/scripts/bv_support/helper_funcs.sh
index 81d71c1692b..7c339ec6cf4 100644
--- a/src/tools/dev/scripts/bv_support/helper_funcs.sh
+++ b/src/tools/dev/scripts/bv_support/helper_funcs.sh
@@ -256,42 +256,32 @@ function add_extra_commandline_args
     extra_commandline_args[${#extra_commandline_args[*]}]="$enable_func"
 }
 
-
-function verify_required_module_exists
+# *************************************************************************** 
+#  Modifications: 
+#    Kathleen Biagas, Monday May 12, 2025
+#    Combined verify_required_module_exists and verify_optional_module_exists
+#    into one method, verify_module_exists, to reduce code duplication
+#                                                                            
+# *************************************************************************** 
+
+function verify_module_exists
 {
-    local reqlib=$1
+    local alib=$1
     #check if required functions exist..
-    declare -F "bv_${reqlib}_enable" &>/dev/null || errorFunc "${reqlib} enable not found"
-    declare -F "bv_${reqlib}_disable" &>/dev/null || errorFunc "${reqlib} disable not found"
-    declare -F "bv_${reqlib}_initialize" &>/dev/null || errorFunc "${reqlib} initialize not found"
-    declare -F "bv_${reqlib}_info" &>/dev/null || errorFunc "${reqlib} info not found"
-    declare -F "bv_${reqlib}_ensure" &>/dev/null || errorFunc "${reqlib} ensure not found"
-    declare -F "bv_${reqlib}_build" &>/dev/null || errorFunc "${reqlib} build not found"
-    declare -F "bv_${reqlib}_depends_on" &>/dev/null || errorFunc "${reqlib} depends_on not found"
-    declare -F "bv_${reqlib}_print" &>/dev/null || errorFunc "${reqlib} print not found"
-    declare -F "bv_${reqlib}_print_usage" &>/dev/null || errorFunc "${reqlib} print_usage not found"
-    declare -F "bv_${reqlib}_is_installed" &>/dev/null || errorFunc "${reqlib} is_installed not found"
-    declare -F "bv_${reqlib}_is_enabled" &>/dev/null || errorFunc "${reqlib} is_enabled not found"
+    declare -F "bv_${alib}_enable" &>/dev/null || errorFunc "${alib} enable not found"
+    declare -F "bv_${alib}_disable" &>/dev/null || errorFunc "${alib} disable not found"
+    declare -F "bv_${alib}_initialize" &>/dev/null || errorFunc "${alib} initialize not found"
+    declare -F "bv_${alib}_info" &>/dev/null || errorFunc "${alib} info not found"
+    declare -F "bv_${alib}_ensure" &>/dev/null || errorFunc "${alib} ensure not found"
+    declare -F "bv_${alib}_build" &>/dev/null || errorFunc "${alib} build not found"
+    declare -F "bv_${alib}_depends_on" &>/dev/null || errorFunc "${alib} depends_on not found"
+    declare -F "bv_${alib}_print" &>/dev/null || errorFunc "${alib} print not found"
+    declare -F "bv_${alib}_print_usage" &>/dev/null || errorFunc "${alib} print_usage not found"
+    declare -F "bv_${alib}_is_installed" &>/dev/null || errorFunc "${alib} is_installed not found"
+    declare -F "bv_${alib}_is_enabled" &>/dev/null || errorFunc "${alib} is_enabled not found"
 }
 
 
-function verify_optional_module_exists
-{
-    local optlib=$1
-    declare -F "bv_${optlib}_enable" &>/dev/null || errorFunc "${optlib} enable not found"
-    declare -F "bv_${optlib}_disable" &>/dev/null || errorFunc "${optlib} disable not found"
-    declare -F "bv_${optlib}_initialize" &>/dev/null || errorFunc "${optlib} info not found"
-    declare -F "bv_${optlib}_info" &>/dev/null || errorFunc "${optlib} info not found"
-    declare -F "bv_${optlib}_ensure" &>/dev/null || errorFunc "${optlib} ensure not found"
-    declare -F "bv_${optlib}_build" &>/dev/null || errorFunc "${optlib} build not found"
-    declare -F "bv_${optlib}_depends_on" &>/dev/null || errorFunc "${optlib} depends_on not found"
-    declare -F "bv_${optlib}_print" &>/dev/null || errorFunc "${optlib} print not found"
-    declare -F "bv_${optlib}_print_usage" &>/dev/null || errorFunc "${optlib} print_usage not found"
-    declare -F "bv_${optlib}_host_profile" &>/dev/null || errorFunc "${optlib} host_profile not found"
-    declare -F "bv_${optlib}_is_installed" &>/dev/null || errorFunc "${optlib} is_installed not found"
-    declare -F "bv_${optlib}_is_enabled" &>/dev/null || errorFunc "${optlib} is_enabled not found"
-}
-
 # *************************************************************************** #
 # Function: uncompress_untar
 #                                                                             #
@@ -508,6 +498,8 @@ function verify_checksum_by_lookup
 #   I modified the routine to download the visit tar file and third party     #
 #   libraries from github.                                                    #
 #                                                                             #
+#   Kathleen Biagas, Monday May 12, 2025                                      #
+#   Return early if file to be downloaded is already present.                 #
 # *************************************************************************** #
 
 function download_file
@@ -516,6 +508,11 @@ function download_file
     # $2...$* [OPTIONAL] list of sites to obtain the file from
 
     typeset dfile=$1
+
+    if [[ -e ${dfile} ]] ; then
+        info "$dfile already downloaded."
+        return
+    fi
     info "Downloading $dfile . . ."
     shift
 
@@ -917,47 +914,46 @@ function prepare_build_dir
     return $untarred_src
 }
 
-# *************************************************************************** #
-#                   Function 1.3, check_optional_3rdparty                     #
-# --------------------------------------------------------------------------- #
-# This function will check to make sure that all of the necessary source      #
-# files for the optional 3rd party libraries actually exist.                  #
+# *************************************************************************** 
+# check_3rdparty
+# --------------------------------------------------------------------------- 
+# This function will check to make sure that all of the necessary files
+# for the third party libraries actually exist.
 #
-# *************************************************************************** #
-
-function check_optional_3rdparty
-{
-    info "Checking optional 3rd party libs"
-
-    for (( i = 0; i < ${#optlibs[*]}; ++i ))
-    do
-        ensure="bv_${optlibs[$i]}_ensure"
-        $ensure
-        if [[ $? != 0 ]] ; then
-            return 1
-        fi
-    done
-}
-
-
-# *************************************************************************** #
-#                    Function 1.1, check_required_3rdparty                    #
-# --------------------------------------------------------------------------- #
-# This function will check to make sure that all of the necessary files       #
-# for the required third party libraries actually exist.                      #
-# *************************************************************************** #
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Combined 'check_required_3rdparty' and 'check_optional_3rdparty' into one
+#   function to reduce code duplication.
+#
+#   Kathleen Biagas, Friday May 16, 2025
+#   Check for enabled status and continue loop without further processing
+#   if lib is disabled.
+#
+# ****************************************************************************
 
-function check_required_3rdparty
+function check_3rdparty
 {
     info "Checking for files . . ."
 
-    for (( i = 0; i < ${#reqlibs[*]}; ++i ))
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
-        ensure="bv_${reqlibs[$i]}_ensure"
-        $ensure
-        if [[ $? != 0 ]] ; then
-            return 1
-        fi
+        groupname=${grouplibs_name[$bv_i]}
+        info "Checking ${groupname} libraries"
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            $"bv_${lib}_is_enabled"
+
+            #if not enabled then skip
+            if [[ $? == 0 ]]; then
+                continue
+            fi
+
+            ensure="bv_${lib}_ensure"
+            $ensure
+            if [[ $? != 0 ]] ; then
+                return 1
+            fi
+        done
     done
 
     return 0
@@ -973,7 +969,7 @@ function check_required_3rdparty
 
 function check_files
 {
-    check_required_3rdparty
+    check_3rdparty
     if [[ $? != 0 ]]; then
         return 1
     fi
@@ -985,10 +981,6 @@ function check_files
         fi
     fi
 
-    check_optional_3rdparty
-    if [[ $? != 0 ]]; then
-        return 1
-    fi
     return 0
 }
 
@@ -1263,6 +1255,10 @@ function hostconf_library
 #   Don't put the C or CXX OPT_FLAGS in the host file. These will be handled  #
 #   by CMake when CMAKE_BUILD_TYPE is selected.                               #
 #                                                                             #
+#   Kathleen Biagas, Monday May 12, 2025                                      #
+#   Loop over groups when writing individual libs host conf instead of        #
+#   duplicating logic for reqlibs and optlibs.                                #
+#                                                                             #
 # *************************************************************************** #
 
 function build_hostconf
@@ -1491,16 +1487,15 @@ function build_hostconf
     echo \
 "##############################################################" >> $HOSTCONF
 
- for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
- do
-     hostconf_library ${reqlibs[$bv_i]}
- done
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
+    do
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            hostconf_library ${lib}
+        done
+    done
 
- for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
- do
-     hostconf_library ${optlibs[$bv_i]}
- done
- echo >> $HOSTCONF
+    echo >> $HOSTCONF
 
  #
  # Patch for Ubuntu 11.04
@@ -1526,6 +1521,10 @@ function build_hostconf
 #   Eric Brugger, Fri Feb  1 14:56:58 PST 2019
 #   I modified it to work post git transition.
 #
+#   Kathleen Biagas, Monday May 12, 2025
+#   Loop over groups when printing individual libs instead of
+#   duplicating logic for reqlibs and optlibs.
+#
 # *************************************************************************** #
 
 function printvariables
@@ -1556,19 +1555,23 @@ function printvariables
     printf "%s%s\n" "WGET_OPTS=" "${WGET_OPTS}"
 
     bv_visit_print
-    for (( bv_i=0; bv_i<${#reqlibs[*]}; ++bv_i ))
-    do
-        initialize="bv_${reqlibs[$bv_i]}_print"
-        $initialize
-    done
 
-    for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
+    for (( bv_i=0; bv_i < ${#grouplibs_name[*]}; ++bv_i ))
     do
-        initialize="bv_${optlibs[$bv_i]}_print"
-        $initialize
+        for lib in `echo ${grouplibs_deps[$bv_i]}`;
+        do
+            initialize="bv_${lib}_print"
+            $initialize
+        done
     done
 }
 
+# *************************************************************************** #
+# Modifications:
+#   Kathleen Biagas, Friday May 16, 2025
+#   Remove 'GROUPING' section. Expand comments for each group instead.
+#
+# *************************************************************************** #
 function usage
 {
     initialize_build_visit
@@ -1613,19 +1616,7 @@ function usage
              somewhere like /usr/gapps/visit." "${THIRD_PARTY_PATH}"
 
     printf "\n"
-    printf "GROUPING\n"
-    printf "\n"
-
-    for (( bv_i=0; bv_i<${#grouplibs_name[*]}; ++bv_i ))
-    do
-        name=${grouplibs_name[$bv_i]}
-        comment=${grouplibs_comment[$bv_i]}
-        enabled=${grouplibs_enabled[$bv_i]}
-        printf "%-20s %s [%s]\n" "--$name" "$comment" "$enabled"
-    done
-    printf "\n"
 
-    printf "\n"
     printf "VISIT-SPECIFIC OPTIONS\n"
     printf "\n"
     printf "%-20s %s [%s]\n" "--install-network" "Install specific network config files." "${VISIT_INSTALL_NETWORK}"
@@ -1642,6 +1633,8 @@ function usage
     printf "\n"
     printf "THIRD-PARTY LIBRARIES\n"
     printf "  A download attempt will be made for all files which do not exist.\n"
+    printf "  Enable individual libraries by using '--<name>', e.g. '--mpich'.\n"
+    printf "  Disable individual libraries by using '--no-<name>', e.g. '--no-python'.\n"
     printf "\n"
     printf "  REQUIRED -- These are built by default unless --no-thirdparty flag is used.\n"
     printf "\n"
@@ -1655,7 +1648,7 @@ function usage
     done
 
     printf "\n"
-    printf "  OPTIONAL\n"
+    printf "  OPTIONAL -- Using '--optional' flag will enable all libraries in this group.\n"
     printf "\n"
 
     for (( bv_i=0; bv_i<${#optlibs[*]}; ++bv_i ))
@@ -1666,6 +1659,18 @@ function usage
         $printUsageFunc
     done
 
+    printf "\n"
+    printf "  EXPLICIT -- These are only built when explicitly requested.\n"
+    printf "\n"
+
+    for (( bv_i=0; bv_i<${#explicitlibs[*]}; ++bv_i ))
+    do
+        initializeFunc="bv_${explicitlibs[$bv_i]}_initialize"
+        $initializeFunc
+        printUsageFunc="bv_${explicitlibs[$bv_i]}_print_usage"
+        $printUsageFunc
+    done
+
     printf "\n"
     printf "GIT OPTIONS\n"
     printf "\n"
diff --git a/src/tools/dev/scripts/bv_support/modules.xml b/src/tools/dev/scripts/bv_support/modules.xml
index 10aa26da2cb..ec61a4dedb3 100644
--- a/src/tools/dev/scripts/bv_support/modules.xml
+++ b/src/tools/dev/scripts/bv_support/modules.xml
@@ -1,74 +1,21 @@
 <modules>
     <license name="bsd|mit|lgpl">
         <!-- required libraries -->
-        <required>
-            <lib name="cmake"/> <!-- cmake is here -->
+        <group name="required" comment="All required libraries, built by default. Entire group can be disabled by '--no-thirdparty'. Individual libraries in the group can be disabled via --no-name flag, e.g. --no-python." enabled="yes">
+            <lib name="cmake"/>
             <lib name="python"/>
-            <lib name="vtk"/> <!-- <lib name="vtk" reqdeps="cmake vtk" optdeps="qt mesagl"/> -->
+            <lib name="vtk"/> 
             <lib name="qt6"/>
             <lib name="qt"/>
             <lib name="zlib"/>
-        </required>
+        </group>
 
         <!-- optional libraries -->
-        <optional>
+        <group name="optional" comment="Optional libraries, the entire group is disabled by default, and can be enabled via --optional flag or. Individual libraries can be enabled via --name, e.g. --conduit." enabled="no">
             <lib name="adios"/>
             <lib name="adios2"/>
             <lib name="advio"/>
-            <lib name="blosc2"/>
-            <lib name="boost"/>
-            <lib name="boxlib"/>
-            <lib name="cfitsio"/>
-            <lib name="cgns"/>
-            <lib name="conduit"/>
-            <lib name="fms"/>
-            <lib name="gdal"/>
-            <lib name="glu"/>
-            <lib name="h5part"/>
-            <lib name="hdf5"/>
-            <lib name="icet"/>
-            <lib name="llvm"/>
-            <lib name="mdsplus"/>
-            <lib name="mesagl"/>
-            <lib name="meson"/>
-            <lib name="mfem"/>
-            <lib name="mili"/>
-            <lib name="moab"/>
-            <lib name="mpich"/>
-            <lib name="nektarpp"/>
-            <lib name="netcdf"/>
-            <lib name="ninja"/>
-            <lib name="openexr"/>
-            <lib name="osmesa"/>
-            <lib name="ospray"/>
             <lib name="anari"/>
-            <lib name="pidx"/>
-            <lib name="pyside"/>
-            <lib name="qwt"/>
-            <lib name="silo"/>
-            <lib name="stripack"/>
-            <lib name="szip"/>
-            <lib name="uintah"/>
-            <lib name="vtkm"/>
-            <lib name="xcb"/>
-            <lib name="xdmf"/>
-            <lib name="xkbcommon"/>
-        </optional>
-
-        <!-- thirdparty flag -->
-        <group name="required" comment="All required libraries" enabled="yes">
-            <lib name="cmake"/> <!-- cmake is here -->
-            <lib name="python"/>
-            <lib name="vtk"/> <!-- <lib name="vtk" reqdeps="cmake vtk" optdeps="qt mesagl"/> -->
-            <lib name="qt6"/>
-            <lib name="qt"/>
-            <lib name="zlib"/>
-        </group>
-
-        <group name="optional" comment="All optional libraries" enabled="no">
-            <lib name="adios"/>
-            <lib name="adios2"/>
-            <lib name="advio"/>
             <lib name="blosc2"/>
             <lib name="boost"/>
             <lib name="boxlib"/>
@@ -77,11 +24,9 @@
             <lib name="conduit"/>
             <lib name="fms"/>
             <lib name="gdal"/>
-            <lib name="glu"/>
             <lib name="h5part"/>
             <lib name="hdf5"/>
             <lib name="icet"/>
-            <lib name="llvm"/>
             <lib name="mfem"/>
             <lib name="mili"/>
             <lib name="moab"/>
@@ -89,9 +34,7 @@
             <lib name="netcdf"/>
             <lib name="openexr"/>
             <lib name="ospray"/>
-            <lib name="anari"/>
             <lib name="pidx"/>
-            <lib name="pyside"/>
             <lib name="qwt"/>
             <lib name="silo"/>
             <lib name="szip"/>
@@ -99,181 +42,17 @@
             <lib name="vtkm"/>
             <lib name="xdmf"/>
         </group>
-
-        <group name="no-thirdparty" comment="Do not build required 3rd party libraries" enabled="no">
-            <lib name="no-cmake"/>
-            <lib name="no-python"/>
-            <lib name="no-qt6" />
-            <lib name="no-qt" />
-            <lib name="no-vtk"/>
-            <lib name="no-zlib"/>
-        </group>
-
-        <!-- all io libraries -->
-        <group name="all-io" comment="Build all available I/O libraries" enabled="no">
-            <lib name="adios"/>
-            <lib name="adios2"/>
-<!--        <lib name="advio"/>    Removed by Allen Sanderson-->
-            <lib name="boost"/> <!-- required by nektarpp -->
-            <lib name="boxlib"/>
-            <lib name="cfitsio"/>
-            <lib name="conduit"/>
-            <lib name="mfem"/>
-            <lib name="cgns"/>
-            <lib name="fms"/>
-            <lib name="gdal"/>
-            <lib name="h5part"/>
-            <lib name="hdf5"/>
-            <lib name="netcdf"/>
-            <lib name="nektarpp"/>
-            <lib name="openexr"/>
-            <lib name="pidx"/>
-            <lib name="silo"/>
-            <lib name="szip"/>
-            <lib name="uintah"/>
-            <lib name="xdmf"/>
-            <lib name="zlib"/>
-        </group>
-
-        <!-- dbio-only-->
-        <group name="dbio-only" comment="Disables EVERYTHING but I/O." enabled="no">
-            <lib name="adios"/>
-            <lib name="adios2"/>
-            <lib name="advio"/>
-            <lib name="boost"/> <!-- required by nektarpp -->
-            <lib name="boxlib"/>
-            <lib name="cfitsio"/>
-            <lib name="conduit"/>
-            <lib name="mfem"/>
-            <lib name="cgns"/>
-            <lib name="fms"/>
-            <lib name="gdal"/>
-            <lib name="h5part"/>
-            <lib name="hdf5"/>
-            <lib name="netcdf"/>
-            <lib name="nektarpp"/>
-            <lib name="pidx"/>
-            <lib name="silo"/>
-            <lib name="szip"/>
-            <lib name="uintah"/>
-            <lib name="xdmf"/>
-            <lib name="zlib"/>
-            <lib name="no-qt6"/>
-            <lib name="no-qt"/>
-            <lib name="no-qwt"/>
-            <lib name="no-python"/>
-        </group>
-
-        <!--
-            #all the optional non io libraries
-        -->
-        <group name="nonio" comment="Build non I/O libraries" enabled="no">
-            <lib name="icet"/>
-            <lib name="ospray"/>
-            <lib name="anari"/>
-        </group>
-
-        <!--
-        # Releasibility of these libs is not yet understood
-        -->
-        <group name="advanced" comment="Must be manually downloaded" enabled="no">
-<!--        <lib name="mdsplus"/>    Removed for now by Allen Sanderson-->
-            <lib name="mili"/>
-        </group>
-    </license>
-
-    <!-- modules needed by gpl license -->
-    <license name="gpl">
-        <!--
-        <add-license name="lpgl" />
-        -->
-        <!-- required libraries -->
-        <required>
-            <lib name="cmake"/>
-            <lib name="python"/>
-            <lib name="vtk"/>
-            <lib name="qt6"/>
-            <lib name="qt"/>
-            <lib name="zlib"/>
-        </required>
-
-        <!-- optional libraries -->
-        <optional>
-            <lib name="boost"/>
-            <lib name="szip"/>
-            <lib name="netcdf"/>
+        <group name="explicit" comment="Libraries that can only be enabled individually, the group cannot be enabled as a whole. This list can include mutually exclusive libraries like 'mesgal' and 'osmesa', or libraries only needed on specific platforms, or libraries with problematic builds." enabled="no">
             <lib name="glu"/>
-            <lib name="hdf5"/>
-            <lib name="icet"/>
             <lib name="llvm"/>
             <lib name="mesagl"/>
+            <lib name="meson"/>
             <lib name="mpich"/>
+            <lib name="ninja"/>
             <lib name="osmesa"/>
-            <lib name="pyqt"/>
-            <lib name="qwt"/>
-            <lib name="uintah"/>
-            <lib name="damaris"/>
-            <lib name="xercesc"/>
-            <lib name="xsd"/>
-        </optional>
-
-        <!-- thirdparty flag -->
-        <group name="required" comment="All required libraries" enabled="yes">
-            <lib name="cmake"/>
-            <lib name="python"/>
-            <lib name="vtk"/>
-            <lib name="qt6"/>
-            <lib name="qt"/>
-            <lib name="zlib"/>
-        </group>
-
-        <group name="optional" comment="All optional libraries" enabled="no">
-            <lib name="boost"/>
-            <lib name="hdf5"/>
-            <lib name="netcdf"/>
-            <lib name="mpich"/>
-            <lib name="qwt"/>
-            <lib name="szip"/>
-            <lib name="uintah"/>
-            <lib name="damaris"/>
-            <lib name="xercesc"/>
-            <lib name="xsd"/>
-        </group>
-
-
-        <group name="no-thirdparty" comment="Do not build required 3rd party libraries" enabled="no">
-            <lib name="no-cmake"/>
-            <lib name="no-python"/>
-            <lib name="no-qt6" />
-            <lib name="no-qt" />
-            <lib name="no-vtk"/>
-            <lib name="no-zlib"/>
-        </group>
-
-        <!-- nodbio flag -->
-        <group name="dbio-only" comment="Disables EVERYTHING but I/O." enabled="no">
-            <lib name="hdf5"/>
-            <lib name="netcdf"/>
-            <lib name="szip"/>
-            <lib name="zlib"/>
-            <lib name="uintah"/>
-            <lib name="no-python"/>
-            <lib name="no-qt6"/>
-            <lib name="no-qt"/>
-            <lib name="no-qwt"/>
-        </group>
-
-        <!-- all io libraries -->
-        <group name="all-io" comment="Build all available I/O libraries" enabled="no">
-            <lib name="hdf5"/>
-            <lib name="netcdf"/>
-            <lib name="szip"/>
-            <lib name="zlib"/>
-            <lib name="uintah"/>
-        </group>
-        <!-- #all the optional non io libraries -->
-        <group name="nonio" comment="Build non I/O libraries" enabled="no">
-            <lib name="icet"/>
+            <lib name="pyside"/>
+            <lib name="xcb"/>
+            <lib name="xkbcommon"/>
         </group>
     </license>
 </modules>


Reviews:
user: login: markcmiller86
body: @biagas great work on threading through all this logic! I found a couple of typos I think and proposed minor changes.

One thing though...I think there verbiage `required`, `optional` and now `extras` is still potentially unclear to someone venturing into this code for the first time. Is there a place you could add a handful of comments that captures the meaning and differences between these three lists? 

I am still confused on how *optional* mili is different from *extra* mesagl for example.
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T23:41:05Z
user: login: cyrush
body: Looks good, thanks for working through this and for adding good docs and comments. 
state: DISMISSED
author_association: MEMBER
submitted_at: 2025-05-21T16:46:50Z
user: login: biagas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-21T17:35:16Z
user: login: biagas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-21T19:34:23Z
user: login: markcmiller86
body: Great work on this @biagas :muscle:. Its a lot of complicated shell coding. Only thing that would make any "cooler" is if it was writen in Perl :wink:. The new name for the new category of dependency is also an improvement.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-21T21:04:43Z

Review comments:
diff_hunk: @@ -700,11 +699,33 @@ function strip_quotes
     echo "${str}"
 }
 
+
+# *************************************************************************** 
+# Function: bv_enable_group                                                     #
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Modified to test for actual group names and return early if possible.
+#   Don't allow 'extras' group to be 'enabled, print message and exit script.
path: src/tools/dev/scripts/bv_support/bv_main.sh
user: login: markcmiller86
body: ```suggestion
#   Don't allow 'extras' group to be 'enabled'. Print message and exit if so.
```
created_at: 2025-05-12T23:33:00Z
author_association: MEMBER
diff_hunk: @@ -256,42 +256,32 @@ function add_extra_commandline_args
     extra_commandline_args[${#extra_commandline_args[*]}]="$enable_func"
 }
 
-
-function verify_required_module_exists
+# *************************************************************************** 
+#  Modifications: 
+#    Kathleen Biagas, Monday May 12, 2025
+#    Combined verify_required_module_exists and verify_optional_module_exists
+#    into one methd: verify_module exists to reduce code duplication
path: src/tools/dev/scripts/bv_support/helper_funcs.sh
user: login: markcmiller86
body: ```suggestion
#    into one method, verify_module_exists, to reduce code duplication
```
created_at: 2025-05-12T23:35:56Z
author_association: MEMBER
diff_hunk: @@ -69,7 +70,13 @@ See ``bv_qt.sh`` as an example of allowing system or also an alternate (already
 ``bv_qt_system_qt`` and ``bv_alt_qt_dir`` were added and other functions were modified to support this for qt.
 
 
-Once ``bv_foo.sh`` has been updated appropriately, add the module name to ``bv_support/modules.xml`` under the appropriate categories.
+Once ``bv_foo.sh`` has been updated appropriately, add the module name to ``bv_support/modules.xml`` under the appropriate group.
+The `required` group in ``bv_support/modules.xml`` is for libraries that are required for basic functioning of _VisIt.
+The `optional` group is for most i/o and other non-required support libraries.
+The `extras` group is for any library (and its dependencies) that should be explicitly requested.
+This could be libraries that are mutually exclusive such as `mesagl` and `osmesa`, or libraries that may not be needed on many systems such as `mpich`, `xcb` or `xkbcommon`.
+The `extras` group should also be used for any library that has proven to have a problematic build system.
+
path: src/doc/dev_manual/CreatingABuildVisItModule.rst
user: login: cyrush
body: Great docs! Given this write up -- maybe the name for the group should be `explicit`?
created_at: 2025-05-21T16:42:56Z
author_association: MEMBER
diff_hunk: @@ -256,42 +256,32 @@ function add_extra_commandline_args
     extra_commandline_args[${#extra_commandline_args[*]}]="$enable_func"
 }
 
-
-function verify_required_module_exists
+# *************************************************************************** 
+#  Modifications: 
+#    Kathleen Biagas, Monday May 12, 2025
+#    Combined verify_required_module_exists and verify_optional_module_exists
+#    into one method, verify_module_exists, to reduce code duplication
+#                                                                            
+# *************************************************************************** 
+
+function verify_module_exists
 {
-    local reqlib=$1
+    local alib=$1
     #check if required functions exist..
-    declare -F "bv_${reqlib}_enable" &>/dev/null || errorFunc "${reqlib} enable not found"
-    declare -F "bv_${reqlib}_disable" &>/dev/null || errorFunc "${reqlib} disable not found"
-    declare -F "bv_${reqlib}_initialize" &>/dev/null || errorFunc "${reqlib} initialize not found"
-    declare -F "bv_${reqlib}_info" &>/dev/null || errorFunc "${reqlib} info not found"
-    declare -F "bv_${reqlib}_ensure" &>/dev/null || errorFunc "${reqlib} ensure not found"
-    declare -F "bv_${reqlib}_build" &>/dev/null || errorFunc "${reqlib} build not found"
-    declare -F "bv_${reqlib}_depends_on" &>/dev/null || errorFunc "${reqlib} depends_on not found"
-    declare -F "bv_${reqlib}_print" &>/dev/null || errorFunc "${reqlib} print not found"
-    declare -F "bv_${reqlib}_print_usage" &>/dev/null || errorFunc "${reqlib} print_usage not found"
-    declare -F "bv_${reqlib}_is_installed" &>/dev/null || errorFunc "${reqlib} is_installed not found"
-    declare -F "bv_${reqlib}_is_enabled" &>/dev/null || errorFunc "${reqlib} is_enabled not found"
+    declare -F "bv_${alib}_enable" &>/dev/null || errorFunc "${alib} enable not found"
+    declare -F "bv_${alib}_disable" &>/dev/null || errorFunc "${alib} disable not found"
+    declare -F "bv_${alib}_initialize" &>/dev/null || errorFunc "${alib} initialize not found"
+    declare -F "bv_${alib}_info" &>/dev/null || errorFunc "${alib} info not found"
+    declare -F "bv_${alib}_ensure" &>/dev/null || errorFunc "${alib} ensure not found"
+    declare -F "bv_${alib}_build" &>/dev/null || errorFunc "${alib} build not found"
+    declare -F "bv_${alib}_depends_on" &>/dev/null || errorFunc "${alib} depends_on not found"
+    declare -F "bv_${alib}_print" &>/dev/null || errorFunc "${alib} print not found"
+    declare -F "bv_${alib}_print_usage" &>/dev/null || errorFunc "${alib} print_usage not found"
+    declare -F "bv_${alib}_is_installed" &>/dev/null || errorFunc "${alib} is_installed not found"
+    declare -F "bv_${alib}_is_enabled" &>/dev/null || errorFunc "${alib} is_enabled not found"
 }
 
path: src/tools/dev/scripts/bv_support/helper_funcs.sh
user: login: cyrush
body: nice refactor to reduce redundant logic 
created_at: 2025-05-21T16:45:16Z
author_association: MEMBER
diff_hunk: @@ -917,47 +914,46 @@ function prepare_build_dir
     return $untarred_src
 }
 
-# *************************************************************************** #
-#                   Function 1.3, check_optional_3rdparty                     #
-# --------------------------------------------------------------------------- #
-# This function will check to make sure that all of the necessary source      #
-# files for the optional 3rd party libraries actually exist.                  #
+# *************************************************************************** 
+# check_3rdparty
+# --------------------------------------------------------------------------- 
+# This function will check to make sure that all of the necessary files
+# for the third party libraries actually exist.
 #
-# *************************************************************************** #
-
-function check_optional_3rdparty
-{
-    info "Checking optional 3rd party libs"
-
-    for (( i = 0; i < ${#optlibs[*]}; ++i ))
-    do
-        ensure="bv_${optlibs[$i]}_ensure"
-        $ensure
-        if [[ $? != 0 ]] ; then
-            return 1
-        fi
-    done
-}
-
-
-# *************************************************************************** #
-#                    Function 1.1, check_required_3rdparty                    #
-# --------------------------------------------------------------------------- #
-# This function will check to make sure that all of the necessary files       #
-# for the required third party libraries actually exist.                      #
-# *************************************************************************** #
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Combined 'check_required_3rdparty' and 'check_optional_3rdparty' into one
+#   function to reduce code duplication.
+#
+#   Kathleen Biagas, Friday May 16, 2025
+#   Check for enabled status and continue loop without further processing
+#   if lib is disabled.
+#
+# ****************************************************************************
 
-function check_required_3rdparty
+function check_3rdparty
path: src/tools/dev/scripts/bv_support/helper_funcs.sh
user: login: cyrush
body: nice refactor to reduce redundant logic 
created_at: 2025-05-21T16:45:49Z
author_association: MEMBER
diff_hunk: @@ -69,7 +70,13 @@ See ``bv_qt.sh`` as an example of allowing system or also an alternate (already
 ``bv_qt_system_qt`` and ``bv_alt_qt_dir`` were added and other functions were modified to support this for qt.
 
 
-Once ``bv_foo.sh`` has been updated appropriately, add the module name to ``bv_support/modules.xml`` under the appropriate categories.
+Once ``bv_foo.sh`` has been updated appropriately, add the module name to ``bv_support/modules.xml`` under the appropriate group.
+The `required` group in ``bv_support/modules.xml`` is for libraries that are required for basic functioning of _VisIt.
+The `optional` group is for most i/o and other non-required support libraries.
+The `extras` group is for any library (and its dependencies) that should be explicitly requested.
+This could be libraries that are mutually exclusive such as `mesagl` and `osmesa`, or libraries that may not be needed on many systems such as `mpich`, `xcb` or `xkbcommon`.
+The `extras` group should also be used for any library that has proven to have a problematic build system.
+
path: src/doc/dev_manual/CreatingABuildVisItModule.rst
user: login: biagas
body: I like the name change. Will implement.
created_at: 2025-05-21T17:35:16Z
author_association: CONTRIBUTOR
diff_hunk: @@ -917,47 +914,46 @@ function prepare_build_dir
     return $untarred_src
 }
 
-# *************************************************************************** #
-#                   Function 1.3, check_optional_3rdparty                     #
-# --------------------------------------------------------------------------- #
-# This function will check to make sure that all of the necessary source      #
-# files for the optional 3rd party libraries actually exist.                  #
+# *************************************************************************** 
+# check_3rdparty
+# --------------------------------------------------------------------------- 
+# This function will check to make sure that all of the necessary files
+# for the third party libraries actually exist.
 #
-# *************************************************************************** #
-
-function check_optional_3rdparty
-{
-    info "Checking optional 3rd party libs"
-
-    for (( i = 0; i < ${#optlibs[*]}; ++i ))
-    do
-        ensure="bv_${optlibs[$i]}_ensure"
-        $ensure
-        if [[ $? != 0 ]] ; then
-            return 1
-        fi
-    done
-}
-
-
-# *************************************************************************** #
-#                    Function 1.1, check_required_3rdparty                    #
-# --------------------------------------------------------------------------- #
-# This function will check to make sure that all of the necessary files       #
-# for the required third party libraries actually exist.                      #
-# *************************************************************************** #
+# Modifications:
+#   Kathleen Biagas, Monday May 12, 2025
+#   Combined 'check_required_3rdparty' and 'check_optional_3rdparty' into one
+#   function to reduce code duplication.
+#
+#   Kathleen Biagas, Friday May 16, 2025
+#   Check for enabled status and continue loop without further processing
+#   if lib is disabled.
+#
+# ****************************************************************************
 
-function check_required_3rdparty
+function check_3rdparty
path: src/tools/dev/scripts/bv_support/helper_funcs.sh
user: login: biagas
body: Thanks!
created_at: 2025-05-21T19:34:23Z
author_association: CONTRIBUTOR

PR comments:
user: login: biagas
created_at: 2025-05-12T23:30:47Z
body: In draft mode for comment on the new approach.
author_association: CONTRIBUTOR
user: login: biagas
created_at: 2025-05-12T23:52:06Z
body: > I am still confused on how _optional_ mili is different from _extra_ mesagl for example.

The main benefit  of the `optional` group is to get most of visit's third party libraries with one command line option: `--optional`.

The items in `extras` aren't always needed and/or wanted: `mesagl` may or may not be desired, `mesagl` and `osmesa` are mutually exclusive.  `extras` can also be used to hold libraries that prove to have problematic builds.  It may be the case that there are items currently in `optional` that should be in `extras` for that very reason. 



author_association: CONTRIBUTOR
user: login: biagas
created_at: 2025-05-12T23:56:53Z
body: > One thing though...I think there verbiage `required`, `optional` and now `extras` is still potentially unclear to someone venturing into this code for the first time. Is there a place you could add a handful of comments that captures the meaning and differences between these three lists?

I am not sure where in the code to place it. I do plan on updating our docs on build_visit to reflect whatever changes get the final approval.  

I did add a few extra comments to _--help_, where the individual library options are listed under their group names.

author_association: CONTRIBUTOR
user: login: markcmiller86
created_at: 2025-05-13T00:11:17Z
body: > > I am still confused on how _optional_ mili is different from _extra_ mesagl for example.
> 
> The main benefit of the `optional` group is to get most of visit's third party libraries with one command line option: `--optional`.

So, it sounds like `optional` is a short-cut, catch-all for *everything available*. Thats reasonable. And, I think `required` is pretty clear but still worth a one-liner somewhere such as...it is not possible to build an instance of VisIt without items in the `required` list.

> 
> The items in `extras` aren't always needed and/or wanted: `mesagl` may or may not be desired, `mesagl` and `osmesa` are mutually exclusive. `extras` can also be used to hold libraries that prove to have problematic builds. It may be the case that there are items currently in `optional` that should be in `extras` for that very reason.

Well, not to sound too pendantic here but "not always needed or wanted" or "may or may not be desired" sound a lot to me like `optional` though I do understand you want to focus here on the impact of the *build* and maybe NOT the available features once built?

Maybe the concept you are after here is `alternates`? osmes and mesagl certainly are alternates and the only reason for choosing one over the other is probably due to build challenges. I dunno...are there run-time impacts regarding that choice...maybe there are as in without osmesa, you can do only screen-capture saves.

But, I think I recall seeing `mpich` mentioned for `extras` too. Was that mentioned as an alternate sort of thing...maybe as an alternate to a vendor MPI? Or, was it mentioned as an *optional* (as in...build VisIt for serial or parallel)? I wonder if spack defines a nomenclature for this sort of thing?

`extras` just sounds a bit too much like `optional` to me.




author_association: MEMBER
user: login: biagas
created_at: 2025-05-13T00:23:15Z
body: @markcmiller86 I am fine with changing the 'optional' and 'extras' group names to whatever seems appropriate.  I kept 'optional' as that is currently in use and familiar with a lot of developers via the '--optional' flag.  @JustinPrivitera suggested 'bonus' in his ticket when he suggested a need for a new group.

'mpich' may not be wanted as part of the build, as you might want to use system MPI which would be setup via other PAR flags.
Needing 'mesagl' or 'osmesa' are dependent on the system, it is feasible to need neither.

author_association: CONTRIBUTOR
user: login: markcmiller86
created_at: 2025-05-13T03:56:08Z
body: > @markcmiller86 I am fine with changing the 'optional' and 'extras' group names to whatever seems appropriate. 

I honestly feel like I don't understand the differences well enough to suggest better names. I know only enough to say the existing names and functionality as I've understood them are still confusing to me. Maybe its just me though.
author_association: MEMBER
user: login: JustinPrivitera
created_at: 2025-05-13T06:35:28Z
body: I suggest `double-optional`.

I don't know if there is a good name. It probably makes sense to have libraries that don't fit into either of the `required` and `optional` categories, so I think we just need to bite the bullet and pick the name that is least offensive to our collective sensibilities.
author_association: MEMBER
user: login: brugger1
created_at: 2025-05-13T13:31:15Z
body: Great work Kathleen!

I like adding a new category for the additional libraries that should only be built in special circumstances. I think `extras` is as good a name as any. I would not change `optional`. This would require additional documentation changes as well as changes to scripts that drive `build_visit`.

I agree with Mark that adding a small amount of documentation in the file to document the differences between the three lists would be helpful.
author_association: COLLABORATOR
user: login: biagas
created_at: 2025-05-16T16:55:13Z
body: > I agree with Mark that adding a small amount of documentation in the file to document the differences between the three lists would be helpful.

Would expanding the comments related to each group in `modules.xml` be sufficient? 
I already updated the 'usage' text with more information for REQUIRED and OPTIONAL library groups.
author_association: CONTRIBUTOR
user: login: biagas
created_at: 2025-05-16T17:01:54Z
body: Did we come to a consensus on a better name for the third group than `extras`?

Also, my current changes do not allow for turning off the `required` group. It used be do-able because the `no-thirdparty` group automatically meant that `--no-thirdparty` option would turn off that group.  I could add parsing of `--no-thirdparty` from command line to do the same thing as the group used to.  Thoughts?
author_association: CONTRIBUTOR
user: login: cyrush
created_at: 2025-05-16T18:08:15Z
body: I think it would be good to preserve `-no-thirdparty`.

`extras` should work, users won't really be using it so I don't think we need to sweat over the name.

author_association: MEMBER
user: login: biagas
created_at: 2025-05-21T21:08:17Z
body: > The new name for the new category of dependency is also an improvement.

Thanks to @cyrush for the new name!
author_association: CONTRIBUTOR