Repository: mesonbuild/meson

Issue:
dependency('foo', static: true) not working as expected
Hi,

When using `dependency('foo', static: true)` with pkg-config backend, meson is not trying to statically link the executable against that library


Discussion:
Yes, it seems we don't pass the correct linker flags for forcing a static link with a particular dependency. It's not trivial to do this either because the only way to make `ld` statically link with an `-lfoo` library is to actually pass the full path to the `libfoo.a` file.
According to https://stackoverflow.com/questions/6578484/telling-gcc-directly-to-link-a-library-statically, you can also use `-l:libfoo.a` might be easier than passing the full path? 
Interesting, that option is not documented anywhere. Any idea which versions of `ld` support it? Does it work on macOS?
It looks like it is documented, but doesn't say which version added it:

> -l namespec
> --library=namespec
> Add the archive or object file specified by namespec to the list of files to link.  This option may be used any number of times.  If namespec is of the form `:filename`, ld will search the library path for a file called filename, otherwise it will search the library path for a file called `libnamespec.a`.
I am trying to link SDL and boost statically and I am having exactly the same problem, which causes some headaches for deployment. Is this supported in version 0.40.0? Thanks for your time.
Should this not pass -Bstatic before the libs?
indeed I modified dependencies/base.py to add -Wl,-Bstatic to the command line before adding libs if static is on. and -Wl,-Bdynamic afterwards. Gotta make sure it works with msvc though

The correct fix would be to pass `--static` to pkg-config and use the output as is. If pkg-config gives incorrect arguments, it is a bug in pkg-config or the dependency's pc files and should be fixed there.
Meson already does that. However static does not include these flags
seemingly as policy. It’s certantly an issue that can be brought to the
pkg-config devs.

It seems like the —static flag to pkg-config is for linking with the
—static flag to gcc. It’s possible that trying to use the —static gcc flag
and the ending -Bdynamic won’t work.

On Fri, Oct 13, 2017 at 6:23 PM Jussi Pakkanen <notifications@github.com>
wrote:

> The correct fix would be to pass --static to pkg-config and use the
> output as is. If pkg-config gives incorrect arguments, it is a bug in
> pkg-config or the dependency's pc files and should be fixed there.
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <https://github.com/mesonbuild/meson/issues/1709#issuecomment-336581393>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/ABPnvWnDoou83GzrbTv3t3W3SZJW1UXiks5sr-LDgaJpZM4NMro9>
> .
>

This bug was fixed for 'pkg-config' by 9da031c04c9905949c896a8fdc5b608acd6dde47

For 'cmake' this bug still exists:


Test on current master branch:
```meson
project('hello', 'c')
zlib_dep = dependency('zlib', static : true, method: 'pkg-config')
exe = executable('hello', 'hello.c', dependencies: zlib_dep)
```
```
[1/2] cc -Ihello.p -I. -I.. -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O0 -g -MD -MQ hello.p/hello.c.o -MF hello.p/hello.c.o.d -o hello.p/hello.c.o -c ../hello.c
[2/2] cc  -o hello hello.p/hello.c.o -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group /usr/lib/libz.a -Wl,--end-group
```
```meson
project('hello', 'c')
zlib_dep = dependency('zlib', static : true, method: 'cmake')
exe = executable('hello', 'hello.c', dependencies: zlib_dep)
```

```
[1/2] cc -Ihello.p -I. -I.. -I/usr/include -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -O0 -g -MD -MQ hello.p/hello.c.o -MF hello.p/hello.c.o.d -o hello.p/hello.c.o -c ../hello.c
[2/2] cc  -o hello hello.p/hello.c.o -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group /usr/lib/libz.so -Wl,--end-group
```

Resolving patch:
diff --git a/mesonbuild/dependencies/cmake.py b/mesonbuild/dependencies/cmake.py
--- a/mesonbuild/dependencies/cmake.py
+++ b/mesonbuild/dependencies/cmake.py
@@ -388,6 +388,7 @@ def _detect_dep(self, name: str, package_version: str, modules: T.List[T.Tuple[s
             cmake_opts += ['-DARCHS={}'.format(';'.join(self.cmakeinfo.archs))]
             cmake_opts += [f'-DVERSION={package_version}']
             cmake_opts += ['-DCOMPS={}'.format(';'.join([x[0] for x in comp_mapped]))]
+            cmake_opts += [f'-DSTATIC={self.static}']
             cmake_opts += args
             cmake_opts += self.traceparser.trace_args()
             cmake_opts += toolchain.get_cmake_args()


Test patch:
diff --git a/test cases/rust/13 external c dependencies/test.json b/test cases/rust/13 external c dependencies/test.json
--- a/test cases/rust/13 external c dependencies/test.json	
+++ b/test cases/rust/13 external c dependencies/test.json	
@@ -12,7 +12,8 @@
       ]
     },
     "exclude": [
-      { "static": true, "method": "pkg-config" }
+      { "static": true, "method": "pkg-config" },
+      { "static": true, "method": "cmake" }
     ]
   }
 }