module MxxRu::Cpp
Constants
- CPP_STD03
C++03 standard.
Since v.1.6.3
- CPP_STD11
C++11 standard.
Since v.1.6.3
- CPP_STD14
C++14 standard.
Since v.1.6.3
- CPP_STD17
C++17 standard.
Since v.1.6.14.3
- CPP_STD_DEFAULT
Default C++ standard variant. The compiler defaults must be used.
Since v.1.6.3
- Composite_target
Composition of subprojects target
- Composite_target_type
Target
type is a composition of subprojects- Cpp_source_file
Class, describing one C/C++ source file.
- Custom_subdir_obj_placement
Analog of
RuntimeSubdirObjPlacement
, but allow to specify paths for final results (EXE, LIB, DLL) and intermediate files (OBJ, RES). UnlikeRuntimeSubdirObjPlacement
these paths are independent of runtime_mode.Example:
MxxRu::Cpp::composite_target { global_obj_placement MxxRu::Cpp::CustomSubdirObjPlacement.new( # Final resuls going here. 'bin32', # All intermediate files going here. 'tmp/output32' ) required_prj ... }
If this composite project will be applied for project structure:
prj_1/ `- src/ prj_2/ `- module_1/ `- module_2/
Then after build project structructure will be:
prj_1/ `- src/ prj_2/ `- module_1/ `- module_2/ bin32/ tmp/ `- output32/ `- prj_1/ | `- src/ `- prj_2/ `- module_1/ `- module_2/
- Dll_info
Class, describing a shared library.
- Dll_requirements
Class, incapsulating DLL dependencies.
When someone is linking to the DLL on mswin platform, then it depends only from import library of that DLL. But when someone is linking to the DLL on unix platform, then it depends from all libraries DLL depends to. Exact details knows concrete toolset implementation only. Therefore, after DLL building base toolset class addresses to it's derivative with requirement to build all dependencies lists. These lists are returned as an object of
DllRequirements
type.- Dll_target
Dll is a target type.
- Dll_target_type
Target
type is shared library (dll).- ENV_VAR
- Exe_info
Class, describing EXE-file.
- Exe_target
Exe is a target type.
- Exe_target_type
Target
type is application.- Global_single_value_option
Auxiliary class, intended to store objects like runtime_mode, rtl_mode, etc, with information about who has set this or that mode.
- Lib_info
Class, describing a library.
- Lib_or_dll_target
Base class for targets that may be lib or dll, or MacOS bundle.
In that cases for a project should be defined special target class. The class constructor should define two blocks:
-
one of them is called if developer wants to build target as a static library. Block is run during as_lib method call;
-
second is called if developer wants to build target as a shared library. Block is run during as_dll method call;
Starting from version 1.4.10 this approach could also be used for bulding MacOS bundles.
For example:
class Prj < MxxRu::Cpp::LibOrDllTarget TAG = "threads_1/prj.rb" def initialize( a_alias = TAG ) super( a_alias, TAG ) target( "threads.1.3" ) threading_mode( MxxRu::Cpp::THREADING_MULTI ) init_dll_block( Proc.new { rtl_mode( MxxRu::Cpp::RTL_SHARED ) implib_path( "lib" ) define( "THREADS_1__DLL", OPT_UPSPREAD ) }) # This is avaliable from v.1.4.10 init_macos_bundle_block( Proc.new { rtl_mode( MxxRu::Cpp::RTL_SHARED ) } ) cpp_source( "threads.cpp" ) cpp_source( "micro_time.cpp" ) if toolset.tag( "target_os" ) == "mswin" define( "__WIN32__" ) cpp_source( "win32/os_thread.cpp" ) elsif toolset.tag( "target_os" ) == "unix" cpp_source( "posix/os_thread.cpp" ) end define( "THREADS_1__PRJ" ) end end
After definition of such class for the target, project may allow to use itself by the other projects using two methods.
Manual execution of as_lib, as_dll, as_macos_bundle methods¶ ↑
If project defines one class only, inherited from
LibOrDllTarget
, then all clients of that project should explicitly call as_lib or as_dll, or as_macos_bundle method during a reference to required_prj:class MyPrj < MxxRu::Cpp::ExeTarget def initialize( a_alias = "my_prj.rb" ) super( a_alias ) required_prj( "threads_1/prj.rb" ).as_dll( self ) end end
Such approach is not good because if in composite project several projects at the same time uses threads_1/prj.rb, then in one of them it's easy to forget to call as_dll. And it wouldn't be incorrect, because as_dll may be called by other projects in composite project.
Definition of auxiliary target classes¶ ↑
To make usage of target that may be lib or dll easier, project may define two auxiliary classes, which would call methods as_lib, as_dll and as_macos_bundle inside their constructors:
class Prj < MxxRu::Cpp::LibOrDllTarget def initialize( a_alias = "threads_1/prj.rb" ) super( a_alias, "threads_1" ) ... end end class Lib < Prj def super( a_alias = "threads_1/lib.rb" ) super( a_alias ) as_lib end end class Dll < Prj def super( a_alias = "threads_1/dll.rb" ) super( a_alias ) as_dll end end class MacOSBundle < Prj def super( a_alias = "threads_1/macos_bundle.rb" ) super( a_alias ) as_macos_bundle end end
Then for using the target it would be enough to do that:
class MyPrj < MxxRu::Cpp::ExeTarget def initialize( a_alias = "my_prj.rb" ) super( a_alias ) required_prj( "threads_1/dll.rb" ) end end
-
- Lib_target
Lib is a target type.
- Lib_target_type
Target
type is static library (lib).- Linker_lists
Class, incapsulating all lists required for linker.
- MXXCPPARG_DEBUG
- MXXCPPARG_EXTRACT_OPTIONS
- MXXCPPARG_NO_DEPENDS_ANALYZER
- MXXCPPARG_ONLY_ONE
- MXXCPPARG_RELEASE
Arguments passed into Ruby interpreter, intended to control
MxxRu::Cpp
.- Macos_bundle_target
MacOS bundle is a target type.
- Macos_bundle_target_type
Target
type is MacOS bundle (.bundle is a kind of dll on MacOS).Since v.1.4.10
- Mswin_rc_file
Class, describing one mswin resource file.
- Mswin_res_info
Class, describing mswin-res-info.
- OPTIM_SIZE
Optimization by size.
- OPTIM_SPEED
Optimization by speed.
- Obj_info
Class, describing object file.
- Obj_placement
Base class for a folder name generator. Results of compilation and linking would be located in that folder.
- Qt_gen
Files generator for Qt class.
Main features:
-
building of moc-files using moc tool. Generation from source and header files is supported.
-
building source files from ui-files using uic-compiler. For all files generated this way moc tool executed automatically.
Generated source files automatically added into cpp_source list of target.
Local list defines is supported.
If only pointer to the target passed into contructor, default list of defines is used. If it's required to change default list, new list should be passed through a second argument:
generator( MxxRu::Cpp::QtGen.new( self, [ "QT_THREAD_SUPPORT" ] ) )
-
- RTL_DEFAULT
Default compiler libraries are used.
- RTL_SHARED
Use shared runtime library.
- RTL_STATIC
Use static runtime library.
- RTTI_DEFAULT
Default RTTI mode. No RTTI options are passed to compiler.
- RTTI_DISABLED
RTTI mode should be disabled.
- RTTI_ENABLED
RTTI mode should be enabled.
- RUNTIME_DEBUG
Debug mode. Debug information is generated.
- RUNTIME_DEFAULT
Default mode. Nor debug information nor optimization options are set.
- RUNTIME_RELEASE
Release mode. Optimization is turned on.
- Runtime_subdir_obj_placement
The generator of folder name for compilation results, building a hierarchy of subfolders in a special folder, which name is choosen based on runtime mode.
For example, let src/lib/l.cpp and src/main/m.cpp files would be the sources of lib/l.lib library and m.exe application. If project is compiled in RELEASE mode, then following files would be created: release/src/lib/l.obj, release/src/main/m.obj, release/lib/l.lib and release/m.exe. Thus the presence of subfolders required will be supervised (for example, release/src/lib, release/src/main,…). If some subfolder doesn't exist, it will be created.
An example of usage:
class Build < MxxRu::Cpp::Composite_target def initialize( a_alias = MxxRu::BUILD_ROOT ) global_obj_placement( MxxRu::Cpp::RuntimeSubdirObjPlacement.new( "output" ) ) required_prj( "src/lib/prj.rb" ) required_prj( "src/main/prj.rb" ) end end
- SCREEN_CONSOLE
Console application.
- SCREEN_WINDOW
Windowed application.
- Source_subdir_obj_placement
The generator of folder name for an object file, using a subfolder with a fixed name in a folder with source file. Folder for lib, dll and exe files are not modified. get_obj and get_mswin_res methods are checking if result folder exists. If it's not, they are trying to create it.
- Spreadable_option
Auxiliary class for a storage of options, which can be broken on 3 groups: global, local and upspread. Examples of such options are: defines, include_paths, compiler_options, linker_options, …
- THREADING_DEFAULT
Default compiler threading mode.
- THREADING_MULTI
Multithreading is used.
- THREADING_SINGLE
Multithreading is not used.
- Target_type
Target
type (exe, lib, dll, unittest, composite etc.). The real type of the target is defined by a derivative class.- Target_with_full_path
Base class for any target for which full path must be calculated.
Public Class Methods
Simple method to define composite target.
Example:
MxxRu::Cpp::composite_target( MxxRu::BUILD_ROOT ) { required_prj 'some_project.rb' required_prj 'some_another_project.rb' }
# File lib/mxx_ru/cpp/composite.rb, line 100 def Cpp.composite_target( prj_alias = nil, &block ) prj_alias = MxxRu::Util::prj_alias_form_caller( caller ) unless prj_alias MxxRu::setup_target CompositeTarget.new( prj_alias, &block ) end
Creation of obj_placement object, which should be used by default.
# File lib/mxx_ru/cpp/obj_placement.rb, line 391 def Cpp.default_obj_placement return SourceSubdirObjPlacement.new end
Detect current toolset based on values of environment variables
Following algorithm is used: Getting the value of MXX_RU_CPP_TOOLSET envonment variable. It should be in a following format:
<file> [tag=value [tag=value [...]]
<file> value is used in require directive.
After loading of file defined, toolset method should return a pointer to toolset object.
If toolset object was created, pairs of tag=value are parsed and saved to the toolset created using a setup_tag method.
# File lib/mxx_ru/cpp/detect_toolset.rb, line 50 def Cpp.detect_toolset begin env = get_or_detect_toolset_variable_content # Exctracting file name, responsible for toolset object creation. toolset_file_name_regexp = /^(\S+)(.*)$/ file_name_match = toolset_file_name_regexp.match( env ) if nil == file_name_match raise MxxRu::InvalidValueEx.new( "Invalid format of environment variable '#{env_var}'. " + "Expected format: #{env_var}=<file>[ <tag>=<value>[ " + "<tag>=<value>[ ...]]]" ) end file_name = file_name_match[ 1 ] unparsed_tags = file_name_match[ 2 ] # Loading the file # Try to loading specified file first, if it fails try to # loading file with 'mxx_ru/cpp/toolsets' added... try_load_toolset_file file_name if nil == toolset() raise MxxRu::InvalidValueEx.new( "C/C++ Toolset is not set by file '#{file_name}'" ) end # Setting up toolset tags setup_toolset_tags( toolset(), unparsed_tags ) rescue MxxRu::Ex => ex $stderr.print "<<<[#{ex.class.name}]\t#{ex}>>>\n" exit( -1 ) end end
Simple method to define externals CMake project.
Example:
MxxRu::Cpp::ext_cmake_project { where 'deps/some_library' with WITH_SSL: 'NO', WITH_THREADS: 'YES' install_includedir 'some_library/headers' includedir_subfolders 'interface', 'backends', 'statistics' }
Since v.1.6.11
# File lib/mxx_ru/cpp/ext_cmake_project.rb, line 466 def Cpp.ext_cmake_project( prj_alias = nil, &block ) prj_alias = MxxRu::Util::prj_alias_form_caller( caller ) unless prj_alias MxxRu::setup_target ExtCMakeProjectTarget.new( prj_alias, &block ) end
Generator for generating method for simple way of describing targets.
# File lib/mxx_ru/cpp/target.rb, line 1548 def Cpp.generate_simple_target_method( target_type ) target_class_name = target_type.to_s.capitalize class_eval %Q{ def Cpp.#{target_type}( prj_alias = nil, &block ) prj_alias = MxxRu::Util::prj_alias_form_caller( caller ) unless prj_alias MxxRu::setup_target #{target_class_name}.new( prj_alias, &block ) end } end
Gets or detects value for MXX_RU_CPP_TOOLSET.
Since v.1.5.1
# File lib/mxx_ru/cpp/detect_toolset.rb, line 120 def Cpp.get_or_detect_toolset_variable_content env = ENV[ ENV_VAR ] if env.nil? $stderr.puts "Environment variable #{ENV_VAR} not found. " + "Try to detect toolset by HOST_OS and/or PATH..." env = try_detect_toolset_myself if env $stderr.puts "Detection successed. Toolset is: #{env}" else $stderr.puts "Detection failed." raise MxxRu::InvalidValueEx.new( "Environment variable '#{ENV_VAR}' not found (not set " + "or empty" ) end end env end
Simple method to define libraries collection target.
Example:
MxxRu::Cpp::lib_collection_target { required_prj 'some_project.rb' required_prj 'some_another_project.rb' }
Since v.1.4.0
# File lib/mxx_ru/cpp/lib_collection.rb, line 87 def Cpp.lib_collection_target( prj_alias = nil, &block ) prj_alias = MxxRu::Util::prj_alias_form_caller( caller ) unless prj_alias MxxRu::setup_target LibCollectionTarget.new( prj_alias, &block ) end
Set current toolset.
# File lib/mxx_ru/cpp/toolset.rb, line 1327 def Cpp.setup_toolset( toolset ) raise MxxRu::InvalidCastEx.new( 'Expected MxxRu::Cpp::Toolset' ) if !( toolset.kind_of?( MxxRu::Cpp::Toolset ) ) @@current_toolset = toolset end
Get current toolset.
# File lib/mxx_ru/cpp/toolset.rb, line 1336 def Cpp.toolset return @@current_toolset end
Try to detect toolset from host_os and PATH.
Since v.1.5.1
Only Windows platform and MS C++, Linux and GCC is detected now.
Returns name of toolset of throw exception if toolset is not detectable.
# File lib/mxx_ru/cpp/detect_toolset.rb, line 146 def Cpp.try_detect_toolset_myself if RbConfig::CONFIG['host_os'] =~ /linux/ # Assume that GCC is default compiler on Linux. "gcc_linux" elsif RbConfig::CONFIG['host_os'] =~ /^freebsd(9|10|11|12)$/ "clang_freebsd" else if ENV[ 'COMP_ENV' ] and ENV[ 'VC_ARCH' ] 'icc_win' elsif ENV[ 'VS160COMNTOOLS' ] 'vc16' elsif ENV[ 'VS140COMNTOOLS' ] 'vc14' elsif ENV[ 'VS120COMNTOOLS' ] 'vc12' elsif ENV[ 'VS110COMNTOOLS' ] 'vc11' elsif ENV[ 'VS100COMNTOOLS' ] 'vc10' elsif ENV[ 'VS90COMNTOOLS' ] 'vc9' elsif ENV[ 'VS80COMNTOOLS' ] 'vc8' elsif ENV[ 'VS71COMNTOOLS' ] 'vc7' end end end
Try load toolset file (without and with 'mxx_ru/cpp/toolsets' prefix).
Raises LoadError if loading failed
# File lib/mxx_ru/cpp/detect_toolset.rb, line 101 def Cpp.try_load_toolset_file( file_name ) files_to_load = [ file_name, File.join( 'mxx_ru/cpp/toolsets', file_name ) ] load_result = files_to_load.detect { |file_to_load| begin require file_to_load rescue LoadError false end } raise MxxRu::InvalidValueEx.new( "Unable to load Toolset from files: " + "'#{files_to_load.join('; ')}'" ) unless load_result end