LinkOnceODRLinkage on Windows for global variables - windows

I'm compiling two files with clang 6.0: testA.c and testB.c.
On both files I am running a custom compiler pass that inserts a zero-initialized global variable called globalVarTest. I set the linkage of such global variable to be LinkOnceODRLinkage.
Now, when I link testA.c and testB.c together (that is, the object files obtained by compiling them separately), the linker complains that there are multiple definitions of globalVarTest.
Isn't LinkOnceODRLinkage supposed to tell the linker that if both definitions match, the symbols is the same and it can therefore pick any of the two definitions when building the final executable?
UPDATE:
The same procedure works on Linux. Is this a limitation of the Windows linker? I have been able to achieve the same effect using COMDAT sections but I wonder why LLVM is not using that mechanism automatically without me requiring to explicitly set COMDATS.

I got an answer from the LLVM mailing list. Using LinkOnceODRLinkage does not work on Windows, even though it used to work in the past.
The best way to achieve the same effect is to explicitly use COMDAT sections. Apparently, this is what was happening automatically by setting LinkOnceODRLinkage, until the behavior changed.

Related

What is meant by an exe being dynamically compiled?

Came across the following paragraph from a page on the MySQL website here:
You can write plugins in C or C++ (or another language that can use C
calling conventions). Plugins are loaded and unloaded dynamically, so
your operating system must support dynamic loading and you must have
compiled the calling application dynamically (not statically). For
server plugins, this means that mysqld must be compiled
dynamically.
What is meant by dynamical compiling? I know about dynamical linking, but I'm not sure what they meant with dynamical compiling.
Also, on Windows 10 (x64), how can I assure that an exe has been compiled dynamically? Is it possible to figure it out from the output of dumpbin? Here's the dumpbin output for mysqld.exe (version 5.7):
Note: I reviewed this old question which did not provide me with that much information. The depends tool it suggests is no longer on Windows.
Compiling dynamically simply means that you are compiling the code such that the compiled output is suitable for dynamic linking.
On Windows, the process of creating as DLL necessarily compiles it such that it's suitable for dynamic linking because DLLs are always dynamically linked.
I believe that most platforms today always compile dynamically and produce relocatable output, even if they're subsequently linked statically.

setting up autotools to link single system library statically

I have a project, where I want to link one of system libraries statically. The project uses GNU build system.
In configure.ac I have:
AC_CHECK_LIB(foobar, foobar_init)
On development machine this library is installed in /usr/lib/x86_64-linux-gnu. It is detected, but it is linked dynamically, which causes issues, as it is not present on some machines. Linking it statically (-Wl,-Bstatic etc.) works fine, but I don't know how to set this up in autotools. I tried forcing this into Makefile.am link flags for the project, but it still gives a preference to dynamic library.
I also tried using --enable-static with ./configure, but it seems to have no effect on system libraries.
If you want to link the whole program statically, then you should pass the --disable-shared option to configure. You might or might not need also to pass --enable-static, depending on the default value for that option (which you can influence via your configure.ac file). You really should consider doing this.
You should also consider making this the installer's problem, not the build system's. Let it be the installer's responsibility to ensure that all the shared libraries needed by the program are provided by the systems where it is installed. This is very common; in fact, it is one of the inspirations for package-management systems such as yum / dnf and apt, and their underlying packaging formats.
If you insist on linking only one library statically, while linking everything else dynamically, then you'll need to jump through a few more hoops. The objective will be to emit link options that cause just that library to be linked statically, without changing other libraries' linking. With the GNU toolchain, and supposing that the program is otherwise being linked dynamically, that would be this combination of options:
-Wl,-Bstatic -lfoobar -Wl,-Bdynamic
Now consider the documentation of the AC_CHECK_LIB() macro:
Macro: AC_CHECK_LIB (library, function, [action-if-found],
[action-if-not-found], [other-libraries])
[...] action-if-found is a list of shell commands to run if the link with the library succeeds; action-if-not-found is a list of shell
commands to run if the link fails. If action-if-found is not
specified, the default action prepends -llibrary to LIBS and defines
'HAVE_LIBlibrary' (in all capitals). [...]
Note in particular the default behavior in the event that the optional arguments are not provided (your present case) -- that's not quite what you want, at least not by itself. I suggest providing at least an alternative behavior for action-if-found case, and you could consider also making configure fail in the action-if-not-found case. The latter is left as an exercise; implementing just the former might look like this:
AC_CHECK_LIB([foobar], [foobar_init], [
LIBS="-Wl,-Bstatic -lfoobar -Wl,-Bdynamic $LIBS"
AC_DEFINE([HAVE_LIBFOOBAR], [1], [Define to 1 if you have libfoobar.])
])
You should also pay attention to the order of your AC_CHECK_LIB() invocations. As its docs go on to say:
This macro is intended to support building LIBS in a right-to-left
(least-dependent to most-dependent) fashion such that library
dependencies are satisfied as a natural side effect of consecutive
tests. Linkers are sensitive to library ordering so the order in which
LIBS is generated is important to reliable detection of libraries.
If you find that you still aren't getting what you want, then have a look at the link commands that make actually executes. You need to understand what's wrong about them before you can determine how to fix the problem.
With all that said, I observe that the above treatment is basically a hack, and it makes your build system much less resilient. It introduces dependencies on GNU toolchain options (which some other toolchains may nevertheless accept), and it assumes dynamic linking is being performed overall. It may be possible to resolve those issues with additional Autoconf code, but I urge you to instead go with one of the first two alternatives I described.

Using dynamic library

When I would like to compile a program which uses a dynamic library, do I have to install (i.e. copy to a specific place, say, /usr/share/lib) this library? Or is it ok, if I put this library to any place somewhere and later during linking I point the linker to it, e.g. '-L ./thelibfolder'?
do I have to install (i.e. copy to a specific place, say, /usr/share/lib) this library?
No.
For a UNIX shared library, you need to arrange for two things:
You have to make the library known to the static linker, while linking main executable. Usually this is achieved by adding -L/path/to/directory -lfoo link flags to the link line.
You have to make runtime loader search /path/to/directory as well. This is system-specific. On many systems, setting LD_LIBRARY_PATH environment variable achieves the desired result, though this is usually not the preferred method. Another method is to encode this path into the application itself, e.g. on Linux one would add -Wl,-rpath=/path/to/directory to the application link line.

How can I convince Xcode to emit a duplicate symbol linker error?

Here's a different one from the usual confusion over duplicate symbol errors... :-)
I'm working on some legacy Mac code in an Xcode project that has the same global, "trace", defined in several different source files - for instance:
File1.c: SInt32 trace;
File2.c: Boolean trace;
etc. It's clear the original author meant them to have file-specific scope, but just neglected to prefix any of these lines with "static". That's fine, easy enough to fix.
But I'm kind of shocked the linker isn't flagging these! It looks to me like Xcode's linker (I presume gnu ld) only emits duplicate symbol warnings or errors for functions, that are linked into the code segment - but not global variables that are linked into the data segment. Instead, it silently conflates them, which is causing bugs.
So... how do I convince Xcode to emit link errors for duplicate global variables? Or get this information in some other way that can be a routine part of my build?
Well, I thought I'd answered my own question... :-)
I posted earlier:
So if you're using Xcode with LLVM GCC
4.2, go to the build settings dialog, find the "LLVM GCC 4.2 - Code
Generation" section, and check the "No
Common Blocks" checkbox. This enables
the compiler's "-fno-common" option,
and changes the object file generation
so that ld will choke and emit an
error if you have two globals in
different source files with the same
name.
Unfortunately, that doesn't seem to solve all instances. It seems to work fine if all the globals have the same type.
But the example in the question is taken straight from the code, where a variable named "trace" is defined as a global in two different files with two different types. And that's still not caught by the build system when I check that checkbox.

How to specify preference for compilers when using enable_language [cmake]

When using enable_language in cmake, it always search for compilers in a certain default sequence. I wonder how I can change this sequence. For example, if my system has both ifort (icc) and gfortran (g++) installed, and I want to use ifort (icc) instead of the gfortran (g++), how could I set up this?
CLARIFICATION: I know we can switch the compiler explicitly by changing the variable CMAKE_Fortran_Compiler, but what I want to do is rather to modify the default sequence that cmake searches for available compilers if the user does not specify such a preference.
From what I currently found, a work-around is to set CMAKE_Fortran_Compiler before project(xxx), so that this variable can never gets overridden later, but clearly this is not the best way, since I will need gfortran if there turns out to be no ifort available.
By the way, what's the best place to look for this kind of information? The documentation does not seem to be very complete..
Thanks!
The right place to look is the CMake FAQ, which answers your question.
Omegaice's answer will work, as will CC=/path/to/icc cmake ..., see also this discussion thread.
Setting CMAKE_Fortran_Compiler before the project call is strongly discouraged (as the FAQ will tell you).
Note that manually calling enable_language is no different from specifying the languages with the project call (or indeed not specifying them, in which case they default to C and CXX), since that calls enable_language internally.
You can probably specify which compiler to use by doing ccmake .. -DCMAKE_Fortran_Compiler=<executable> (where <executable> is either the name of the compiler or the full path to the compiler) instead of setting it in the CMakeLists.txt.

Resources