How to setup your C/C++ projects? http://plagatux.es November, 2012
Outline Introduction 1 Introduction 2 Concepts Scripting CPack 3 Qt libraries Cross-compiling
Introduction System for configuring C/C++ projects. Independent of: Platform IDE/Editor Compiler Generates native makefiles and workspaces Some of its major features Open source Simplicity of scripting language Modules for finding/configuring software Create custom targets/commands Out-of-Source builds Cross compiling Integrated testing & packaging (CTest & CPack)
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Many IDEs, editors and SOs IDE Windows Mac OS X Vis. Studio Code::Blocks XCode Linux KDevelop Anjuta Multi-platform Eclipse QtCreator Editors + Tools + Makefiles Multi-platform
Compilers Introduction Compilers & Linkers GNU Compilers (gcc, g++, asm, fortran, etc) Visual Studio compilers MinGW (Windows Port of GNU Compilers) Intel compilers Target-specific compilers (embedded hardware) Cross-compiling Eclipse + plugins? Is it really necessary?
Who are using CMake?
Who are using CMake? Many important libraries & tools use CMake VTK KDE Blender Compiz MySQL Inkscape Qt4 & Qt5 OpenCV Point Clouds Library Boost ZLib...
Why to use CMake? Introduction Do not depend on specific platform, IDE or compiler. Many independent builds for each project. Easy to tune specific-platform stuff. Easy integration with other applications like Doxygen. Console and Graphical applications.
Typical project setup Introduction CMakeLists.txt in root directory. CMakeLists.txt files in code directories. src C/C++ libraries. tests unitary tests. utils apps using (or not) the libraries. Procedure 1 Go to project path. 2 Create build path (debug release) & go inside. 3 Run CMake indicating build & source paths. 4 Make or compile with appropriate workspace. 5 Install targets.
Simple example Introduction
Outline Introduction Concepts Scripting CPack 1 Introduction 2 Concepts Scripting CPack 3 Qt libraries Cross-compiling
Code organization Introduction Concepts Scripting CPack Each project in a independent directory. Each subdirectory can contain a subproject. Inheritance of configuration in subdirectories. Order of processing: Root, dir1, dir3, dir4, dir2
Source tree & Binary tree Concepts Scripting CPack The source tree contains: Program sources & headers. Data files. CMake input files. The binary tree contains: Native build system files (dsw, dsp, makefiles, workspaces). Libraries. Executables. Build outputs. Any other build generated files.
Predefined targets Introduction Concepts Scripting CPack
Basic variables Introduction Concepts Scripting CPack CMAKE_BUILD_TYPE (Debug Release) Determines type of compilation CMAKE_VERBOSE_MAKEFILE (ON OFF) If it is enabled the compilation show all the information CMAKE_MODULE_PATH Path to where CMake modules are located CMAKE_INSTALL_PREFIX Where to install targets (be careful with privileges)
Basic commands Introduction Concepts Scripting CPack Comments with # Project PROJECT( myproject ) Set and read variables SET(VARIABLE Ou yeah ) MESSAGE(STATUS VARIABLE : $ {VARIABLE } ) Conditional blocks IF (WIN32) MESSAGE(STATUS Doing s p e c i f i c windows s t u f f s ) ELIF ( LINUX ) MESSAGE(STATUS Doing s p e c i f i c l i n u x s t u f f s ) ELIF (APPLE) MESSAGE(STATUS Doing s p e c i f i c apple s t u f f s ) ELSE ( ) MESSAGE(FATAL_ERROR Unrecognized operative system ) ENDIF ( )
Basic commands Introduction Concepts Scripting CPack Messages MESSAGE( Important message ) MESSAGE(STATUS Incidental information ) MESSAGE(WARNING CMake warning, continue processing ) MESSAGE(SEND_ERROR CMake error, continue but skiping generation ) MESSAGE(FATAL_ERROR CMake error, stop a l l processing ) Subdirectories ADD_SUBDIRECTORY( src ) ADD_SUBDIRECTORY( t e s t s ) ADD_SUBDIRECTORY( u t i l s ) Modify variables In terminal mode : cmake -D VAR=XXX... In GUI mode
Concepts Scripting CPack Libraries and applications commands Compile & link commands ADD_DEFINITIONS( D _NDEBUG) INCLUDE_DIRECTORIES( $ {PROJECT_SOURCE_DIR } / src ) LINK_DIRECTORIES ( $ {PATH_TO_SOME_LIBRARIES } ) LINK_LIBRARIES ( $ {OpenCV_LIBS } TARGET_LINK_LIBRARIES ( mytarget $ { MyLIB } ) Target commands #The f o l l o w i n g commands depends on CMAKE_CXX_FLAGS, CMAKE_CXX_DEBUG_FLAGS, #CMAKE_CXX_RELEASE_FLAGS, etc. ADD_LIBRARY( mylib $ {SOURCES} ) # The l i b r a r y w i l l be shared or s t a t i c depending on BUILD_SHARED_LIBS v a r i a b l e ADD_EXECUTABLE(myApp $ {SOURCES} ) Verbose compiling make VERBOSE=1
Concepts Scripting CPack Libraries and applications commands Install commands # I n s t a l l headers f i l e s of the l i b r a r y INSTALL ( FILES $ {HEADERS} DESTINATION include / $ {PROJECT_NAME} / COMPONENT main ) # I n s t a l l l i b r a r y f i l e s of the l i b r a r y INSTALL (TARGETS $ {PROJECT_NAME} RUNTIME DESTINATION bin COMPONENT main # Dynamic l i b r a r y : DLLs LIBRARY DESTINATION l i b PERMISSIONS # Dynamic l i b r a r y : so OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE COMPONENT main ARCHIVE DESTINATION l i b / s t a t i c COMPONENT main ) # S t a t i c l i b r a r y # I n s t a l l a p p l i c a t i o n INSTALL (TARGETS myapp RUNTIME DESTINATION bin COMPONENT main ) #These commands generates i n s t a l l a t i o n r u l e s f o r a p r o j e c t. #DESTINATION is r e l a t i v e to CMAKE_INSTALL_PREFIX unless you specify a absolute path
Advanced commands Concepts Scripting CPack Find libraries # In / usr / share / cmake 2.8/Modules or C : \ ProgramFiles \ cmake \ Modules \ are the Find f i l e s FIND_PACKAGE( Qt4 4.4.3 REQUIRED QUIET COMPONENTS QtCore QtGui ) FIND_PACKAGE(OpenCV REQUIRED) FIND_PACKAGE( ZLIB REQUIRED) FIND_PACKAGE( GTest )... # To specify other places where to find Find f i l e s SET(CMAKE_MODULE_PATH $ {CMAKE_MODULE_PATH} $ {CMAKE_INSTALL_PREFIX } / l i b / cmake / )... LINK_LIBRARIES ( $ {OpenCV_LIBS } $ {QT_QTCORE_LIBRARY } ) TARGET_LINK_LIBRARIES (myapp $ {QT_LIBRARIES } ) # Variables defines in Find f i l e s... FIND_PACKAGE( PkgConfig REQUIRED) IF (PKG_CONFIG_FOUND) PKG_CHECK_MODULES(AVCODEC REQUIRED libavcodec >=53.35.0) ELSE ( ) MESSAGE(FATAL_ERROR " pkg c o n f i g command not found " ) ENDIF ( )... FIND_LIBRARY (ARGTABLE argtable2 PATHS $ {ARGTABLE_ROOT } / l i b )
Advanced commands Tunning compiling options SET(EXTRA_C_FLAGS " " ) SET(EXTRA_C_FLAGS_RELEASE " " ) SET(EXTRA_C_FLAGS_DEBUG " " ) SET(EXTRA_EXE_LINKER_FLAGS " " ) SET(EXTRA_EXE_LINKER_FLAGS_RELEASE " " ) SET(EXTRA_EXE_LINKER_FLAGS_DEBUG " " ) Concepts Scripting CPack IF (WARNINGS_ANSI_ISO) add_extra_compiler_option( ansi ) add_extra_compiler_option( Wcast a l i g n ) add_extra_compiler_option( W s t r i c t a l i a s i n g =2) ELSE ( ) add_extra_compiler_option( Wno narrowing ) add_extra_compiler_option( Wno delete non v i r t u a l dtor ) add_extra_compiler_option( Wno unnamed type template args ) ENDIF ( ) IF (WARNINGS_ARE_ERRORS) add_extra_compiler_option( Werror ) ENDIF ( ) SET(CMAKE_C_FLAGS " $ {CMAKE_C_FLAGS} $ {EXTRA_C_FLAGS } " ) SET(CMAKE_CXX_FLAGS " $ {CMAKE_CXX_FLAGS} $ {EXTRA_C_FLAGS } " ) SET(CMAKE_CXX_FLAGS_RELEASE " $ {CMAKE_CXX_FLAGS_RELEASE} $ {EXTRA_C_FLAGS_RELEASE } " ) SET(CMAKE_C_FLAGS_RELEASE " $ {CMAKE_C_FLAGS_RELEASE} $ {EXTRA_C_FLAGS_RELEASE } " ) SET(CMAKE_CXX_FLAGS_DEBUG " $ {CMAKE_CXX_FLAGS_DEBUG} $ {EXTRA_C_FLAGS_DEBUG } " ) SET(CMAKE_C_FLAGS_DEBUG " $ {CMAKE_C_FLAGS_DEBUG} $ {EXTRA_C_FLAGS_DEBUG } " )
Packaging the project Concepts Scripting CPack A packaging tool distributed with CMake. It can be used without CMake (file CPackConfig.cmake). To use it with CMake INCLUDE(CPack). Generators: TGZ TBZ2 TZ ZIP Nullsoft Installer (Windows only) DragNDrop (OSX only) DEB/RPM (Linux only)
CPack commands Introduction Concepts Scripting CPack IF (NOT CPACK_GENERATOR) IF ( UNIX ) SET(CPACK_GENERATOR "DEB" ) ENDIF ( ) ENDIF ( ) SET(CPACK_PACKAGE_CONTACT " piponazo@plagatux. es " ) SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "My personal l i b r a r y " ) SET(CPACK_PACKAGE_VENDOR " Luis Diaz Mas " ) SET(CPACK_PACKAGE_VERSION_MAJOR $ {VERSION_MAJOR} ) SET(CPACK_PACKAGE_VERSION_MINOR $ {VERSION_MINOR } ) SET(CPACK_PACKAGE_VERSION_PATCH $ {VERSION_PATCH } ) SET(CPACK_SOURCE_GENERATOR "TBZ2 " ) SET(CPACK_SOURCE_PACKAGE_FILE_NAME $ {PROJECT_NAME} ) # Avoid mercurial f i l e s, builds and vim temporal f i l e s SET(CPACK_SOURCE_IGNORE_FILES " \ \ \ \. hg / ; / b u i l d. / ; \ \ \ \. swp$ " ) IF (CPACK_GENERATOR STREQUAL "DEB" ) SET(CPACK_DEBIAN_PACKAGE_MAINTAINER " piponazo@plagatux. es " ) SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) ENDIF ( ) INCLUDE( CPack )
Concepts Scripting CPack Big project example - OpenCV
Outline Introduction Qt libraries Cross-compiling 1 Introduction 2 Concepts Scripting CPack 3 Qt libraries Cross-compiling
Qt Overview Introduction Qt libraries Cross-compiling Figure: Image taken from http://qt-project.org/
Qt commands Introduction Qt libraries Cross-compiling Finding Qt FIND_PACKAGE( Qt4 4.8.1 REQUIRED QUIET COMPONENTS QtCore QtGui QtNetwork ) Compiling libraries and applications INCLUDE( $ {QT_USE_FILE } ) IF (BUILD_SHARED_LIBS) ADD_DEFINITIONS( DQT_SHARED) ELSE ( ) ADD_DEFINITIONS( DQT_STATIC) ENDIF ( ) IF ( $ {CMAKE_BUILD_TYPE} STREQUAL " Release " ) ADD_DEFINITIONS( DQT_NO_DEBUG) ENDIF ( ) Compiling plug-ins #Not use INCLUDE( $ {QT_USE_FILE } ) INCLUDE_DIRECTORIES( $ {QT_INCLUDE_DIR} $ {QT_QTCORE_INCLUDE_DIR} $ {QT_QTGUI_INCLUDE_DIR } ) ADD_DEFINITIONS( DQT_PLUGIN DQT_SHARED DQT_DEBUG D_REENTRANT)
Qt commands Introduction Qt libraries Cross-compiling Generating MOCS SET(MOCS mainwindow. h connectiondialog. h ) QT4_WRAP_CPP(MOCS_GEN $ {HDRS_MOCS} ) Compiling UIs SET( UIS mainwindow. ui connectiondialog. u i ) QT4_WRAP_UI(UIS_GEN $ { UIS } ) Compiling resources QT4_ADD_RESOURCES(RSC f i l e. qrc ) Putting all together ADD_EXECUTABLE(myApp $ {SOURCES} $ {MOCS_GEN} $ {UIS_GEN} $ {RSC} )
Qt Example Introduction Qt libraries Cross-compiling
Cross-compiling Introduction Qt libraries Cross-compiling Independent files for each specific board/configuration Use CMAKE_TOOLCHAIN_FILE variable Example with Raspberri pi (toolchain-rpi.cmake) INCLUDE( CMakeForceCompiler ) SET(CMAKE_SYSTEM_NAME Linux ) # t h i s one is important SET(CMAKE_SYSTEM_VERSION 1) # t h i s one not so much SET(RPI_ROOT / home / l u i s / rpi toolchain / arm bcm2708 / arm bcm2708hardfp linux gnueabi ) SET(CMAKE_C_COMPILER $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi gcc ) SET(CMAKE_CXX_COMPILER $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi g++) set (CMAKE_AR $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi ar ) set (CMAKE_LINKER $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi ld ) set (CMAKE_NM $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi nm) set (CMAKE_OBJCOPY $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi objcopy ) set (CMAKE_OBJDUMP $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi objdump ) set (CMAKE_STRIP $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi s t r i p ) set (CMAKE_RANLIB $ {RPI_ROOT } / bin / arm bcm2708hardfp linux gnueabi t a n l i b ) SET(CMAKE_FIND_ROOT_PATH $ {RPI_ROOT } / arm bcm2708hardfp linux gnueabi ) SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
Example - hello world RPi Qt libraries Cross-compiling