Page 1 of 2

CMake build script

Posted: Fri May 15, 2015 7:07 pm
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 !

Re: CMake build script

Posted: Wed Jun 10, 2015 8:56 am
by REDDemon
Finally :) was thinking do to it first or later, nice to see someone already did it.

Re: CMake build script

Posted: Wed Jul 08, 2015 9:59 am
by Darktib
I updated the script so that DX9 compilation is automatically deactivated if no sdk is found

Re: CMake build script

Posted: Sun Dec 11, 2016 4:23 am
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.

Re: CMake build script

Posted: Tue Dec 13, 2016 11:31 pm
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^^)

Re: CMake build script

Posted: Wed Dec 14, 2016 12:12 am
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.

Re: CMake build script

Posted: Wed Dec 14, 2016 9:26 am
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.

Re: CMake build script

Posted: Fri Dec 16, 2016 9:28 pm
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)

Re: CMake build script

Posted: Fri Dec 16, 2016 9:42 pm
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.

Re: CMake build script

Posted: Fri Dec 16, 2016 11:06 pm
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/

Re: CMake build script

Posted: Sat Dec 17, 2016 6:54 pm
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.

Re: CMake build script

Posted: Sat Dec 17, 2016 11:41 pm
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...).

Re: CMake build script

Posted: Sun Dec 18, 2016 12:15 am
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).

Re: CMake build script

Posted: Wed Dec 21, 2016 5:38 pm
by REDDemon
I think the newest visual studio works only on newer Windows versions. which OS have you?

Re: CMake build script

Posted: Wed Dec 21, 2016 11:34 pm
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.