When trying to link some older code with customized Windows/POSIX portability, there are #ifdef conditional compilations that call _ftime() on Cygwin and ftime() everywhere else (note the leading _).
When I try to compile and link this code, though, I get the following
../../bin/../lib/libconv-core.a(convcore.o):convcore.c:(.text+0xf6b): undefined reference to `_ftime'
../../bin/../lib/libconv-core.a(convcore.o):convcore.c:(.text+0xf6b): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `_ftime'
We've found that present Cygwin actually defines the common POSIX function ftime(). Just call it by its standard name instead of the Microsoft CRT oddity.
Related
I have researched more into the problem and posted a more detailed question with my findings here: Rust, how to use global variable from DLL? C++ equivalent requires __declspec(dllimport)
Original question:
Summary:
When linking my project with MSVC 2019's link.exe, I am getting errors such as unresolved external symbol jl_module_type. These symbols are defined in a file julia.lib, which I have verified using dumpbin /exports julia.lib. This file is passed as an argument to link.exe, and yet, it still complains about unresolved symbols. It looks like all the symbols that failed to be linked are variables rather than functions.
More information:
julia.lib has been renamed from libjulia.dll.a, and it corresponds to another file libjulia.dll. They were built with Cygwin/MinGW, but AFAIK this should not affect things. The actual project this is being used in is written in Rust, so link.exe is being invoked automatically by Rust's cargo tool. It is configured to build my project as a DLL.
I added an online modbus library: freemodbus to my project and afterwards I find out that it fails at linkage phase with the following undefined reference:
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7e-m/libc_nano.a(lib_a-signalr.o): In function `_kill_r':
/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build_nano/arm-none-eabi/armv7e-m/newlib/libc/reent/../../../../../../newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7e-m/libc_nano.a(lib_a-signalr.o): In function `_getpid_r':
/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build_nano/arm-none-eabi/armv7e-m/newlib/libc/reent/../../../../../../newlib/libc/reent/signalr.c:97: undefined reference to `_getpid'
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7e-m/libc_nano.a(lib_a-fstatr.o): In function `_fstat_r':
/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build_nano/arm-none-eabi/armv7e-m/newlib/libc/reent/../../../../../../newlib/libc/reent/fstatr.c:62: undefined reference to `_fstat'
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/lib/armv7e-m/libc_nano.a(lib_a-isattyr.o): In function `_isatty_r':
/build/newlib-5zwpxE/newlib-2.2.0+git20150830.5a3d536/build_nano/arm-none-eabi/armv7e-m/newlib/libc/reent/../../../../../../newlib/libc/reent/isattyr.c:58: undefined reference to `_isatty'
collect2: error: ld returned 1 exit status
Now after researching online I found out that adding EITHER of the following to the linker options flags solves this issue:
1. target_link_libraries(... -lc -lstdc++)
2. target_link_libraries(... -specs=nosys.specs)
The first option I think I got related to the fact that the order of those libraries matters so even if they are already included especially libc they would need to be included again or in rite order True?
I just didn't understand the 2nd one: I know it is related to syscalls? Some research brought his to my attention:
"It seems syscalls are not present. You can use specs nosys.specs or
rdimon.specs; or use custom syscalls."
Can someone clarify if these are correct assumptions?
Thanks
I am trying to link a c program that I compiled with the gcc compiler. The linker does not find the symbol tdestroy which is a gnu extension to libc (#define __USE_GNU followed by #include <search.h>). Is there an additional library that I have to link with in order for the linker to find this symbol?
~Update~: I just realized that it does indeed link on my Linux environment but on Windows, I still get a undefined reference to 'tdestroy' error with mingw/gcc, even after using _GNU_SOURCE instead of __USE_GNU.
Don't use __USE_GNU. That's an internal GLIBc macro. The tdestroy man page says the macro you need
to define at the beginning is _GNU_SOURCE.
#define _GNU_SOURCE
#include <search.h>
void *td = tdestroy;
int main(){}
compiles with no linker error (no extra libraries needed).
You should never define __USE_GNU (sic), it is an internal symbol. You need to define _GNU_SOURCE, see Feature Test Macros.
If you do that, the tdestroy function will become available.
It is also a good idea to build with -Werror=implicit-function-declaration, so that missing prototypes lead to a compiler failure, and not later to a linker failure.
I have downloaded libgcrypt library source code and I want to customize this standard shared library by adding my function inside one particular
source code file .
Although compilation/build process of customized shared library is successful, but it shows error at linking time.
Here is what I have done .
inside /src/visibility.c file, I have added my custom function,
void MyFunction(void)
{
printf("This is added just for testing purpose");
}
I have also include function prototype inside /src/gcrypt.h
void MyFunction(void);
#build process
./configure --prefix=/usr
sudo make install
nm command find this custom function.
nm /usr/lib/libgcrypt.so | grep MyFunction
000000000000dd70 t MyFunction
Here is my sample code to access my custom function.
//aes_gcrypt_example.c
#include <stdio.h>
#include <gcrypt.h>
#include <assert.h>
int main()
{
MyFunction();
return 0;
}
gcc aes_gcrypt_example.c -o aes -lgcrypt
/tmp/ccA0qgAB.o: In function `main':
aes_gcrypt_example.c:(.text+0x3a2): undefined reference to `MyFunction'
collect2: error: ld returned 1 exit status
I also tried by making MyFunction as extern inside gcrypt.h, but in that case also I am getting same error.
Why is this happening ?
Is the customization of standard library is not allowed ?
If YES, then is there any FLAG to disable to allow customization ?
If NO, what mistake I am making ?
It would be great help if someone provide some useful link/solution for the above mentioned problem. I am using Ubuntu16.04 , gcc 4.9.
Lower-case t for the symbol type?
nm /usr/lib/libgcrypt.so | grep MyFunction
000000000000dd70 t MyFunction
Are you sure that's a visible function? On my Ubuntu 16.04 VM, the linkable functions defined in an object file have T (not t) as the symbol type. Is there a stray static kicking around and causing confusion? Check a couple of other functions defined in libgcrypt.so (and documented in gcrypt.h) and see whether they have a t or a T. They will have a T and not t. You'll need to work out why your function gets a t — it is not clear from the code you show.
The (Ubuntu) man page for nm includes:
The symbol type. At least the following types are used; others
are, as well, depending on the object file format. If lowercase,
the symbol is usually local; if uppercase, the symbol is global
(external).
The line you show says that MyFunction is not visible outside its source file, and the linker agrees because it is not finding it.
Your problem now is to check that the object file containing MyFunction has a symbol type T — if it doesn't the problem is in the source code.
Assuming that the object file shows symbol type T but the shared object shows symbol type t, you have to find what happens during the shared object creation phase to make the symbol invisible outside the shared object. This is probably because of a 'linker script' that controls which symbols are visible outside the library (or maybe just compilation options). You can search on Google with 'linker script' and various extra words ('tutorial', 'provide', 'example', etc) and come up with links to the relevant documentation.
You may need to research documentation for LibTool, or for the linker BinUtils. LibTool provides ways of manipulating shared libraries. In a compilation command line that you show in a comment, there is the option -fvisibility=hidden. I found (mostly by serendipitous accident) a GCC Wiki on visibility. See also visibility attribute and code generation options.
This is part of a series of at least two closely related, but distinct questions. I hope I'm doing the right thing by asking them separately.
I'm trying to get my Visual C++ 2008 app to work without the C Runtime Library. It's a Win32 GUI app without MFC or other fancy stuff, just plain Windows API.
So I set Project Properties -> Configuration -> C/C++ -> Advanced -> Omit Default Library Names to Yes (compiler flag /Zl) and rebuilt. Let's pretend I have written a suitable entry point function, which is the subject of my other question.
I get two linker errors; they are probably related. The linker complains about unresolved external symbols __fltused and _memcpy in foobar.obj. Needless to say, I use neither explicitly in my program, but I do use memcpy somewhere in foobar.cpp. (I would have used CopyMemory but that turns out to be #defined to be identical to memcpy...)
(I thought I could get rid of the memcpy problem by using a compiler intrinsic, like #pragma intrinsic(memcpy), but this makes no difference.)
If I look at the preprocessor output (adding /P to the compiler command line), I see no references to either __fltused or _memcpy in foobar.i.
So, my question is: Where do these linker errors come from, and how do I resolve them?
__fltused implies you are using or have at least declared some floats or doubles. The compiler injects this 'useless' symbol to cause a floating support .obj to get loaded from the crt. You can get around this by simply declaring a symbol with the name
#ifdef __cplusplus
extern "C" {
#endif
int _fltused=0; // it should be a single underscore since the double one is the mangled name
#ifdef __cplusplus
}
#endif
WRT _memcpy - memcpy is a __cdecl function, and all cdecl functions get an automatic _ as part of their decoration. so, when you say "__cdecl memcpy" - the compiler & linker go looking for a symbol called '_memcpy'. Intrinsic functions - even explicitly requested - can still be imported if the build settings have debug settings that contra-indicate intrinsics. So you are going to need to implement your own memcpy and related functions at some point anyway.
I recommend setting the "generate assembly listing" (or some such) compiler option for foobar.cpp once, and then inspecting the assembler code. This should really tell you where these symbols are used.