Linking to a platform specific Library - visual-c++

Suppose that I have a 64 and a 32 bit version of a certain library (VC++, VS2013)
(I would really appreciate it if this fact would not draw away attention from the question itself)
Now, Suppose that I have a project that is also compiled under the two latter platforms
Is there a way in which I can make the IDE/linker use the 32 bit version of the library when compiling the project under the 32 bit platform,
and of course, using the 64 bit library when compiling under the 64 bit version
Thanks in advance
Eyal Perry

Recall that all project settings are per configuration/platform pair. When working with Project Properties dialog, pay attention to Configuration and Platform drop-downs at the top.
So, under Linker > Input > Additional Dependencies, simply mention 32-bit LIB file for Win32 platform, and 64-bit LIB for Win64 platform.

You need not to include your library name twice (or as many time your platform or config), as it will be same. Additional lib directory needs to be changed.
Properties->(Select configuration="All Configuration" platform="All Platforms")->Linker->Input->Additional Dependencies->(Include your lib name - which will be same, for x32, x64, release, debug...)
What you really want to change is additional library path! as below:
Properties->(Select configuration="release or debug " platform="win32")->Linker->General->Additional library Directories->Provide here win32 lib directory.
Repeat this for platform x64 givign respective directory.

Related

Upgrading to Universal CRT-how can I get rid of a dependency on vcruntime140.dll and msvcp140.dll?

I have a project that I'm trying to get updated to the universal CRT, and I'm still seeing a dependency on vcruntime140.dll and msvcp140.dll, which I think should have been replaced with a ucrtbase.dll, as well as api-ms-win-crt* dlls.
I've already checked out this response here, and this blog post, which explain things pretty well, but still no luck. Here's what I've changed:
Platform Toolset: Visual Studio 2019 (v142)
Windows SDK version: 10.0 (latest installed version)
Additional include directories: added $(UniversalCRT_IncludePath)
Additional library directories: added $(UniversalCRT_LibraryPath_x86)
I also updated my linker dependencies to this set:
ucrt.lib
vcruntime.lib
msvcrt.lib
user32.lib
advapi32.lib
Wsock32.lib
Crypt32.lib
ws2_32.lib
But when I run dumpbin /dependents mydll.dll
File Type: DLL
Image has the following dependencies:
api-ms-win-crt-string-l1-1-0.dll
api-ms-win-crt-heap-l1-1-0.dll
api-ms-win-crt-runtime-l1-1-0.dll
api-ms-win-crt-stdio-l1-1-0.dll
api-ms-win-crt-filesystem-l1-1-0.dll
api-ms-win-crt-convert-l1-1-0.dll
api-ms-win-crt-time-l1-1-0.dll
api-ms-win-crt-environment-l1-1-0.dll
api-ms-win-crt-utility-l1-1-0.dll
VCRUNTIME140.dll
USER32.dll
ADVAPI32.dll
WSOCK32.dll
CRYPT32.dll
WS2_32.dll
MSVCP140.dll
bcrypt.dll
KERNEL32.dll
Summary
E000 .data
66000 .rdata
E000 .reloc
1000 .rsrc
14A000 .text
Is there something else I'm missing to be able to drop the dependency on the specific CRT version?
I've done some more digging, and found this page that says the following:
Starting in Visual Studio 2015, the CRT has been refactored into new
binaries. The Universal CRT (UCRT) contains the functions and globals
exported by the standard C99 CRT library. The UCRT is now a Windows
component, and ships as part of Windows 10.
Great, that's what I expected. Just below though is this:
The vcruntime library contains Visual C++ CRT implementation-specific
code, such as exception handling and debugging support, runtime checks
and type information, implementation details and certain extended
library functions. This library is specific to the version of the
compiler used.
Which implies that there is still a non-universal VC++ dependency that gets linked in by VS. To me, this implies that a dependency-free DLL doesn't really exist (at least not something built with VC++), since you'll always have a vcruntime dependency.
There is always the option of static linking (/MT), but in my case, I'm also looking at a DLL that has /clr, and the two options are mutually exclusive. Application local deployment (just copy vcruntime140.dll with the binaries) also seems to work, and may be the best option for something that I want to be a portable/xcopy deployment.
I'm going to mark this as an answer for now, but if there's a way around this, I'd be interested in seeing it.

CMakeLists unable to find newly installed HDF5?

I'm working on a program that worked on another computer (1st one) and trying to get it to work on my new computer (3rd one). When I go to build and type ccmake .., I get this error:
CMake Error at build/share/cmake/hdf5/hdf5-targets.cmake:67 (message):
The imported target "hdf5" references the file
"/home/myname/Desktop/MyProject/build/lib/libhdf5.a"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
"/home/myname/Desktop/MyProject/build/share/cmake/hdf5/h
df5-targets.cmake"
but not all the files it references.
Call Stack (most recent call first):
build/share/cmake/hdf5/hdf5-config.cmake:70 (INCLUDE)
build/share/cmake/hdf5/FindHDF5.cmake:85 (INCLUDE)
src/Thing/CMakeLists.txt:66 (find_package)
Even when I then installed hdf5 using sudo apt-get, I got the same error
I had to delete that lib directory because it contained boost files that are outdated and caused a huge list of errors, possibly because of a conflict since I newly installed boost files in usr/lib and usr/include on this new computer. I got this program to work on a 2nd computer by simply deleting that lib directory
Is the way to resolve this to change the CMakeLists.txt so that it refers to the directory of the newly installed hdf5? The CMakeLists.txt looks like:
CMAKE_MINIMUM_REQUIRED (VERSION 2.6)
PROJECT (Projectname)
# CMake Modules
SET(CMAKE_MODULE_PATH
${PROJECT_BINARY_DIR}/share/cmake/hdf5
${CMAKE_SOURCE_DIR}/CMake
${CMAKE_MODULE_PATH})
SET(ENV{HDF5_ROOT_DIR_HINT} ${PROJECT_BINARY_DIR})
# Build output
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/lib")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/bin")
mark_as_advanced(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH)
#other stuff I excluded to keep this brief
Also, even if I delete all the files in the lib directory at home/myname/Desktop/MyProject/build/lib except for libhdf5.a, I get a bunch of boost errors. Its a very long output and I think its because make creates new boost files in lib that were originally from home/myname/Desktop/MyProject/build/lib, instead of referring to the newly installed boost files in usr/lib and usr/include
In case it helps, line 66 of src/Thing/CMakeLists.txt looks likefind_package(HDF5 COMPONENTS C CXX)
I could also post the contents of hdf5-config.cmake and FindHDF5.cmake, if necessary
EDIT: dpkg -l | greap hdf5 gives
ii hdf5-helpers 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - Helper tools
ii hdf5-tools 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - Runtime tools
ii libhdf5-10:amd64 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - runtime files - serial version
ii libhdf5-cpp-10:amd64 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - C++ libraries
ii libhdf5-dev 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - development files - serial version
ii libhdf5-openmpi-10:amd64 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - runtime files - OpenMPI version
ii libhdf5-openmpi-dev 1.8.15-patch1+docs-4 amd64 Hierarchical Data Format 5 (HDF5) - development files - OpenMPI version
ii libhdf5-serial-dev 1.8.15-patch1+docs-4 all transitional dummy package
A not so short introduction to linking of third-party libraries on Linux:
Generally you should decide 2 aspects.
The first one is about "system vs custom library"
you may link your application against a library installed from a system package (in Debian using apt-get). This is the preferred way to compile programs on Linux unless you have some reasons against (see below). Also usually this is the easiest way, 'cause all build tools are configured to find library components in certain "well-known" places.
Link against a custom build of a library. Use this method if you need some custom build options for a library, or need a specific version of library not available in repostitories and so on.
The second step is to choose between static and dynamic library.
Usually in Linux applications are linked against dynamically loaded libraries (.so). This reduces applications size, may decrease memory consumption and application loading time (because libraries for a given application are in memory already), and sometimes simplifies small updates like security fixes - one needs to update just a single library instead of all applications that use this vulnerable library
But there're drawbacks as well :) If you plan to distribute your application linked with dynamic libraries to other computers you need to make sure that the libraries of required versions are on a given target computer. Each library may in turn be linked with other libraries and so on. In the end you have to distribute a whole copy of an operating system, like e.g. Steam for Linux does: internally it carries a large part of Ubuntu. So sometimes it may be wiser to link against a static library and include everything needed rignt into your app.
Back to the practical questions. Since you've already installed system packages with libhdf5 development files (libhdf5-dev) I suggest you to go with the "system library" (p1.1).
In this case you should remove all other copies of the library from your build tree completely and use the following code chunk in your CMakeLists.txt:
find_package(HDF5 REQUIRED)
...
include_directories(${HDF5_INCLUDE_DIRS})
...
target_link_libraries(yourapp ${HDF5_LIBRARIES} <other required libs>)
if your application is a C++ app you may use ${HDF5_CXX_LIBRARIES} instead of ${HDF5_LIBRARIES}.
If you decided to link against a static library, then you need to define a special variable HDF5_USE_STATIC_LIBRARIES before calling find_package(HDF5...):
set(HDF5_USE_STATIC_LIBRARIES ON)
find_package(HDF5 REQUIRED)
...
If you still wish to use a custom build of the library then you should
"explain" to find_package where to look for library components. You may run make DESTDIR=/some/path install in the HDF5 build tree and then use that /some/path as the value of HDF5_ROOT environmental variable when running cmake in your application build tree:
HDF5_ROOT=/some/path cmake .
In this case CMake will try to locate HDF5 components in that directory. I would remove sytem package libhdf5-dev before this operation (just in case) using apt-get remove libhdf5-dev.
But again I believe that you should have good reasons not to use the system libhdf5 package.

Setting up GLEW,FREEGLUT

I'm setting up FREEGLUT and GLEW for Visual Studio2012 on Windows7 64bit.
First of all, should I need to set up also GLUT?
Second, I'm confused, in GLEW/lib and GLEW/bin there both Release and Release MX folder, which one should I pick files?
In regards to GLEW:
I suggest you use GLEW for now, and switch to GLEW MX (Multiple Rendering Contexts) once you need the additional functionality it provides.
According to http://glew.sourceforge.net/advanced.html
Starting with release 1.2.0, thread-safe support for multiple rendering contexts, possibly with different capabilities, is available. Since this is not required by most users, [GLEW MX] is not added to the binary releases to maintain compatibility between different versions.
Here is how you build glew:
Note: Just because you are using a 64 bit machine, doesn't mean that you have Visual Studio set up to run 64 bit applications. I suggest you use the 32 bit versions of libraries until you are ready to reap the benefits of using the 64 bit versions, as you can switch later.
1. Link your project with the static GLEW library in the lib folder. This is either glew32s.lib or GLEW depending on your platform.
Note: glew32s.lib is to link statically, glew32.lib (without the s) is to link dynamically. If you prefer to dynamically link with GLEW instead, leave out the define and link with glew32.lib instead of glew32s.lib on Windows. Don't forget to include glew32.dll or libGLEW.so with your executable!
2. Add the include folder to your include path.
3. Include the header in your program, but make sure that it is included before the OpenGL headers or the library you used to create your window.
In regards to GLUT:
Could someone else answer (or edit my answer), as I have not used GLUT yet.
Additional Sources Used For This Answer:
https://open.gl/

VC++ 2010 wants to link boost libararies i didn't even specify

I'm trying to build my application with MSVC 2010 instead of GCC. With GCC everything works fine. My app uses boost_system and boost_thread libraries.
I built boost with VC2010 in "system" layout, that means the libraries are named just libboost_system.lib (and not libboost_system_compiler_threading_version_wtf_snafu.lib)
The libs reside in C:\Boost\lib,
the Makefile specifies
LFLAGS = /NOLOGO /INCREMENTAL:NO /SUBSYSTEM:CONSOLE
LIBS = /LIBPATH:C:/Boost/lib libboost_system.lib libboost_thread.lib Ws2_32.lib
when invoking nmake it compiles, but when trying to link it quits with
LINK : fatal error LNK1104: cannot open file 'libboost_date_time-vc100-mt-1_43.lib
I mean seriously, WTF? I told it to link libboost_systen.lib and libboost_thread.lib how come it tries to link libboost_data_time and why does it assume I built the libs in "tagged" layout??
How can I stop MSVC trying to be smart and guess what I might have wanted to link?
Thanks,
Philipp
This is a feature of the Boost libs with compatible compilers for automatic linking.
(Those convoluted library names cover the myriad of threading and linking options that are available on the platform; there are good reasons to use that convention on Windows...)
More information here:
http://www.boost.org/doc/libs/1_33_1/more/getting_started.html#auto-link
I can't find a page for a more recent version, but I believe the BOOST_ALL_NO_LIB and related options are all still valid in 1.43.
Assuming you are auto-linking (i.e. you've defined BOOST_ALL_DYN_LINK or library specific equivalents).
For layout 'system' you have to define the preprocessor macro:
BOOST_AUTO_LINK_NOMANGLE
to link to the correct library names.
For layout 'tagged' you have to define the preprocessor macro:
BOOST_AUTO_LINK_TAGGED
to link to the correct library names.
I don't know if you could do this override for some libraries and keep the default for others. That would be a very cumbersome setup I'd imagine.

How can I force MSVC++ to ignore CRT dependencies of a static library?

I don't know if it's possible to do this, but I would like the /NODEFAULTLIB to be applied to a static library project.
I have many application projects (A.exe, B.dll, C.dll) that use a common static library D.lib.
This library has a lot of code and also has other .lib dependencies as well. One of them is the openssl library, which seems to have been built for win32 against the Release version of the CRT (i don't have the original project/sources).
So far, to avoid the mixing of the Release/Debug versions of CRT, I have to put the /NODEFAULTLIB:msvcrt.lib linker directive in all leaf projects (A.exe, B.dll). This works but I think it's not the ideal way of dealing with that issue.
I tried to put this property in D.lib project, but it has no effect.
Is there a way to force msvc++ to ignore the msvcrt.lib dependency from the 3rd party library?
A .lib does not have any linker settings because you don't link it, you link to it. A .lib is just an archive of .obj files, sort of like an uncompressed .zip file - that's why you have to put the setting on all projects that link to it.
If you're using VS2005+ you could use property sheets so that you only have to put the setting in one place and then use that property sheet in all projects.
However, OpenSSL is just that - Open Source, so you should be able to get the source for the version you are using and build it again (and add it to your version control system of course). I thought OpenSSL could be built as a DLL or LIB, which would solve your problem as the DLL would not interfere with the linking of your code.
Failing that, you always have the option of slitting your functionality out into a separate DLL so that you only have issues with one project.
To prevent your distributed static link library from depending on a specific MSVC runtime library you need to set this compiler option (in Visual Studio 2010 it looks like):
Configuration Properties -> C/C++ -> Advanced -> Omit Default Library Name = Yes (/ZI)
Now your users can link to your release built static lib from their debug build and not try to link to the incorrect runtime library causing problems, as well as linkers warnings.
Note that may cause link errors if your library actually depends on a specific runtime library or its behavior, and compatible components are not provided in some other way.
My understanding is that if library LIB in linked statically into a DLL, the DLL contains already all relevant code from LIB. Therefore, this coupling cannot be removed. This is just based on my understanding of statical linking, not on experiments.

Resources