CMake: Changes for Linux

Published February 20, 2016
Advertisement


So the past few days I've been working with CMake to try and get my some of the JBEngine Libraries running for Linux. The first thing I did was use vcxproj2cmake tool to generate the CMakeLists.txt from my already created Visual Studio Project Files. To start with I concentrated on the Maths and Sound Libraries as they were the easiest to do. Maths Libraries only requires some third party includes of glm and the Sound Library only has one library dependency on FMOD.

[font=arial]Working with vcxproj2cmake[/font]


To get the tool working I ended up having to copy all it's files into the same directory as the project file. It just didn't seem to work with a path. Secondly I then had to manually change all the paths that I had entered (or Visual Studio had generated) for the include and library directories in the Visual Studio Projects. Microsoft tends to default to using "\" for directories where as Unix system use "/". Once I had done this It finally generated a CMakeLists.txt for me, but this was only the beginning!

Creating Cross-platform code


Being the naive developer that I was a few years ago I had scattered through my source code the use of the "\" for directories instead of "/". This was one of the first things I had to address. It was mostly the includes in the files so it wasn't too hard to track down. This wasn't too time consuming for the Maths and Sound libraries as there are no more that 5 files in each. Doing this for the whole JBEngine Source may be a little more tedious.

The next problem I encountered was resolved by this Stack Overflow post: Why does MSVC Let me do this. I was essentially passing an anonymous object to a function. It was a little confusing to track down as it wasn't a simple example:
?
part of the bounds header:
[code=:0]void Union(Bounds& bound);void Union(vec3& v);


implementation of Bounds Union function
[code=:0] void Bounds::Union( Bounds& bound ){ Union(bound.GetMin()); Union(bound.GetMax());}

What you don't see here is that Bounds.GetMin() and Bounds.GetMax() do not return a reference. This means that the returned vec3 object from the functions are newly created and therefore anonymous objects. MSVC automagically resolves this in some way but g++/gcc does not do this for you. This took me a little time to figure out as I had never even had to think about this sort of thing before.

They were the only real code issues that I faced, the rest was all about learning CMake.

Learning CMake


So I started off with an already "complete" CMakeLists.txt which would work for Windows. Unfortunately this was never going to work out the box for Linux. Well at least it didn't for the Sound Library. First of all I had to get the Linux version of the FMOD Libs.

I had quite a bit of trouble getting used to how CMake works, specifically with include and library paths and also using the if(UNIX) branches for OS specific target_link_libraries. I finally managed to get CMake working and now I only had to deal with the make compilation issues.

What I hadn't realised is that fmod had changed significantly since I got the library for Windows so then I had to adapt the code to use the new library.

Once I had managed this I then created a Test application to play a sound. So it was all quite easy I just had problems with:


  • vcproj2cmake
  • code issues
  • cmake issues
  • library compatibility issues.
  • and then more code issues due to the new library.


It really was a breeze.

On a serious note it wasn't half as bad as I thought, and I've learnt much more about CMake. The next things I will need to look at are:


  • Adding CMake Dependencies i.e. JBEngine Library requires all the other smaller Libraries such as Sound, Maths, Renderer etc.
  • Ensuring I haven't broken anything in Visual Studio whilst messing around with the project files.
  • Looking into Visual Studio Project/Solution Generation from CMake.

2 likes 2 comments

Comments

tnovelli

Interesting. I started using CMake to go the other way around, porting from Linux to Windows.

If you want to get away from Visual Studio you can use CMake with the commandline MSVC compiler, or with MinGW (gcc) or Clang.

MinGW as a cross-compiler under Linux is pretty ideal if you don't even want to touch Windows except for testing. I think Clang is a better compiler but it's more work to set up.

February 20, 2016 03:37 PM
JordanBonser

Interesting. I started using CMake to go the other way around, porting from Linux to Windows.

If you want to get away from Visual Studio you can use CMake with the commandline MSVC compiler, or with MinGW (gcc) or Clang.

MinGW as a cross-compiler under Linux is pretty ideal if you don't even want to touch Windows except for testing. I think Clang is a better compiler but it's more work to set up.

Ahh that's like the complete opposite of what I want to do. I think Visual Studio is great for development and I want to keep Windows as my main development platform. I will just be using Linux for testing out the changes and doing any Linux only development.

Thanks for the tip on using the MSVC compiler from the commandline. I think I will do that as a validation step to check my CMake files are working.

February 22, 2016 08:37 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement