CMake build script

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Darktib
Posts: 167
Joined: Sun Mar 23, 2008 8:25 pm
Location: France

CMake build script

Post by Darktib »

Hi there,

I made a CMake build script for Irrlicht long ago, and I always forget to post it to the forums, so here it is !

This script is only for building the engine. For the examples normally there would be a script per-example + 1 for all examples + 1 for the whole Irrlicht project. Anyway, put the following script in <IRRLICHT_ROOT>/source/CMakeLists.txt. This should work for Windows (XP to 8.1 at least), Linux (tested on Mint / Ubuntu / Fedora). For beginners, see the small tutorial at the end of this post. I don't put any licence on it, use it as you want.

There are 4 variables that can control the build:
- IRR_FAST_MATH : whether to build using fast maths (false by default, as it can cause some problems when the compiler gets too aggressive)
- IRR_SHARED_LIB : whether to generate dynamic libs (dlls/so) instead of static libs (true by default)
- IRR_DIRECTX_SDK : path to the DirectX SDK if you want to build with DirectX 9. Compile config will be adjusted, and this variable will default to the installation of the SDK (of nothing, if no SDK is installed).
- IRR_OUT_DIR : directory that will contain /lib/<platform>/smth.lib, and /bin/<platform>/smth.dll. By default this is the root directory of Irrlicht

The script is target-oriented, that means that it is really easy to include in a project (aside from allowing easy compilation of the engine). Let's say you have a project using CMake, and you want to use Irrlicht in it. In you CMakeLists.txt, just do the following:

Code: Select all

add_subdirectory(<IRRLICHT_ROOT>/source irrlicht) # 'irrlicht' is actually a path to the binary dir, leave it as written here and you're good
target_link_libraries(MyTarget PRIVATE Irrlicht)
There is still room for improvement, don't hesitate to contribute !

<IRRLICHT_ROOT>/source/CMakeLists.txt

Code: Select all

#
# Irrlicht 3D engine
#
cmake_minimum_required(VERSION 2.8)
project(Irrlicht)
 
# Irrlicht directories
# -------------------------------------------------------------------------------------------------
set(IRR_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
set(IRR_SRC_DIR "${IRR_ROOT_DIR}/source/Irrlicht")
 
# Options
# -------------------------------------------------------------------------------------------------
set(DXSDK "")
if(DEFINED ENV{DXSDK_DIR})
    set(DXSDK "ENV{DXSDK_DIR}")
endif()
set(IRR_FAST_MATH 0 CACHE BOOL "Whether to enable fast maths (at the expense of precision)")
set(IRR_SHARED_LIB 1 CACHE BOOL "Whether to generate shared libraries instead of static libraries")
set(IRR_DIRECTX_SDK ${DXSDK} CACHE PATH "Path to the DirectX SDK (for DirectX 9, this folder should contain /Include, /Lib)")
set(IRR_OUT_DIR ${IRR_ROOT_DIR} CACHE PATH "Path to the folder in which the generated files will be placed, ie libs in <this_path>/lib/<platform> and dlls in <this_path>/bin/<platform>")
 
# Some helper functions
# -------------------------------------------------------------------------------------------------
function(glob_c_cpp_sources result folder)
    file(GLOB res
        "${folder}/*.c"
        "${folder}/*.cpp"
        "${folder}/*.h"
        "${folder}/*.hpp")
    set(${result} ${res} PARENT_SCOPE)
endfunction()
 
function(setup_target_paths Target LibDir RTDir)
    set_target_properties(${Target} PROPERTIES
        OUTPUT_NAME ${Target}
        DEBUG_POSTFIX _d
        RELWITHDEBINFO_POSTFIX _rd
        MINSIZEREL_POSTFIX _rm
        RUNTIME_OUTPUT_DIRECTORY ${RTDir}
        LIBRARY_OUTPUT_DIRECTORY ${LibDir}
        ARCHIVE_OUTPUT_DIRECTORY ${LibDir}
        PDB_OUTPUT_DIRECTORY ${RTDir}
        RUNTIME_OUTPUT_DIRECTORY_DEBUG ${RTDir}
        LIBRARY_OUTPUT_DIRECTORY_DEBUG ${LibDir}
        ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LibDir}
        PDB_OUTPUT_DIRECTORY_DEBUG ${RTDir}
        RUNTIME_OUTPUT_DIRECTORY_RELEASE ${RTDir}
        LIBRARY_OUTPUT_DIRECTORY_RELEASE ${LibDir}
        ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LibDir}
        PDB_OUTPUT_DIRECTORY_RELEASE ${RTDir}
        RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${RTDir}
        LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${LibDir}
        ARCHIVE_OUTPUT_DIRECTORY_RELWITHDEBINFO ${LibDir}
        PDB_OUTPUT_DIRECTORY_RELWITHDEBINFO ${RTDir}
        RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${RTDir}
        LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${LibDir}
        ARCHIVE_OUTPUT_DIRECTORY_MINSIZEREL ${LibDir}
        PDB_OUTPUT_DIRECTORY_MINSIZEREL ${RTDir}
    )
endfunction()
 
# Source files
# -------------------------------------------------------------------------------------------------
glob_c_cpp_sources(IRR_SRC_FILES ${IRR_SRC_DIR})
glob_c_cpp_sources(IRR_SRC_FILES_INTERFACE ${IRR_ROOT_DIR}/include)
glob_c_cpp_sources(IRR_SRC_FILES_AESGLADMAN ${IRR_SRC_DIR}/aesGladman)
glob_c_cpp_sources(IRR_SRC_FILES_BZIP2 ${IRR_SRC_DIR}/bzip2)
glob_c_cpp_sources(IRR_SRC_FILES_LIBPNG ${IRR_SRC_DIR}/libpng)
glob_c_cpp_sources(IRR_SRC_FILES_LZMA ${IRR_SRC_DIR}/lzma)
glob_c_cpp_sources(IRR_SRC_FILES_ZLIB ${IRR_SRC_DIR}/zlib)
file(GLOB IRR_SRC_FILES_JPEGLIB "${IRR_SRC_DIR}/jpeglib/j*.c" "${IRR_SRC_DIR}/jpeglib/*.h")
 
# Remove test/dll main code from (some) thirdparty libs
# -------------------------------------------------------------------------------------------------
list(REMOVE_ITEM IRR_SRC_FILES_BZIP2
    "${IRR_SRC_DIR}/bzip2/bzip2.c"
    "${IRR_SRC_DIR}/bzip2/bzip2recover.c"
    "${IRR_SRC_DIR}/bzip2/dlltest.c"
    "${IRR_SRC_DIR}/bzip2/mk251.c"
    "${IRR_SRC_DIR}/bzip2/spewG.c"
    "${IRR_SRC_DIR}/bzip2/unzcrash.c")
list(REMOVE_ITEM IRR_SRC_FILES_JPEGLIB
    "${IRR_SRC_DIR}/jpeglib/jmemdos.c"
    "${IRR_SRC_DIR}/jpeglib/jmemmac.c"
    "${IRR_SRC_DIR}/jpeglib/jmemname.c"
    "${IRR_SRC_DIR}/jpeglib/jmemansi.c"
    "${IRR_SRC_DIR}/jpeglib/jpegtran.c")
list(REMOVE_ITEM IRR_SRC_FILES_LIBPNG
    "${IRR_SRC_DIR}/libpng/pngtest.c")
list(REMOVE_ITEM IRR_SRC_FILES_ZLIB
    "${IRR_SRC_DIR}/zlib/gzclose.c"
    "${IRR_SRC_DIR}/zlib/gzlib.c"
    "${IRR_SRC_DIR}/zlib/gzread.c"
    "${IRR_SRC_DIR}/zlib/gzwrite.c"
    "${IRR_SRC_DIR}/zlib/infback.c")
   
# Group files
# -------------------------------------------------------------------------------------------------
source_group(Irrlicht\\engine           FILES ${IRR_SRC_FILES})
source_group(Irrlicht\\interface        FILES ${IRR_SRC_FILES_INTERFACE})
source_group(Irrlicht\\libs\\aesGladman FILES ${IRR_SRC_FILES_AESGLADMAN})
source_group(Irrlicht\\libs\\bzip2      FILES ${IRR_SRC_FILES_BZIP2})
source_group(Irrlicht\\libs\\jpeglib    FILES ${IRR_SRC_FILES_JPEGLIB})
source_group(Irrlicht\\libs\\libpng     FILES ${IRR_SRC_FILES_LIBPNG})
source_group(Irrlicht\\libs\\lzma       FILES ${IRR_SRC_FILES_LZMA})
source_group(Irrlicht\\libs\\zlib       FILES ${IRR_SRC_FILES_ZLIB})
 
# Irrlicht target
# -------------------------------------------------------------------------------------------------
set(IRR_ALL_SRC_FILES
    ${IRR_SRC_FILES}
    ${IRR_SRC_FILES_INTERFACE}
    ${IRR_SRC_FILES_AESGLADMAN}
    ${IRR_SRC_FILES_BZIP2}
    ${IRR_SRC_FILES_JPEGLIB}
    ${IRR_SRC_FILES_LIBPNG}
    ${IRR_SRC_FILES_LZMA}
    ${IRR_SRC_FILES_ZLIB})
if(${IRR_SHARED_LIB})
    add_library(Irrlicht SHARED ${IRR_ALL_SRC_FILES})
else()
    add_library(Irrlicht STATIC ${IRR_ALL_SRC_FILES})
endif()
 
# Target properties (for compilation & export)
# -------------------------------------------------------------------------------------------------
target_include_directories(Irrlicht
    PUBLIC ${IRR_ROOT_DIR}/include
    PRIVATE ${IRR_SRC_DIR}
    PRIVATE ${IRR_SRC_DIR}/aesGladman
    PRIVATE ${IRR_SRC_DIR}/bzip2
    PRIVATE ${IRR_SRC_DIR}/jpeglib
    PRIVATE ${IRR_SRC_DIR}/libpng
    PRIVATE ${IRR_SRC_DIR}/lzma
    PRIVATE ${IRR_SRC_DIR}/zlib)
if(NOT ${IRR_DIRECTX_SDK} STREQUAL "")
    target_include_directories(Irrlicht PRIVATE ${IRR_DIRECTX_SDK}/Include)
    if(${CMAKE_SIZEOF_VOID_P} EQUAL 4)
        set(DX_LIBS ${IRR_DIRECTX_SDK}/Lib/x86)
    else()
        set(DX_LIBS ${IRR_DIRECTX_SDK}/Lib/x64)
    endif()
    target_link_libraries(Irrlicht
        PRIVATE ${DX_LIBS}/d3dx9.lib
        PRIVATE ${DX_LIBS}/dinput8.lib
        PRIVATE ${DX_LIBS}/dxguid.lib)
else()
    target_compile_definitions(Irrlicht PRIVATE NO_IRR_COMPILE_WITH_DIRECT3D_9_)
endif()
if(NOT ${IRR_SHARED_LIB})
    target_compile_definitions(Irrlicht PUBLIC _IRR_STATIC_LIB_)
endif()
 
# Per platform config
# -------------------------------------------------------------------------------------------------
 
# Export symbols
target_compile_definitions(Irrlicht PRIVATE IRRLICHT_EXPORTS)
 
# Other flags, mac/mingw not supported here
set(IRR_PLATFORM "Linux")
if(WIN32)
    # Disable the ton of warnings from standard library
    target_compile_definitions(Irrlicht PRIVATE _CRT_SECURE_NO_WARNINGS)
 
    # Multi processor compilation
    target_compile_options(Irrlicht PRIVATE /MP)
 
    # Fast math options
    if(${IRR_FAST_MATH})
        target_compile_options(Irrlicht PRIVATE /fp:fast)
 
        # SSE2 is automatically activated on x64
        if(${CMAKE_SIZEOF_VOID_P} EQUAL 4)
            target_compile_options(Irrlicht PRIVATE /arch:SSE2)
        endif()
    endif()
 
    # Platform
    if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
        set(IRR_PLATFORM "Win64-VisualStudio")
    else()
        set(IRR_PLATFORM "Win32-VisualStudio")
    endif()
elseif(UNIX)
    # Standard mode
    target_compile_options(Irrlicht
        PRIVATE -Wall
        PRIVATE -pipe
        PRIVATE -fno-exceptions
        PRIVATE -fno-strict-aliasing)
 
    # Disable RTTI on C++ files only (no sense for C files)
    set_source_files_properties(${IRR_SRC_FILES} ${IRR_SRC_FILES_AESGLADMAN}
        PROPERTIES COMPILE_FLAGS -fno-rtti)
 
    # Debug macro
    target_compile_options(Irrlicht PRIVATE $<$<CONFIG:Debug>:-D_DEBUG>)
 
    # X11 and OpenGL
    target_link_libraries(Irrlicht
        PRIVATE X11
        PRIVATE GL
        PRIVATE Xxf86vm)
endif()
 
# Last step, output directories
# -------------------------------------------------------------------------------------------------
setup_target_paths(Irrlicht "${IRR_OUT_DIR}/lib/${IRR_PLATFORM}" "${IRR_OUT_DIR}/bin/${IRR_PLATFORM}")
 
Beginner's tutorial:

There are 2 ways to use CMake: using the GUI, or the command line.
- GUI: set the "source dir" to <IRRLICHT_ROOT>/source, and the binary dir to something you want (ideally NOT the source dir, something like <IRRLICHT_ROOT>/build or whatever you prefer), then hit 'configure' (you will be prompted for a build tool to generate for). You can modify the variables to your liking, and then hit 'generate'. Then use the build tool (VS / C::B / make / ...) and voilà !
- Command line:

Code: Select all

 
cd <IRRLICHT_ROOT>
mkdir build
cd build
cmake ..
#or: cmake -DVARIABLE=smth ..
make
 
edit 8 july 2015: better handling of DirectX SDK and DirectX 9

Enjoy !
Last edited by Darktib on Fri Dec 16, 2016 9:28 pm, edited 2 times in total.
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: CMake build script

Post by REDDemon »

Finally :) was thinking do to it first or later, nice to see someone already did it.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Darktib
Posts: 167
Joined: Sun Mar 23, 2008 8:25 pm
Location: France

Re: CMake build script

Post by Darktib »

I updated the script so that DX9 compilation is automatically deactivated if no sdk is found
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: CMake build script

Post by REDDemon »

Ehi :) I'm going to integrate that in irrlicht trunk, I have to ask if you could put your build script file under the same license of irrlicth so I can freely edit it where needed.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Darktib
Posts: 167
Joined: Sun Mar 23, 2008 8:25 pm
Location: France

Re: CMake build script

Post by Darktib »

Hey, glad you're going to integrate it ! No problem for the license, I put it under the same as Irrlicht as your request :)

edit: I'll just verify if I have some polish to do, since I improved this script a bit in my git repo of Irrlicht (here: https://github.com/Synxis/Irrlicht). I'll do it tomorrow (too late now^^)
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: CMake build script

Post by CuteAlien »

Ehm, still discussing this (sorry). Btw, I wouldn't recommend fast_math as default. It can maybe be some optimization for some apps, but in my experience it caused far more often troubles.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: CMake build script

Post by REDDemon »

Thanks, sorry I had a bit too much iniziative ^^.I have few improvements for it ill keep it updated for when There will be the need for it.
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
Darktib
Posts: 167
Joined: Sun Mar 23, 2008 8:25 pm
Location: France

Re: CMake build script

Post by Darktib »

Well it turns out that the code in the OP was almost already at the latest version - I disabled the default fast math.

@CuteAlien CMake is a very good thing, and it is still possible to add the CMakeLists.txt without removing any file (and thus keeping the old *.sln for example).
The ability to add Irrlicht as a git submodule then just doing a

Code: Select all

target_link_library(MyApp PUBLIC Irrlicht)
is just gold, way easier than doing the download/compilation of dependencies by hand.

BTW I think there is still a bug with array allocators, I had a fix here: https://github.com/Synxis/Irrlicht/comm ... 2f27be5afb (and probably already posted it in the bug report I think)
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: CMake build script

Post by CuteAlien »

Darktib: Why do you think those elements should be constructed? They already exist, so isn't copying fine? I think I need a concrete case where this causes a problem to understand the problem.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Darktib
Posts: 167
Joined: Sun Mar 23, 2008 8:25 pm
Location: France

Re: CMake build script

Post by Darktib »

Because maintaining old projects files is tedious and very time-consuming. New IDEs appear for example, with different file formats, and you just can't directly support 30+ different build systems. CMake allows you to specify how your project is built once, and also how to use it easily. Then the user generates the build config he wants - for example if I want to use ninja as a build system, I can with cmake. Moreover, at first the old files can be kept for compatibility.

I know CMake language is terrible, but even with such a bad language the tool is very very useful (also more and more developers are using it, at the moment nearly 40% of all C++ devs worldwide use it[1]).

[1]: https://blog.jetbrains.com/clion/2015/0 ... ore-clion/
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: CMake build script

Post by CuteAlien »

Darktib: I was talking about your bug-report for the array :-)

I know cmake and it's pros/cons... not completely against it and used it myself in the past (but no longer really). Just still trying to find something better. Adding it while maintaining other files would add more overhead. Replacing other project files means people can no longer simply use VS project files and start the engine as CMake can't produce project files which can be distributed. I had hoped using relative paths could get us (closer to) best of both worlds, but seems cmake canceled support for that again.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Darktib
Posts: 167
Joined: Sun Mar 23, 2008 8:25 pm
Location: France

Re: CMake build script

Post by Darktib »

Ah sorry^^.
All core::array is using the allocator for new elements / destroying elements, except these 2 lines - so consistency is not respected.
Also it can pose problems with array of non-copyable elements (can be useful in some cases). A workaround is to store pointers to non-copyable objects in the vector but this is not very good memory-wise.

I understand the point on the time to maintain the cmake script. If a core dev always use cmake for his projects it can be worth though.
Sadly I also searched for alternatives but didn't found them; most need the build script to include compiler flag (which is a showstopper for me...).
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: CMake build script

Post by CuteAlien »

Yeah, the difference in those 2 lines should be that they are not creating/destroying elements. It creates new ones when the array didn't contain any before. But here it assigns to already created elements. Or at least I think that's the reasoning behind it.

And cmake - it's just delayed for now. I kinda brought it up in another thread (http://irrlicht.sourceforge.net/forum/v ... =7&t=51645) and likely we will end up with it. We just have to be careful it doesn't become another scons (which we have already - but no one left in the team really caring about it). Maybe one option is to keep one VS solution for the latest VS version. I just have to figure out some weekend how to get that VS working on my computer (already spend more than a full day on it without success.. but maybe got close to figuring out why it fails... meaning I got some idea, just not time/motivation yet to follow up on it).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
REDDemon
Developer
Posts: 1044
Joined: Tue Aug 31, 2010 8:06 pm
Location: Genova (Italy)

Re: CMake build script

Post by REDDemon »

I think the newest visual studio works only on newer Windows versions. which OS have you?
Junior Irrlicht Developer.
Real value in social networks is not about "increasing" number of followers, but about getting in touch with Amazing people.
- by Me
CuteAlien
Admin
Posts: 9628
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: CMake build script

Post by CuteAlien »

I switched to Windows 10. The conflict likely is a combination of older VS installs + Windows 7.1 SDK install conflicting with the SDK coming with newer VS versions.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply