This allows each implementation (gnu-like) and msvc to be implemented in
their respective classes rather than through an if tree in the CCompiler
class. This is cleaner abstraction and allows us to clean up the Fortran
compiler, which was calling CCompiler bound methods without an instance.
Because we need to inherit them in some cases, and python's
keyword-or-positional arguments make this really painful, especially
with inheritance. They do this in two ways:
1) If you want to intercept the arguments you need to check for both a
keyword and a positional argument, because you could get either. Then
you need to make sure that you only pass one of those down to the
next layer.
2) After you do that, if the layer below you decides to do the same
thing, but uses the other form (you used keyword by the lower level
uses positional or vice versa), then you'll get a TypeError since two
layers down got the argument as both a positional and a keyword.
All of this is bad. Fortunately python 3.x provides a mechanism to solve
this, keyword only arguments. These arguments cannot be based
positionally, the interpreter will give us an error in that case.
I have made a best effort to do this correctly, and I've verified it
with GCC, Clang, ICC, and MSVC, but there are other compilers like Arm
and Elbrus that I don't have access to.
It seems that clang-cl isn't quite compatible with cl in the way it handles
pch, and when the precompiled header is used, the pathname of the header is
needed, not just its filename.
This fixes test\common\13 pch with clang-cl
When invoked as clang-cl to compile, it doesn't emit cl-compatible D9002
warnings about unknown options, but fortunately also supports
-Werror-unknown-argument instead.
When invoked to link, and using LINK, it does emit cl-compatible LNK4044
warnings about unknown options.
Currently, ComplierHolder.determine_args() unconditionally adds the link
arguments to the commmand, even if we aren't linking, because it doesn't
have access to the mode (preprocess, compile, link) that
_get_compiler_check_args() will use.
This leads to command lines like:
'cl testfile.c /nologo /showIncludes /c /Fooutput.obj /Od kernel32.lib
user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib
uuid.lib comdlg32.lib advapi32.lib'
which clang-cl considers invalid; MSVS cl accepts this, ignoring the
unneeded libraries
Change from passing extra_args down to _get_compiler_check_args(), to
passing down a callback to CompilerHolder.determine_args() (with a bound
kwargs argument), so it can consult mode and kwargs to determine the args to
use.
Handle clang's cl or clang-cl being in PATH, or set in CC/CXX
Future work: checking the name of the executable here seems like a bad idea.
These compilers will fail to be detected if they are renamed.
v2:
Update compiler.get_argument_type() test
Fix comparisons of id inside CCompiler, backends and elsewhere
v3:
ClangClCPPCompiler should be a subclass of ClangClCCompier, as well
Future work: mocking in test_find_library_patterns() is effected, as we
now test for a subclass, rather than self.id in CCompiler.get_library_naming()
Some compilers try very had to pretend they're another compiler (ICC
pretends to be GCC and Linux and MacOS, and MSVC on windows), Clang
behaves much like GCC, but now also has clang-cl, which behaves like MSVC.
This method provides an easy way to determine whether testing for MSVC
like arguments `/w1234` or gcc like arguments `-Wfoo` are likely to
succeed, without having to check for dozens of compilers and the host
operating system, (as you would otherwise have to do with ICC).
Replace several checks against GCC_MINGW or (GCC_MINGW, GCC_CYGWIN) with
is_windows_compiler instead, so that clang and other gcc-like compilers
using MinGW work appropriately with vs_module_defs, c_winlibs, and
cpp_winlibs.
Fixes#4434.
For PE/COFF it is not possible to allow undefined symbols, so do not
try to use the option to do so.
While gcc ld silently ignores it, this is not the case for the llvm
linker.
Fix#4415
* This helps with reproducibility on macOS in the same way
`$ORIGIN` improves reproducibility on Linux-like systems.
* This makes the build-tree more resilient to users injecting
rpaths via `LDFLAGS`. Currently Meson on macOS crashes when
a build-tree rpath and a user-provided `-Wl,-rpath` in
LDFLAGS collide, leading to `install_name_tool` failures.
While this still does not solve the root cause, it makes
the occurrence much less likely, as users will generally
pass absolute `-Wl,-rpath` arguments into Meson.
Occasionally Darwin libraries can be .so rather than .dylib e.g. tensorflow_cc.so
tensorflow_cc is a c++ API for Tensorflow (https://github.com/FloopCZ/tensorflow_cc)
which was primarily written for Linux but is also compilable on Darwin. Possibly
through laziness, possibly just to have consistent filenames, the developers did not
opt to change the suffix from the Linux default when this is compiled on Darwin.
Also, the Darwin linker will find libraries with a .so suffix if they are
in its path. find_library() needs to match the linker behaviour.
In get_library_dirs() we are trusting the compiler to return a correct
list of directories to search for libraries, based on whether or not
we are compiling 64-bit or 32-bit. Unfortunately, this is often not the
case, as 64-bit libraries often are returned when compiling with -m32 on
a 64-bit OS.
Since system directories do not contain a mix of libraries, the solution
here is to check each directory, by picking a .so file in the directory
and checking whether its 64-bit or 32-bit. If we can't determine if we
want 32-bit or 64-bit, just skip the checks and assume the directory is
good.
Using the -pthread argument is not needed with clang when compiling for
darwin, and it results in the warning:
warning: argument unused during compilation: '-pthread'
GNU binutils ld silently ignores -rpath flags when targeting windows
(and it is already commented within ninjabackend.py that rpath as
concept doesn't exist on windows), and build_rpath_args in
VisualStudioCCompiler also returns an empty array. Therefore skip
this flag altogether.
This fixes linking with lld in MinGW mode, which doesn't support the
rpath flag.
* Enums are strongly typed and make the whole
`gcc_type`/`clang_type`/`icc_type` distinction
redundant.
* Enums also allow extending via member functions,
which makes the code more generalisable.
It's fairly common on Linux and *BSD platforms to check for these
attributes existence, so it makes sense to me to have this checking
build into meson itself. Autotools also has a builtin for handling
these, and by building them in we can short circuit cases that we know
that these don't exist (MSVC).
Additionally this adds support for two common MSVC __declspec
attributes, dllimport and dllexport. This implements the declspec
version (even though GCC has an __attribute__ version that both it and
clang support), since GCC and Clang support the MSVC version as well.
Thus it seems reasonable to assume that most projects will use the
__declspec version over teh __attribute__ version.
- For optimization=s add /O1: Use Maximum Optimization (Favor Size),
and remove /Os as it's implied by /O1.
- Because we add /O1, this implies /Gy, i.e. Function-Level Linking, so
unused code can be omitted.
- Add /Gw: Optimize Global Data, so unused data can be omitted.
With buildtype=minsize on x86 this reduces the size of a statically
linked Vala compiler binary from 5 MB down to just 1.87 MB.
This means that we will take into account all the flags set in the
cross file when fetching the list of library dirs, which means we
won't incorrectly look for 64-bit libraries when building for 32-bit.
Signed-off-by: Nirbheek Chauhan <nirbheek@centricular.com>
Closes https://github.com/mesonbuild/meson/issues/3881
* get_library_naming: Use templates instead of suffix/prefix pairs
This commit does not change functionality, and merely sets the
groundwork for a more flexibly naming implementation.
* find_library: Fix manual searching on OpenBSD
On OpenBSD, shared libraries are called libfoo.so.X.Y where X is the
major version and Y is the minor version. We were assuming that it's
libfoo.so and not finding shared libraries at all while doing manual
searching, which meant we'd link statically instead.
See: https://www.openbsd.org/faq/ports/specialtopics.html#SharedLibs
Now we use file globbing to do searching, and pick the first one
that's a real file.
Closes https://github.com/mesonbuild/meson/issues/3844
* find_library: Fix priority of library search in OpenBSD
Also add unit tests for the library naming function so that it's
absolutely clear what the priority list of naming is.
Testing is done with mocking on Linux to ensure that local testing
is easy
We used to immediately try to use whatever exe_wrapper was defined in
the cross file, but some people generate the cross file once and use
it for several projects, most of which do not even need an exe wrapper
to build.
Now we're a bit more resilient. We quietly fall back to using
non-exe-wrapper paths for compiler checks and skip the sanity check.
However, if some code needs the exe wrapper, f.ex., if you run a built
executable using custom_target() or run_target(), we will error out
during setup.
Tests will, of course, continue to error out when you run them if the
exe wrapper was not found. We don't want people's tests to silently
"pass" (aka skip) because of a bad CI setup.
Closes https://github.com/mesonbuild/meson/issues/3562
This commit also adds a test for the behaviour of exe_wrapper in these
cases, and refactors the unit tests a bit for it.
We already have code to fetch and find binaries specified in a cross
file, so use the same code for exe_wrapper. This allows us to handle
the same corner-cases that were fixed for other cross binaries.
Paths provided to us by the user or by pkg-config can be (and must be)
assumed to be usable since they might not be usable standalone.
Closes https://github.com/mesonbuild/meson/issues/3832
Rather than storing in the cache of search paths the full list returned
from the compiler and having each call ignore the non-existent ones, remove
from the list all non-existent ones before returning to the caching function.
When find_library is used to find dependencies, meson checks all paths for
libraries with all prefixes that could match. This means that when we are
compiling with -m32 on a 64-bit system, meson will find 64-bit libraries and
assumes that they will work. Naturally that is not the case.
The obvious fix is to do a test link against those libraries, but the extra
wrinkle here is that we need to do a "whole link" so as to test the static
libs. A check with gcc+ld on linux shows that unless there are unresolved
symbols from the main.c file, the static library is never checked so we avoid
the error from an incompatible library.