Repository: spack/spack

Issue:
Installation issue: libzmq
### Steps to reproduce the issue

```console
$ spack spec -I libzmq
Input spec
--------------------------------
 -   libzmq

Concretized
--------------------------------
[+]  bi2quif  libzmq@4.3.5%gcc@11.4.0~docs~drafts+libbsd+libsodium~libunwind build_system=autotools arch=linux-ubuntu22.04-westmere
[+]  hxjiqjp      ^libbsd@0.11.7%gcc@11.4.0 build_system=autotools arch=linux-ubuntu22.04-westmere
[+]  qpnkqe3          ^libmd@1.0.4%gcc@11.4.0 build_system=autotools arch=linux-ubuntu22.04-westmere
[+]  4nnhisp      ^libsodium@1.0.18%gcc@11.4.0 build_system=autotools arch=linux-ubuntu22.04-westmere
[+]  yf5px7h      ^pkgconf@1.9.5%gcc@11.4.0 build_system=autotools arch=linux-ubuntu22.04-westmere
```

### Error message

The build completes without errors but the result is lacking security features of previous spack libzmq builds.  Specifically support for CURVE security now requires `configure --with-libsodium` while in releases prior to libzmq-4.3.5, CURVE was enabled with or without `--with-libsodium`.

@vsoch ran into this when running the `flux-core` which depends on libzmq:
```
$ spack load flux-core
garlick@morbo:~/other/spack$ flux start -s2
flux-broker: src/zsock_option.inc:1334: zsock_set_curve_server: Assertion `rc == 0 || zmq_errno () == ETERM' failed.
flux-start: 0 (pid 806480) Aborted

^Cflux-broker: simple: barrier: operation failed
flux-broker: bootstrap failed
```
This is due to lack of curve support in `libzmq-4.3.6`.

### Information on your system


* **Spack:** 0.21.0.dev0 (537ab481670bad654225f488fb4ec92d25f148a8)
* **Python:** 3.10.12
* **Platform:** linux-ubuntu22.04-westmere
* **Concretizer:** clingo


### Additional information

Mentioning @dennisklein

Note that it was always recommended to build libzmq `--with-libsodium`.  The internal crypto that gets used ("tweetnacl") in earlier versions when this option is not provided is not really production quality code, which is why it was removed in the latest release.

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have run `spack maintainers <name-of-the-package>` and **@mentioned** any maintainers
- [X] I have uploaded the build log and environment files
- [X] I have searched the issues of this repo and believe this is not a duplicate


Discussion:
> Note that it was always recommended to build libzmq --with-libsodium. 

Er I should qualify that statement!    The configure logic around this stuff did change around 2016 for v4.2.1.  So maybe the original recipe was correct for older versions.
@tldahlgren do you know how to add a variant to a `depends_on` ? Everything I tried has failed.
Just a note that I've been trying fixes locally, but there is some bug with shared (I think I opened an issue earlier this week) so I can't build anything with develop.
> @tldahlgren do you know how to add a variant to a `depends_on` ? Everything I tried has failed.

Do you want the variant associated with the dependency and or the condition when the dependency applies?

Also, is this a binary or multi-valued variant?
> > @tldahlgren do you know how to add a variant to a `depends_on` ? Everything I tried has failed.
> 
> Do you want the variant associated with the dependency and or the condition when the dependency applies?

Examples:
- `depends_on("gettext~libxml2", when="~libxml2")`
- `depends_on("arpack-ng~mpi", when="+arpack")`
- `depends_on("kvtree~shared", when="@0.5: ~shared")`
- `depends_on("dray~shared", when="@:0.8.0 +dray~shared")`
- `depends_on("umpire+cuda~shared", when="+raja+cuda ^raja@:0.14")`
- `depends_on("mpi", when="^hdf5+mpi~shared")`

> 
> Also, is this a binary or multi-valued variant?

Here's an example of setting dependencies for multiple values for a single-valued variant from the `flecsi` package (though with proper indentation):
- `for level in ("low", "medium", "high"):`
      `depends_on("caliper@2.0.1~adiak~libdw", when=f"@:1 caliper_detail={level}")`

Or a multi-valued variant in the dependency:
- `depends_on("fftw precision=float,double ~mpi+openmp")`
> Just a note that I've been trying fixes locally, but there is some bug with shared (I think I opened an issue earlier this week) so I can't build anything with develop.

What is the bug here?  Which issue?
Oh you're right I don't think I opened that issue (I opened 2 and there was a third) here is the error:

```
==> Installing flux-core-0.54.0-v3nbqm2xp52p7ya7bw7h7rdaf2mu6bcf [45/45]
==> No binary for flux-core-0.54.0-v3nbqm2xp52p7ya7bw7h7rdaf2mu6bcf found: installing from source
Process Process-1:
Traceback (most recent call last):
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 1014, in _setup_pkg_and_run
    kwargs["env_modifications"] = setup_package(
                                  ^^^^^^^^^^^^^^
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 746, in setup_package
    set_wrapper_variables(pkg, env_mods)
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 522, in set_wrapper_variables
    update_compiler_args_for_dep(dspec)
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 494, in update_compiler_args_for_dep
    dep_link_dirs.extend(query.libs.directories)
                         ^^^^^^^^^^
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/spec.py", line 1208, in __get__
    value = f()
            ^^^
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/spec.py", line 1197, in <lambda>
    callbacks_chain.append(lambda: getattr(pkg, self.attribute_name))
                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vanessa/Desktop/Code/flux/spack/var/spack/repos/builtin/packages/gettext/package.py", line 135, in libs
    )
      
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/llnl/util/lang.py", line 486, in __getitem__
    return self.dict[key]
           ~~~~~~~~~^^^^^
KeyError: 'shared'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/vanessa/anaconda3/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/home/vanessa/anaconda3/lib/python3.11/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 1034, in _setup_pkg_and_run
    package_context = get_package_context(tb)
                      ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 1242, in get_package_context
    func = getattr(obj, tb.tb_frame.f_code.co_name, "")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/vanessa/Desktop/Code/flux/spack/var/spack/repos/builtin/packages/gettext/package.py", line 135, in libs
    )
      
  File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/llnl/util/lang.py", line 486, in __getitem__
    return self.dict[key]
           ~~~~~~~~~^^^^^
KeyError: 'shared'
==> Error: Failed to install flux-core due to InstallError: The process has stopped unexpectedly (exit 1)
```
I looked it up a few days ago and there was explicitly a change with a "shared" variant that seemed relevant but I can't find the commit now.
> Oh you're right I don't think I opened that issue (I opened 2 and there was a third) here is the error:
> 
> ```
> ==> Installing flux-core-0.54.0-v3nbqm2xp52p7ya7bw7h7rdaf2mu6bcf [45/45]
> ==> No binary for flux-core-0.54.0-v3nbqm2xp52p7ya7bw7h7rdaf2mu6bcf found: installing from source
> Process Process-1:
> Traceback (most recent call last):
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 1014, in _setup_pkg_and_run
>     kwargs["env_modifications"] = setup_package(
>                                   ^^^^^^^^^^^^^^
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 746, in setup_package
>     set_wrapper_variables(pkg, env_mods)
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 522, in set_wrapper_variables
>     update_compiler_args_for_dep(dspec)
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 494, in update_compiler_args_for_dep
>     dep_link_dirs.extend(query.libs.directories)
>                          ^^^^^^^^^^
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/spec.py", line 1208, in __get__
>     value = f()
>             ^^^
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/spec.py", line 1197, in <lambda>
>     callbacks_chain.append(lambda: getattr(pkg, self.attribute_name))
>                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "/home/vanessa/Desktop/Code/flux/spack/var/spack/repos/builtin/packages/gettext/package.py", line 135, in libs
>     )
>       
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/llnl/util/lang.py", line 486, in __getitem__
>     return self.dict[key]
>            ~~~~~~~~~^^^^^
> KeyError: 'shared'
> 
> During handling of the above exception, another exception occurred:
> 
> Traceback (most recent call last):
>   File "/home/vanessa/anaconda3/lib/python3.11/multiprocessing/process.py", line 314, in _bootstrap
>     self.run()
>   File "/home/vanessa/anaconda3/lib/python3.11/multiprocessing/process.py", line 108, in run
>     self._target(*self._args, **self._kwargs)
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 1034, in _setup_pkg_and_run
>     package_context = get_package_context(tb)
>                       ^^^^^^^^^^^^^^^^^^^^^^^
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/spack/build_environment.py", line 1242, in get_package_context
>     func = getattr(obj, tb.tb_frame.f_code.co_name, "")
>            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>   File "/home/vanessa/Desktop/Code/flux/spack/var/spack/repos/builtin/packages/gettext/package.py", line 135, in libs
>     )
>       
>   File "/home/vanessa/Desktop/Code/flux/spack/lib/spack/llnl/util/lang.py", line 486, in __getitem__
>     return self.dict[key]
>            ~~~~~~~~~^^^^^
> KeyError: 'shared'
> ==> Error: Failed to install flux-core due to InstallError: The process has stopped unexpectedly (exit 1)
> ```
> 
> I looked it up a few days ago and there was explicitly a change with a "shared" variant that seemed relevant but I can't find the commit now.

Yep, that's the `gettext` issue that's been resolved in my tests with the fix in #39423 
The libzmq issue with 4.3.5 is clear though right?  Prior versions had CURVE support.  This one (just released two days ago) doesn't.  I would think we'd want to fix the 4.3.5 release without adding a variant?
> Yep, that's the gettext issue that's been resolved in my tests with the fix in https://github.com/spack/spack/pull/39423

Phew! I'll watch that for merge - thank you!
> The libzmq issue with 4.3.5 is clear though right? Prior versions had CURVE support (just released two days ago) doesn't. I would think we'd want to fix the 4.3.5 release without adding a variant?

Yep I think so - and the reason it suddenly broke is because the new zmq was added just 2 days ago: https://github.com/spack/spack/commit/d2ddd99ef63191353a264ce83a0bdbe0c4fb37aa

I rebuild my containers regularity and had locally one from the day before that, and then the CI was pulling latest. It's when I realized that and pulled again that I reproduced the issue. And so for the current builds https://github.com/converged-computing/flux-views/pull/5 I'm trying to pin that version (and hoping with unify:true it uses it for flux-core).
okay I think (at least based on the spec) that should work! It will be another hour plus before the final container is built, and that's when I can sanity check it. It was working before so as long as I can get that version the issue should be resolved.
![image](https://github.com/spack/spack/assets/814322/8bcd2e0d-d7ff-4645-bd4b-8d9d89022967)

> > Yep, that's the gettext issue that's been resolved in my tests with the fix in https://github.com/spack/spack/pull/39423
> 
> Phew! I'll watch that for merge - thank you!

You probably won't actually see the problem IF you install `gettext` separately with `develop` updated in the last couple of days then the package you want.
> You probably won't actually see the problem IF you install gettext separately with develop updated in the last couple of days then the package you want.

I was installing flux-core from develop today, and it was getting gettext that way. I'll just want until it's merged to try again, I think I'm spacked out for today. Thank you!

Resolving patch:
diff --git a/var/spack/repos/builtin/packages/libzmq/package.py b/var/spack/repos/builtin/packages/libzmq/package.py
--- a/var/spack/repos/builtin/packages/libzmq/package.py
+++ b/var/spack/repos/builtin/packages/libzmq/package.py
@@ -105,19 +105,16 @@ def autoreconf(self, spec, prefix):
     def configure_args(self):
         config_args = []
 
+        config_args.extend(self.with_or_without("docs"))
         config_args.extend(self.enable_or_disable("drafts"))
         config_args.extend(self.enable_or_disable("libbsd"))
+        config_args.extend(self.with_or_without("libsodium"))
         config_args.extend(self.enable_or_disable("libunwind"))
         # the package won't compile with newer compilers because warnings
         # are converted to errors. Hence, disable such conversion.
         # this option was only added in version 4.2.3.
         if self.spec.version >= Version("4.2.3"):
             config_args.append("--disable-Werror")
-
-        if "+libsodium" in self.spec:
-            config_args.append("--with-libsodium=" + self.spec["libsodium"].prefix)
-        if "~docs" in self.spec:
-            config_args.append("--without-docs")
         if "clang" in self.compiler.cc:
             config_args.append("CFLAGS=-Wno-gnu")
             config_args.append("CXXFLAGS=-Wno-gnu")


Test patch: