Link problems on Release x64 - visual-studio-2010

I have a Visual Studio 2010 C++ project that links statically to tinyxmlSTL 2.5.5 (tinyxmlSTL.lib) and zlib 1.2.7. (zlibstat.lib). There are 4 builds in total covering both x86 and x64 as well as Debug and Release.
All combinations produce working builds except for Release x64 which gets a bunch of errors like this:
MSVCRT.lib(MSVCR100.dll) : error LNK2005: free already defined in LIBCMT.lib(free.obj)
...and a single warning:
LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
If I add /NODEFAULTLIB:MSVCRT to linker options for the application then I get this:
zlibstat.lib(ioapi.obj) : error LNK2001: unresolved external symbol __imp__ftelli64
zlibstat.lib(ioapi.obj) : error LNK2001: unresolved external symbol __imp__fseeki64
Basically, all the projects (app and two libs) are set to use Multi-threaded (/MT) option in Release builds and yet x86 builds just fine while x64 suffers from above issues.
Any help or idea is highly appreciated.

You need to double check your settings for x64. One of the projects is using the /MD flag rather than /MT.
As per the MSVC docs, The MSVCRT.lib is invoked by using /MD.
EDIT :
As per your comments, it sounds like zlib is the likely culprit.
zlib has both a static and dll version, but both of these use the /MD flag by default, so unless you changed that while building zlib - that's your issue.
To build zlib using /MT:
If you've not already done so, install CMake
Download and extract zlib to e.g. C:\devel. The download links are about halfway down the homepage. Currently this provides zlib version 1.2.7.
To work around this CMake bug, add
if(CMAKE_SIZEOF_VOID_P EQUAL 8 AND MSVC)
set_target_properties(zlibstatic PROPERTIES STATIC_LIBRARY_FLAGS "/machine:x64")
endif()
to the end of C:\devel\zlib-1.2.7\CMakeLists.txt
In a VS10 command prompt, cd C:\devel\zlib-1.2.7
cmake -H. -Bbuild -G"Visual Studio 10 Win64"
This gets you a VS sloution C:\devel\zlib-1.2.7\build\zlib.sln which you can open. Change the settings for the "zlibstatic" target to /MT and /MTd for Release and Debug respectively.
Building each will yield zlibstatic.lib in a subdirectory of build; either "Release" or "Debug".

In the project properties for ALL projects, check that they all use the same runtime type: either DLL or static
This can be found under Project Properties -> C/C++ -> Code Generation -> Runtime Library. Make sure you have the Release x64 build selected.
The particular value isn't very important (in terms of compile errors) but they should all be the same

I know you say that all your libs are linking with /MT but that error suggests that one of them isn't. Re-check that the correct libs are being linked with the x64 Release build.

Related

linking boost on Windows asks for versioned lib

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

Building ARM64 ASM in Visual Studio with CMake

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

What does -Ot flag stand for in Visual Studio 2017?

I am getting error
Error C1007 unrecognized flag '-Ot' in 'p2'
but unable to find -Ot in the command line string of the project. Googling did not help. Anyone know what does that flag stand for ?
I had a similar issue on a project that I was compiling. It seems to be caused when MSVC 2017 linker tries to link a dependency library ".lib" to your project and it was compiled with Optimization flag /Ot enabled. That is why you can not see it on command line of your own project. You can try one of these actions.
Recompile your libs without /Ot enabled (Properties → C/C++ → Optimization → Favor Size or Speed → Neither), then recompile whole project.
Update MSVC 2017 toolchain to the latest one, which should be 14.14.26428. After updating, recompile your project. It is strange, but in my machine configuration, toolchain 14.13 couldn't link libraries compiled with newer toolchains and /Ot enabled.
Both solutions worked in my case, but I ended up using number 2.
Just for future reference to this error msg:
I got this error with no -Ot option set, the error message was misleading. Turned out that I tried to build a project with a 140 toolset (VS2015 - forgot to upgrade to 141) with .dll and .lib dependencies already built with 141 (VS2017). After updating the toolset to 141 the project could be built.
You should find this flag in the Optimization property page of your project.
-Ot (/Ot) option is the Favor Fast Code flag (Attempts to offer improvements in execution time over space)
According to the Microsoft Visual C++ Documentation (https://learn.microsoft.com/en-us/cpp/build/reference/os-ot-favor-small-code-favor-fast-code),
If you use /Os or /Ot, then you must also specify /Og to optimize the
code.
Happened to me while building nmap. Executables did not have /GL, while libnetutil did. Removing /GL from libnetutil fixed it. Or, if possible (and desired), align /GL to all dependent targets (lib, dll/exe).

CMake to generate a MSVC CUDA project that targets newer devices

My PC has a GTX 580 (compute capability 2.0).
I want to compile a CUDA source that uses dynamic parallelism, a feature introduced in compute capability 3.5.
I know I will not be able to run the program on my GPU, however, it should be possible to compile this code on my machine. I'm assuming this because I can compile with no problems the CUDA samples that use 3.5 capability. These samples come with Visual Studio projects that were "manually generated" (I guess).
I believe my problem is with CMake. I'm using CMake to generate a Visual Studio 2012 project.
My first CMakeLists.txt looked like this:
PROJECT(sample-cuda-tests)
FIND_PACKAGE(CUDA REQUIRED)
INCLUDE_DIRECTORIES(${CUDA_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)
FILE(GLOB_RECURSE includes ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h )
FILE(GLOB_RECURSE sources ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cu )
CUDA_ADD_EXECUTABLE(sample-cuda-tests ${includes} ${sources})
TARGET_LINK_LIBRARIES(sample-cuda-tests ${CUDA_LIBRARIES})
Then, when compiling with the generated Visual Studio 2012 project, I got a warning followed by an error:
warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
error : calling a __global__ function from a __global__ function is only allowed on the compute_35 architecture or above
What was expected. Then I added
list(APPEND CUDA_NVCC_FLAGS -gencode arch=compute_35,code=sm_35)
to the CMakeLists. The warning disappeared, but I got:
error : kernel launch from __device__ or __global__ functions requires separate compilation mode
Ok. So I added to the CMakeLists:
set(CUDA_SEPARABLE_COMPILATION ON)
...and received this:
fatal error : nvcc supports '--relocatable-device-code=true (-rdc=true)', '--device-c (-dc)', and '--device-link (-dlink)' only when targeting sm_20 or higher
What is weird because I thought I was targeting sm_35 (higher than sm_20).
Later I discovered I can set some options directly in CUDA_ADD_EXECUTABLE command. So I removed the line that was appending values to CUDA_NVCC_FLAGS and changed CUDA_ADD_EXECUTABLE command to:
CUDA_ADD_EXECUTABLE(sample-cuda-tests ${includes} ${sources} OPTIONS -gencode arch=compute_35,code=sm_35)
What I got was:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v6.0\bin\crt\link.stub : fatal error C1083: Cannot open compiler generated file: 'C:/Users/sms/Desktop/sample-cuda-tests/CMakeFiles/sample-cuda-tests.dir/Debug/sample-cuda-tests_intermediate_link.obj': No such file or directory
No idea where to go now. Appreciate any help.
I'm using CUDA SDK 6.0 on Windows 7.
As of CMake 3.1.0, CMake script misses creating a directory to put the intermediate file in.
Add the following snippet in the FindCUDA.cmake
get_filename_component(output_file_path "${output_file}" PATH)
add_custom_command(
TARGET ${cuda_target}
PRE_LINK
COMMAND ${CMAKE_COMMAND} -E make_directory ${output_file_path}
)
right before
if (do_obj_build_rule)
in function CUDA_LINK_SEPARABLE_COMPILATION_OBJECTS
Turned out to be a bug on FindCUDA.cmake.
When setting CUDA_SEPARABLE_COMPILATION to ON, if .cu files are not in the same folder of CMakeLists.txt, intermediate linkage objects are generated in the wrong folder, causing a compilation error that, on Visual Studio, looks like this:
Cannot open compiler generated file: 'project_path/CMakeFiles/project_name/Debug/project_name_intermediate_link.obj': No such file or directory.
I've opened an issue in CMake bug tracker:
http://public.kitware.com/Bug/view.php?id=15016
(the bug is better described there)

Compiling FFMpeg libraries for Visual Studio

I'm trying to use the FFMpeg libraries in a Windows application. I use MingW-w64 to compile FFMpeg with static libraries with architecture once with x86 and once with x86_64.
Currently I'm trying to link the 32bit x86 libraries with my VS2008 application.
The libraries are added to the library path and VS does not complain about being unable to load a .a file.
However I get several uneresolved symbol errors like
ait_rtp_receiver.lib(ait_decoder_lib.obj) : error LNK2001: unresolved external symbol _av_free
I import the FFMpeg header files as extern C and I can see the symbols in the .a without the leading underscore.
What can I do to make the name decoration of Mingw-w64's gcc and of the VS compiler suite compatible?
After spending miserable days trying to get the GCC-Mingw based version of building FFMpeg to work, I reverted to using the Visual Studio or Windows SDK compiler and linker. Using the --toolchain=msvc of the configure script made the build process generate static .a files that are basically .lib files that can be loaded within Visual Studio projects.
I wrote the build steps up and here is a link

Resources