Removing symbols from object file on windows - windows

Is there any way to remove(or make local) symbols in an object file? I'm looking for something like objcopy --keep-global-symbol on linux.
Or maybe there is a way to tell linker which symbols should be hidden? I found this page: https://msdn.microsoft.com/en-us/library/28d6s79h.aspx which describes .Def files and my impression from the reading is that I can use these files not only for dll's but also for static libraries. Is this true?
I need this, because I link with 2 libraries A and B which export the same symbols. A is linked dynamically and B is linked statically. If a symbols is exported both by A and B I want my app to use symbol from A, plus I want to use some symbols from B (which are only in B).

If you install one of the Mingw GCC ports, e.g. mingw-w64,
then you will also get the ports of binutils for Windows PE binaries and you will be able to use
the familar objcopy --keep-global-symbol.
Find it in the bin directory of your chosen installation, e.g. C:\mingw-w64\x86_64-7.2.0-posix-seh-rt_v5-rev0\mingw64\bin
However...
You may well have an XY problem here,
because the linker will resolve a symbol from the first library in the input sequence
that defines it and ignore definitions in later libraries; so you may be able to
give preference to the definitions from the DLL just by linking it before the static
library. An illustration:
foo_static.c
#include <stdio.h>
void foo(void)
{
puts("foo_static");
}
bar_static.c
#include <stdio.h>
void bar(void)
{
puts("bar_static");
}
foo_dynamic.c
#include <stdio.h>
__declspec(dllexport) void foo(void)
{
puts("foo_dynamic");
}
gum_dynamic.c
#include <stdio.h>
__declspec(dllexport) void gum(void)
{
puts("gum_dynamic");
}
Compile the *_static.c source files and archive the object files in a static library static.lib:
>cl -c *_static.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
bar_static.c
foo_static.c
Generating Code...
>lib -out:static.lib *_static.obj
Microsoft (R) Library Manager Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Compile the *_dynamic.c source files and link the object files in a DLL dynamic.dll:
>cl -c *_dynamic.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
foo_dynamic.c
gum_dynamic.c
Generating Code...
>link -dll -out:dynamic.dll *_dynamic.obj
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
Creating library dynamic.lib and object dynamic.exp
Notice that function foo is defined (differently) in static.lib and dynamic.dll.
bar is defined only in static.lib. gum is defined only in dynamic.dll
Here is a program source that calls foo, bar and gum:
main.c
extern void foo();
extern void bar();
extern void gum();
int main()
{
foo();
bar();
gum();
return 0;
}
which we compile:
>cl -c main.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.11.25547 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
main.c
Then we link a program prog like this:
>link -out:prog.exe main.obj static.lib dynamic.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
with static.lib first. The program outputs:
>prog.exe
foo_static
bar_static
gum_dynamic
So foo was resolved from static.lib and the definition from
dynamic.dll was ignored.
Now lets relink with the order of the libraries reversed, and run prog again:
>link -out:prog.exe main.obj dynamic.lib static.lib
Microsoft (R) Incremental Linker Version 14.11.25547.0
Copyright (C) Microsoft Corporation. All rights reserved.
>prog.exe
foo_dynamic
bar_static
gum_dynamic
This time, foo was resolved from dynamic.dll and the definition from static.lib
was ignored.

Related

Newly installed g++ on wsl has problem recognizing c++11 STL types

Hi: I'm using WSL+Ubuntu20.04 on win10, installed g++ using sudo apt-get.
g++ --version
g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Fairly new, then I have this code modified from cppreference.com:
#include <iostream>
#include <thread>
#include <shared_mutex>
#include <mutex>
using namespace std;
class Counter {
int value;
shared_mutex m;
public:
...
My command line is:
g++ rwlock.cpp -std=c++11
It doesn't compile, saying that:
error: ‘shared_mutex’ does not name a type
10 | shared_mutex m;
And some other errors, all point to that I don't have these c++11 types defined.
Did I missing anything while installing g++ or should add more command line options when compiling?
Thanks!
The std::shared_mutex was not provided until c++ 17. https://en.cppreference.com/w/cpp/thread/shared_mutex
So to fix this issue, you just need to change the compilation command to
g++ rwlock.cpp -std=c++17

Visual Studio C++ Preprocessor behavior changed?

I'm using Visual Studio C++ Preprocessor to preprocess some files which are not C or C++ files (I find it very convenient).
Recently I upgraded from Visual Studio 2010 to 2015 and found out that the preprocessor behavior slightly changed. Some text that works on VS2010 gives an error on VS2015 and vice versa.
To illustrate the difference, here are two one liner files, ok2010.c and ok2015.c, and the preprocessing command line running with VS2010 and VS2015:
ok2010.c:
#define X `0'`'
ok2015.c:
#define X `0'`'`'
Preprocessing on VS2010:
c:\>cl -E ok2010.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
ok2010.c
#line 1 "ok2010.c"
c:\>cl -E ok2015.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
ok2015.c
#line 1 "ok2015.c"
ok2015.c(1) : error C2001: newline in constant
Preprocessing on VS2015:
c:\>cl -E ok2010.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
ok2010.c
#line 1 "ok2010.c"
ok2010.c(1): error C2001: newline in constant
c:\>cl -E ok2015.c
Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
ok2015.c
#line 1 "ok2015.c"
I guess that the preprocessor handles differently tick (') and backtick (`), and expects them to be balanced. When they are not balanced it reports a newline in a quoted constant expression.
VS2010 ignores backtick entirely and expects only the ticks to be balanced, so this behavior makes sense.
However, I can't make sense of VS2015 behavior since it works only when both ticks and backticks are not balanced...
Any idea?

Building luafilesystem for Lua for Windows

I haven't a clue when it comes to building makefiles - I am trying to build luafilesystem in Windows 7 x86 for use with Lua for Windows. I have scoured the internet for tutorials but I just can't figure it out. I got as far as to run NMAKE in the Developer Command Prompt but I received the following error:
C:\Users\Me\Desktop\luafilesystem-master\luafilesystem-master>nmake -f Makefile.win
Microsoft (R) Program Maintenance Utility Version 12.00.21005.1
Copyright (C) Microsoft Corporation. All rights reserved.
cl /c /Fosrc\lfs.obj /MD /O2 /I"c:\lua5.1\include" src\lfs.c
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.30723 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
lfs.c
src\lfs.c(63) : fatal error C1083: Cannot open include file: 'lua.h': No such file or directory
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\BIN\cl.EXE"' : return code '0x2'
Stop.
I'm not sure what I'm doing wrong. There was no lua.h in the set of files I downloaded directly from the official LuaFileSystem repository.
All I want is to install lfs to use in lua. If you can't figure out what I'm doing wrong but happen to know an easier way, please share. I hope I've provided enough information. Thanks.
You need to have the Lua interpreter you are compiling against to be compiled and available on your computer to access its header files (lua.h and few others) and Lua library/dll files. After you compile the right version of Lua interpreter you need (whether Lua 5.1 or Lua 5.2), set the environmental variables (or update the paths in the make file) LUA_LIBDIR, LUA_INC and LUA_LIB to point to your lua-folder, lua-folder\src, and the lua lib correspondingly.

Mingw32 cross compile with c++11

How can I cross compile on Linux for Windows with code that uses C++11 features? So far I've attempted the following:
#include <stdio.h>
class foo
{
public:
const char* getstr() { return "hello world"; }
};
int main()
{
printf("Hello, World!\n");
foo f;
f.getstr();
auto q = f.getstr();
return 0;
}
This fails to build with:
i586-mingw32msvc-g++ cpp11_test.cpp
cpp11_test.cpp: In function ‘int main()’:
cpp11_test.cpp:15: error: ISO C++ forbids declaration of ‘q’ with no type
cpp11_test.cpp:15: error: invalid conversion from ‘const char*’ to ‘int’
No problem I thought, I just need the -std=c++11 option:
i586-mingw32msvc-g++ cpp11_test.cpp -std=c++11
cc1plus: error: unrecognized command line option "-std=c++11"
Still no luck, --version output is:
i586-mingw32msvc-g++ --version
i586-mingw32msvc-g++ (GCC) 4.2.1-sjlj (mingw32-2)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Is there another option to make this work? Or a new version? How would I get a new version if its not in the package manager, would I have to build a newer compiler from source using the host OS'es compiler?

Missing Symbols in VS2010 Build

Using VS2010 with an older Win32 C/C++ Project,
I'm trying to track down missing symbols in a project recently built. In the past I've used lib.exe to examine contents of libraries, but that doesn't seem to work anymore. For example
lib /List:libname.lib
returns only:
Microsoft (R) Library Manager Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved..
So what are the best practices for tracking down missing symbols in VS2010?
Thanks.
I repro, the command line syntax you use is wrong. Omit the colon:
C:\projects\cpptemp3\Debug>lib /list cpptemp3.lib
Microsoft (R) Library Manager Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
Debug\stdafx.obj
Debug\test.obj
As far as looking for symbols goes, I use dumpbin /symbol [lib or obj file]

Resources