Compiling 32-bit vs 64-bit project using CMake - 64-bit

How do I specify that CMake should use a different link_directories value depending on whether the target is 32-bit or 64-bit? For example, 32-bit binaries need to link with 32-bit Boost, 64-bit binaries need to link with 64-bit Boost.

You do something along these lines
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
set( BOOST_LIBRARY "/boost/win64/lib" )
else( CMAKE_SIZEOF_VOID_P EQUAL 8 )
set( BOOST_LIBRARY "/boost/win32/lib" )
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
set( CMAKE_EXE_LINKER_FLAGS ${BOOST_LIBRARY} )

I know it's quite old question. But it's still on top when you search with Google "cmake 32 64".
I have answer similar to user434507's answer but a little bit more readable in my opinion (I don't like if-else construction in cmake, it looks ugly):
math(EXPR BITS "8*${CMAKE_SIZEOF_VOID_P}")
set(BOOST_LIBRARY "/boost/win${BITS}/lib")
set(CMAKE_EXE_LINKER_FLAGS ${BOOST_LIBRARY})
This will point BOOST_LIBRARY path to /boost/win32/lib or /boost/win64/lib, depending on your architecture.

For Boost specifically, you should use
FIND_LIBRARY(Boost 1.44 COMPONENTS ...)
Then the CMake variable Boost_LIBRARY_DIRS will contain the correct library path, which has to be set using LINK_DIRECTORIES, e.g.
LINK_DIRECTORIES(${Boost_LIBRARY_DIRS})
The more general case is correctly described in user434507's answer.

Based on rominf I turned up following solution (for Windows).
I install boost libraries into: C:\Boost_32 and C:\Boost_64
In CMakeLists.txt
math(EXPR BITS "8*${CMAKE_SIZEOF_VOID_P}")
set(BOOST_ROOT C:/Boost_${BITS})
find_package(Boost 1.64.0 COMPONENTS ... )
INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIR} )
LINK_DIRECTORIES(${Boost_LIBRARY_DIR})
Explanation:
CMAKE_SIZEOF_VOID_P is equal to 4 on 32bit platform, and 8 on 64bit platform.
Expression 8*${CMAKE_SIZEOF_VOID_P} will evaluate to 32 or 64,
respectively.
C:/Boost_${BITS} turns into C:/Boost_32 or C:/Boost_64 automagically
Advantages:
You don't need conditionals (and in my CMakeLists there are too many already),
It is 90% how you 'should' include Boost with CMake.

Related

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.

How to check the compiler version in Qt .pro file?

I want to build a Qt project using either GCC or an ARM compiler. In either environment I have to link different libraries.
How I can check if the current compiler is Linux's g++ and CROSS_COMPILE is 'arm-cortexa9neont-linux-gnueabi-'?
You can use the Platform Scope built in to QMake to set up the build differently depending on platform.
It's based on the mkspec's shipped with Qt and can be found in
[Where Qt's installed]/mkspecs
So in your case I guess it'll look something like this:
linux-arm-gnueabi {
//ARM stuff here
}
Please note that I have not tested this. I've only read what's in the documentation I have linked to.
If you want to know only type of processor, you can use Q_PROCESSOR_ARM macro.

Is there a way to specify all the GDCM libraries in CMakeList at once?

This may be a very basic question, but I am unable to find the answer.
I just installed GDCM library on my Windows 7 workstation and compiled it with CMake and later built the generated solution using VS2012 Express.
However, I'm unsure about which GDCM libraries to include in the CMakeLists and I was wondering if there was an easier way to specify all the libraries at once.(like VTK_LIBRARIES for VTK). I tried GDCM_LIBRARIES and that doesn't return a value, neither does GDCM.
Specifically, I am looking to replace:
TARGET_LINK_LIBRARIES(TestvtkGDCMImageReader vtkgdcm gdcmMSFF gdcmDSED gdcm2vtk)
with something more general.
Typically, GDCM_LIBRARIES would be defined by the use file that you include after finding the GDCM package in CMake; however, it isn't currently set. You might just do it yourself by setting a variable with all of the GDCM library names.
For example, from looking at the libraries included in the 2.4.0 Windows binary distribution, I could do this in my CMakeLists.txt:
set( GDCM_LIBRARIES
gdcmDICT gdcmDSED gdcmIOD gdcmMEXD gdcmMSFF gdcmcharls gdcmexpat gdcmgetopt
gdcmjpeg12 gdcmjpeg16 gdcmjpeg8 gdcmopenjpeg gdcmzlib
# since you built the vtk component, you might also include them here
vtkgdcm gdcm2vtk
)
# then you can replace your line with this
target_link_libraries( TestvtkGDCMImageReader ${GDCM_LIBRARIES} )
Check out where the GDCM dlls you built are installed to see that you get all of the libraries.

Linking to a platform specific Library

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.

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/

Resources