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?
Related
I am trying to compile an OpenMP code, on Windows. The linker options /stack:10000000 and /largeaddressaware are meant to be added, to avoid stack overflow errors. They are not recognised.
I think /largeaddressaware might be unnecessary as I am using a 64 bit compiler. But I do need to make /stack work.
I am using the "Intel oneAPI command prompt for Intel 64 for Visual Studio 2022" and Intel Fortran to compile. It's not clear to me how the /stack flag is meant to be added, but here is what I tried:
ifort -c modules.f90
ifort -c MainCode.f90 /openmp /STACK:10000000 /LARGEADDRESSAWARE
ifort modules.obj MainCode.obj -o Code.exe /openmp /STACK:10000000 /LARGEADDRESSAWARE
What I get is,
C:\Users\e\Desktop\code>ifort -c modules.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.6.0 Build 20220226_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
C:\Users\e\Desktop\code>ifort -c MainCode.f90 /openmp /STACK:10000000 /LARGEADDRESSAWARE
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.6.0 Build 20220226_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
ifort: command line warning #10006: ignoring unknown option '/STACK:10000000'
ifort: command line warning #10006: ignoring unknown option '/LARGEADDRESSAWARE'
C:\Users\e\Desktop\code>ifort modules.obj MainCode.obj -o Code.exe /openmp /STACK:10000000 /LARGEADDRESSAWARE
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.6.0 Build 20220226_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.
ifort: command line warning #10006: ignoring unknown option '/STACK:10000000'
ifort: command line warning #10006: ignoring unknown option '/LARGEADDRESSAWARE'
Microsoft (R) Incremental Linker Version 14.33.31629.0
Copyright (C) Microsoft Corporation. All rights reserved.
-out:Code.exe
-subsystem:console
-defaultlib:libiomp5md.lib
-nodefaultlib:vcomp.lib
-nodefaultlib:vcompd.lib
modules.obj
MainCode.obj
Is there another command I could be using instead? Or am I using /stack wrong?
I tried both capital /STACK and lower case /stack. Neither worked. I also tried -large-address-aware as I had found that somewhere, but that didn't work either. I tried /stack 10000000 too with no luck.
You must put /link (lowercase) on the line before linker options such as /stack and /largeaddressaware. This tells the compiler driver to pass them on to the linker.
There is a downside to setting a very large stack reserve value in that this reduces the 2GB Windows allocates for static code and data, plus some that Windows itself uses. This limit also applies to 64-bit Windows! Rather than start with an insanely large value, start at something like 1000000 and go up from there.
I am following this guide in order to build Opencascade frmo source:
https://github.com/tpaviot/oce/blob/master/BUILD.MINGWw64.md
I have done everything up to the MSYS part.
The CMake configuration and generation was succesfull.
I now have a folder with all the things that CMake generated.
So i start MSYS2, and i cd into that directory.
Then i type make.
This is what i get:
User1#User1-PC MSYS ~/Desktop/OpenCascade project/oce/BUILD
$ make
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\Users\User1\Desktop\OpenCascade project\oce\BUILD>
As you can see, nothing happens, no compilation. There is a prompt for me to type. But nothing gets executed.
EDIT:
*I redid the proccess in a new directory, so that no space characters exist in my directory. Problem still remains.
*When i run make --version, i get this:
$ make --version
GNU Make 4.3 Built for x86_64-pc-msys Copyright (C) 1988-2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
*When i exit the prompt (CONTROL + C) i get this:
C:\Users\User1\Desktop\OPENCAS\oce\BUILD>make: *** [Makefile:1734: cmake_check_build_system] Interrupt
*These are the contents of the makefile, line 1734:
$(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles\Makefile.cmake 0
*When i run make VERBOSE=1, i get this:
User1#User1-PC MSYS ~/Desktop/OPENCAS/oce/BUILD
$ make VERBOSE=1
"C:\Program Files\CMake\bin\cmake.exe" -SC:\Users\User1\Desktop\OPENCAS\oce -BC:\Users\User1\Desktop\OPENCAS\oce\BUILD --check-build-system CMakeFiles\Makefile.cmake 0
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
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.
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.
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]