I have a working win32 project that I'm trying to add an x64 platform build to. I've got the x64 build working by allowing Visual Studio 2013 to 'copy it from the win32 settings' and tweaking the results to get it to work. But in the process, something happened to make the win32 version no longer include all of the windows libraries.
When I diff the build commands for the win32 project from the .log files generated before and after adding the x64 platform, all the compiler and linker commands from the 2 logs are identical except for the lists of libraries included in the linker commands:
The Win32 link command includes these libraries before adding x64:
lz32.lib wsock32.lib odbc32.lib odbc cp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NODEFAULTLIB:/NODEFAULTLIB:LIBCMTD /NODEFAULTLIB:LIBCMT
After adding x64, it only includes the first 4:
lz32.lib wsock32.lib odbc32.lib odbccp32.lib /NODEFAULTLIB:/NODEFAULTLIB:LIBCMTD NODEFAULTLIB:LIBCMT
Those first 4 libraries are explicitly included as in both the before and after vcxproj files:
<AdditionalDependencies>lz32.lib;wsock32.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
And the rest of the libraries are not mentioned specifically in either the before or after vcxproj files. There are no specific errors in the 'after' log compalining about bad or wrong versions of those libraries - they're simply not included. As far as I know, no changes have been made to the win32 sections of the vcxproj file, so what could have caused the windows libraries to have been left out? Or better yet, what normally causes them to be included?
Never mind. I found it. Somewhere along the line, when I was editing my vcxproj file to get the X64 configuration to build, I accidentally changed the AdditionalDependencies macro inclusions for my win32 builds from using %() notation to wrongly using $(), causing the built-in standard dependencies from being ignored. Sorry for the stupid question:
C:\ROBY>diff win32proj.txt x64proj.txt
69c69
< <AdditionalDependencies>lz32.lib;wsock32.lib;odbc32.lib;odbccp32.lib;**%**(AdditionalDependencies)</AdditionalDependencies>
---
> <AdditionalDependencies>lz32.lib;wsock32.lib;odbc32.lib;odbccp32.lib;**$**(AdditionalDependencies)</AdditionalDependencies>
Related
We have a large cmake based C++ project for Linux where we build boost ourselves via cmake exernal project.
The project used to build also on Windows for the classical Intel compiler. But I have no access to this old running configuration.
I use Intel oneAPI 2023.0 with LLVM based icx compiler (clang 15?) and a current MSVC community edition.
I built boost (1.81.0) without a target (as I still struggle with openAPI target) with --layout=system, hence lib names like libboost_atomic.a
In our C++ we do not let CMake search for boost but add the boost libs via target_link_libraries().
When I compile our application with icx I get a link error
Linking CXX executable ....\bin\cfs.exe LINK: command
"C:\PROGRA~2\Intel\oneAPI\compiler\latest\windows\bin\icx.exe /nologo
#CMakeFiles\cfs.dir\objects1 /Qoption,link, /machine:x64
/INCREMENTAL:NO /Qoption,link,/subsystem:console -Qiopenmp
/Qoption,link,/LIBPATH:C:\PROGRA~2\Intel\oneAPI\compile
r\latest\windows\bin\intel64\ifort.exe
/Qoption,link,/LIBPATH:C:\Users\fabia\code\master\release_icx\lib
[....] ....\lib\libboost_log_setup.lib
....\lib\libboost_serialization.lib [.....] /link
/out:....\bin\cfs.exe /implib:. ...\bin\cfs.lib
/pdb:C:\Users\fabia\code\master\release_icx\bin\cfs.pdb /version:0.0
/MANIFEST /MANIFESTFILE:....\bin\cfs.exe .manifest"
I get
fatal error LNK1104: file
"libboost_serialization-clangw16-mt-x64-1_81.lib" not found.
I have no idea where the string clangw16-mt-x64-1_81 comes from.
You can link the libraries present in the boost library path to your project either from the Command Prompt or within the Visual Studio IDE. Please refer to the below link for more details.
https://www.boost.org/doc/libs/1_81_0/more/getting_started/windows.html
If you do not find any binaries, you can add the macro BOOST_ALL_NO_LIB which tells the config system not to automatically select which libraries to link. Please refer to the below link for more details.
https://www.boost.org/doc/libs/1_81_0/libs/config/doc/html/index.html
Or
You can use the target Boost::disable_autolinking to disable automatic linking. Please refer to the below link for more details.
https://cmake.org/cmake/help/latest/module/FindBoost.html
I am trying to compile a simple PETSc program (Which works when compiled in Cygwin) in Visual Studio 2019. But I am unable to compile it in VS2019 even after linking all the necessary library files. I have given below the options I have used in VS2019 for compiling petsc program. I see that the compiler is not able to identify the Petsc variables which leads me to believe that I have not done the library linking part properly.
My guide for linking the files is from compiling the program in cygwin using the following command (compiles and run perfectly):
/home/snarayanan1/petsc-release/lib/petsc/bin/win32fe/win32fe.exe ifort -MT -O3 -fpp -I/home/snarayanan1/petsc-release/include -I/home/snarayanan1/petsc-release/arch-ci-mswin-opt-impi/include -I/cygdrive/c/PROGRA~2/Intel/oneAPI/mpi/2021.5.0/include petsc_solver.F90 Test_petsc.F90 -L/cygdrive/c/cygwin64/home/snarayanan1/petsc-release/arch-ci-mswin-opt-impi/lib -L/cygdrive/c/PROGRA~2/Intel/oneAPI/mkl/2022.0.0/lib/intel64 -lpetsc mkl_intel_lp64_dll.lib mkl_sequential_dll.lib mkl_core_dll.lib /cygdrive/c/PROGRA~2/Intel/oneAPI/mpi/2021.5.0/lib/release/impi.lib Gdi32.lib User32.lib Advapi32.lib Kernel32.lib Ws2_32.lib -o Test_petsc
Fortran -> General -> Additional Include Directories:
C:/cygwin64/home/snarayanan1/petsc-release/include; C:/cygwin64/home/snarayanan1/petsc-release/arch-ci-mswin-opt-impi/include; C:/Program Files (x86)/Intel/oneAPI/mpi/2021.5.0/include
Linker -> General -> Additional Library Directories:
C:/cygwin64/home/snarayanan1/petsc-release/arch-ci-mswin-opt-impi/lib; C:/Program Files (x86)/Intel/oneAPI/mkl/2022.0.0/lib/intel64; C:/Program Files (x86)/Intel/oneAPI/mpi/2021.5.0/lib/release
Linker -> Input -> Additional Dependencies:
libpetsc.lib mkl_intel_lp64_dll.lib mkl_sequential_dll.lib mkl_core_dll.lib C:/Program Files (x86)/Intel/oneAPI/mpi/2021.5.0/lib/release/impi.lib Gdi32.lib User32.lib Advapi32.lib Kernel32.lib Ws2_32.lib
This image shows the errors I get
Can someone let me know where I am going wrong (or) direct me to documentation that talks about linking PETSc to visual Studio in detail?
Thank You.
The configurations that you have done look fine to me. The issue you ran into arises from other places.
Try
Fortran Tab:
• Preprocessor | Preprocess source files | Yes
I'm working on a cross-platform project which has some hand-written assembly to optimize performance for various CPU architectures. I'm converting this project to CMake from a proprietary build system, starting with compiling using Visual Studio on Windows. For x86 and AMD64, I've been able to assemble and link everything just fine, but I can't get it to work on ARM64 (or presumably ARM32, though I haven't tried that yet).
I'm including the ASM files in my sources as follows:
if(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64")
list(APPEND SOURCES
amd64/aesasm.asm
...)
set_source_files_properties(
amd64/aesasm.asm
...
PROPERTY LANGUAGE ASM_MASM)
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "X86")
# ...
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64")
list(APPEND SOURCES
arm64/fdef_asm.asm
...)
set_source_files_properties(
arm64/fdef_asm.asm
...
PROPERTY LANGUAGE ASM_MASM)
Then in my top-level CMakeLists.txt, I enable MASM using enable_language(ASM_MASM). For x86 and AMD64, CMake automatically finds ml/ml64.exe, configures the Visual Studio project correctly, and everything works.
But for ARM64, if I try the same thing, I get this error from Visual Studio when trying to build: MSB3721: The command "echo MASM not supported on this platform. As far as I can tell, this is because Visual Studio considers ARM assembly to be a different dialect, "MARMASM", with a different executable name for the assembler (armasm/armasm64.exe).
I tried setting enable_language(ASM_MARMASM) in my ARM64 toolchain file, but CMake does not recognize this as an ASM dialect, and gives me this error:
CMake Error: Could not find cmake module file: CMakeDetermineASM_MARMASMCompiler.cmake
CMake Error: Could not find cmake module file: F:/os/src/symcrypt/bin/CMakeFiles/3.15.3/CMakeASM_MARMASMCompiler.cmake
CMake Error at CMakeLists.txt:49 (enable_language):
No CMAKE_ASM_MARMASM_COMPILER could be found.
I also tried manually setting the assembler:
get_filename_component(VS_TOOLS_DIRECTORY ${CMAKE_LINKER} DIRECTORY)
find_file(ARM64_COMPILER "armasm64.exe" HINTS ${VS_TOOLS_DIRECTORY})
set(CMAKE_ASM_MARMASM_COMPILER ${ARM64_COMPILER})
enable_language(ASM_MARMASM)
message(STATUS "Manually set assembler to ${CMAKE_ASM_MARMASM_COMPILER}")
But this does not work either; I still get an error that No CMAKE_ASM_MARMASM_COMPILER could be found.
How can I include ARM/ARM64 assembly in my project?
Looks like CMake (still) does not have support for this. I found some bits in the .NET source code to work around it:
https://github.com/dotnet/runtime/blob/f8f63b1fde85119c925313caa475d9936297b463/eng/native/functions.cmake#L173-L207
and
https://github.com/dotnet/runtime/blob/f8f63b1fde85119c925313caa475d9936297b463/eng/native/configurecompiler.cmake#L611-L626
edit: As reference, here's the commit for a project I had this requirement for: https://dyncall.org/pub/dyncall/dyncall/rev/451299d50c1a
I asked this on the openssl-users mailing list with no replies, so I thought I'd try here.
I am trying to build a Windows DLL that includes the static OpenSSL FIPS libraries. I built the FIPS libraries using perl Configure fips --with-fipslibdir=... -no-shared and then nmake -f ms\nt.mak. I'm using openssl-fips-2.0.5, openssl-1.0.1j, and MS Visual Studio 2010.
Now I'm trying to link the resulting libraries into my DLL. I've followed the instructions in the OpenSSL FIPS 2.0 User's Guide, setting a bunch of environment variables (FIPS_LINK, FIPS_CC, FIPS_CC_ARGS, etc.) and then called fipslink.pl. But I'm getting a "First stage Link failure".
It reports "Integrity check OK" and then compiles fips_premain.c, but when linking the DLL I get a bunch of "locally defined symbol _time64 imported" warnings (as well as strncmp, _errno, abort, fprintf, and others), and then some unresolved external symbols including:
__imp_strncpy
__imp_qsort
__imp_wcsstr
__imp_vsnwprintf
All of the errors come from libeayfips32.lib, libeaycompat32.lib, and ssleay32.lib.
I've played around with adding and removing things like /NODEFAULTLIB:msvcrt and /NODEFAULTLIB:libcmtd, and building with /MT or /MD or neither, but I keep getting linker errors each time. What am I missing?
I speculate that the "-no-shared" switch to the Configure script statically links the C standard library. You'd get your static OpenSSL FIPS library, but it would include implementations of printf and friends, as you actually experience.
open file ms\nt.mak then modify line #28 by adding msvcrt.lib msvcrtd.lib at the end , to be like:
EX_LIBS=ws2_32.lib gdi32.lib advapi32.lib crypt32.lib user32.lib msvcrt.lib msvcrtd.lib
then run : nmake -f ms\nt.mak from visual studio command prompt.I hope that no linker messages will appear.
Also try to build the DLL by nmake -f ms\ntdll.mak
Where does an application decide/cause to spawn a new console window (when linking dynamically)?
Is there some define or pragma I may have overlooked or some change in standard behavior in the default runtime dlls? I don't feel very sure these are the right question to ask, please read the Background below and bear with me. I'm glad for every nudge in the right direction.
Background:
A console application (/SUBSYSTEM:CONSOLE) spawns a new daughter-console when started. Other applications using the same sources and configuration setup don't. The only difference (seemingly) are the provided 3rd-party-dlls. Because of the new sub-console, I cannot redirect the output anymore (app.exe > dump.txt). Redirection is vital for this application.
I'm building that c/c++ console application on MS Visual Studio 2008. The application links dynamically to an awful messy lot of dlls. The whole Library-pack is provided by one 3rd party as release build with no debug info. The dll-pack includes, among others, msvcr90.dll (9.0.30729.1) msvcp90.dll (9.0.30729.1) and msvcr80.dll (8.0.50727.42).
Whatever causes this seem to be very global, since the first fprintf to stdout or stderr in main() goes to the new console window, not to the shell where the application was started.
In my first tries, I built the Application on Visual Studio 2005 (which we used until the latest version of the library package) and 2010 (which is recommended by the dll-provider). Those builds didn't spawn consoles but did crash when memory was freed that probably was allocated in a different version of the runtime. Using Dependency Walker I could find the "main" runtime the dlls were linked against.
PS: Afaik linking against 2 different runtimes is dangerous enough. But it is an improvement over the previous version of the dll-pack, which included the r, c and m variants of 71, 80, 90 runtime dlls.
PPS: I mainly developed on linux before, so I could have made some very basic mistakes. Please accept my apologies for my ignorance in advance.
Update 1:
Following Anton Kovalenko's advice, I chipped more and more libraries away. Then I removed more code. Finally I ended with:
#include <stdio.h>
#include <Windows.h>
int main(int _argc, char **_argv)
{
printf("application running ...\n");
fflush(stdout);
Sleep(2000);
exit(0);
}
Configuration Properties > c/c++ > Command Line:
/Od /Ob2 /D "_MBCS" /FD /EHsc /MD /Fo"a4input_interface_6.12_1.dir\Release\\" /Fd"a4input_interface_6.12_1.dir\Release\vc90.pdb" /W3 /nologo /c /TC /errorReport:prompt
Configuration Properties > Linker > Command Line:
/OUT:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe" /VERSION:0.0 /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
Configuration Properties > Manifest Tool > Command Line
/nologo /outputresource:"..\..\..\build\win32_release\inputinterfaces\.inter_612_1_32.exe;#1"
I still have the problem, that a shell is spawned and stdout cannot be redirected using (i.e. app.exe > test.txt). So the text "application running ..." isn't printed on the same shell where the exe is started.
I'm still clueless and still grateful for every hint.
Update 2:
I created a batch-file for the command lines. If I compile it with that, the exe works as intended.
cl.exe /Od /Ob2 /D "_MBCS" /FD /EHsc /MD /Fo"a4input_interface_6.12_1.dir\Release\\" /Fd"a4input_interface_6.12_1.dir\Release\vc90.pdb" /W3 /nologo /c /TC /errorReport:prompt main.c
link.exe /OUT:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe" /VERSION:0.0 /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib a4input_interface_6.12_1.dir\Release\main.obj
mt.exe /manifest a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest /nologo /outputresource:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe";#1"
So there is something visual studio does that isn't reflected in the Command Line it gives. What and why?
I'm still clueless and still grateful for every hint.
Solution:
There was a debugger configured for this name of executable. That's why I had this behavior:
inter_612_2_32.exe no sub shell
intes_612_2_32.exe no sub shell
inter_612_1_32.exe spawns sub shell
intes_612_1_32.exe no sub shell
Using ProcessExplorer I found out, that inter_612_1_32.exe is a sub process of DbgHost.exe. Unfortunately I didn't follow that lead and forgot about it.
The loaded Dlls actually didn't matter. The problem was an entry in the Registry in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\inter_612_1_32.exe
I guess the entry was created by DebugDiag, Application Verifier or some other tool but not removed when deleted in the tool's GUI.
Thanks to everyone who thought about it.
Some of third-party dlls may be calling FreeConsole and AllocConsole, which have the effect you describe. If it's done within DllMain for DLL_PROCESS_ATTACH, it will happen before entering main() for libraries which are your project dependencies.
There seems to be no alternative explanation related to your build environment.
You can learn more if you create a project which will use LoadLibrary for suspected dlls instead of linking against their import libraries: if some of them (or their dependencies) does FreeConsole and AllocConsole in DllMain, it will happen during LoadLibrary call.