diff --git a/bin/orogen b/bin/orogen index 752226df..8e7115f2 100755 --- a/bin/orogen +++ b/bin/orogen @@ -33,6 +33,9 @@ parser = OptionParser.new do |opt| opt.on("--[no-]extended-states", "disable or enable extended states for all tasks defined in this project (enabled by default)") do |flag| project.extended_states = flag end + opt.on("--[no-]default-deployment", "disable or enable generating a default deployment for the non-abstract oroGen tasks") do |flag| + project.define_default_deployments = flag + end opt.on('--no-transports', "disables all transports (by default, #{DEFAULT_TRANSPORTS.join(", ")} are enabled)") do |transport_names| no_transports = true @@ -62,7 +65,7 @@ parser = OptionParser.new do |opt| opt.on("--target=TARGET", "set the orocos build target (gnulinux or xenomai)") do |target| target = target.to_s - if target !~ /^(gnulinux|xenomai)$/ + if target !~ /^(gnulinux|xenomai|win32)$/ STDERR.puts "unknown target '#{target}', possible values are gnulinux and xenomai" exit 1 end diff --git a/lib/orogen/gen/project.rb b/lib/orogen/gen/project.rb index c0318034..6593a406 100644 --- a/lib/orogen/gen/project.rb +++ b/lib/orogen/gen/project.rb @@ -120,6 +120,8 @@ def inspect; to_s end def linux?; orocos_target == 'gnulinux' end # True if the orocos target is xenomai def xenomai?; orocos_target == 'xenomai' end + # True if the orocos target is Win32 + def win32?; orocos_target == 'win32' end def enable_namespace(value); @disabled_namespaces.delete(value) end def disable_namespace(value); @disabled_namespaces << value end @@ -682,9 +684,9 @@ def generate if self_tasks.any?(&:extended_state_support?) state_types = Generation.render_template( "tasks", "TaskStates.hpp", binding) - header = Generation.save_automatic( - 'typekit', 'types', project.name, "TaskStates.hpp", state_types) - typekit(true).load(header) + header = typekit(true).save_automatic_public_header( + 'types', "TaskStates.hpp", state_types) + typekit(true).load(header, relative_path_from: typekit.automatic_public_header_dir) end if typekit diff --git a/lib/orogen/gen/tasks.rb b/lib/orogen/gen/tasks.rb index 14b8040e..3bce2779 100644 --- a/lib/orogen/gen/tasks.rb +++ b/lib/orogen/gen/tasks.rb @@ -577,15 +577,6 @@ def generate validate_constructors(file_cpp, basename) validate_constructors(file_hpp, basename) - fake_install_dir = File.join(project.base_dir, AUTOMATIC_AREA_NAME, project.name) - FileUtils.mkdir_p fake_install_dir - FileUtils.mkdir_p File.join(fake_install_dir, basepath) - - FileUtils.ln_sf File.join(project.base_dir, "tasks",basepath, "#{basename}.hpp"), - File.join(fake_install_dir, basepath, "#{basename}.hpp") - FileUtils.ln_sf File.join(project.base_dir, AUTOMATIC_AREA_NAME, "tasks",basepath, "#{basename}Base.hpp"), - File.join(fake_install_dir, basepath ,"#{basename}Base.hpp") - self end diff --git a/lib/orogen/gen/typekit.rb b/lib/orogen/gen/typekit.rb index 90b30f6f..255d2852 100644 --- a/lib/orogen/gen/typekit.rb +++ b/lib/orogen/gen/typekit.rb @@ -591,9 +591,6 @@ def self.register_plugin(klass) # Changes the typekit base directory def base_dir=(path) @base_dir = path - if path - include_dirs << path - end end INCLUDE_DIR_NAME = 'types' @@ -601,15 +598,6 @@ def base_dir=(path) # Change the directory into which the code generation should be done def automatic_dir=(path) @automatic_dir = path - if path - include_dirs << File.join(automatic_dir, INCLUDE_DIR_NAME) - end - end - - # Full path to the directory in which includes are either generated - # or symlinked - def includes_dir - File.join(automatic_dir, INCLUDE_DIR_NAME) end # The directory in which generated files that are meant to not be @@ -812,7 +800,7 @@ def find_type(type, is_normalized = false) end rescue Typelib::NotFound => e - if !pending_loads.empty? + if has_pending_loads? perform_pending_loads retry end @@ -840,6 +828,7 @@ def initialize(project = nil) @include_dirs = Set.new @included_files = Array.new + @local_loads_symlinks = Array.new @plugins = [] plugins << (TypekitMarshallers::TypeInfo::Plugin.new(self)) @@ -1130,25 +1119,22 @@ def has_opaques_with_templates? self_opaques.any? { |op| op.generate_templates? } end + attr_reader :local_loads_symlinks + # Handle a load that points to a file in this typekit's source tree - def handle_local_load(file) - rel = Pathname.new(file).relative_path_from(Pathname.new(base_dir)) + def handle_local_load(file, relative_path_from: base_dir) + rel = Pathname.new(file).relative_path_from(Pathname.new(relative_path_from)) return file if rel.each_filename.first == ".." - local_type_dir = Pathname.new(includes_dir) - rel_to_type_dir = Pathname.new(file).relative_path_from(local_type_dir) - if rel_to_type_dir.each_filename.first == ".." - # If the type is within a subdirectory called as the - # typekit, remove the duplicate - elements = rel.each_filename.to_a - if elements.first != self.name - elements.unshift self.name - end - target = File.join(includes_dir, *elements) - Generation.create_or_update_symlink(file, target) - target - else file + # If the type is within a subdirectory called as the + # typekit, remove the duplicate + elements = rel.each_filename.to_a + if elements.first != self.name + elements.unshift self.name end + link = File.join(*elements) + @local_loads_symlinks << [file, link] + link end # call-seq: @@ -1177,11 +1163,7 @@ def handle_local_load(file) # the exact offsets for all the fields in the structures). # # @raises LoadError if the file does not exist - def load(file, add = true, user_options = Hash.new) - if !user_options.respond_to?(:to_hash) - raise ArgumentError, "expected an option has as third argument, got #{user_options.inspect}" - end - + def load(file, add = true, relative_path_from: base_dir, **user_options) if match = /(\w+)\/Types\.hpp$/.match(file) project_name = match[1] if project.has_typekit?(project_name) || project.name == project_name @@ -1189,29 +1171,28 @@ def load(file, add = true, user_options = Hash.new) end end - include_dirs = self.include_dirs + include_dirs = self.include_dirs.dup + include_dirs << automatic_public_header_dir # Get the full path for +file+ - file = - if File.file?(file) # Local file - File.expand_path(file) - else # File from used libraries/task libraries - dir = include_dirs.find { |dir| File.file?(File.join(dir, file)) } - if !dir - raise LoadError, "cannot find #{file} in #{include_dirs.to_a.join(":")}" - end - loaded_files_dirs << dir - File.join(dir, file) + if File.file?(file) # Local file + file = File.expand_path(file) + include_statement = handle_local_load(file, relative_path_from: relative_path_from) + # Local loads are inserted in a normalized install path at + # loading and build time. They have no full path until then + full_path = nil + else # File from used libraries/task libraries + dir = include_dirs.find { |dir| File.file?(File.join(dir, file)) } + if !dir + raise LoadError, "cannot find #{file} in #{include_dirs.to_a.join(":")}" end + loaded_files_dirs << dir + full_path = File.join(dir, file) + include_path = include_dirs.map { |d| Pathname.new(d) } + include_statement = resolve_full_include_path_to_relative(full_path, include_path) + end - # If it is a local header, symlink it to the "right" place in - # typekit/types and load that - file = handle_local_load(file) - - # And resolve it to an include statement - include_path = include_dirs.map { |d| Pathname.new(d) } - inc = resolve_full_include_path_to_relative(file, include_path) - included_files << inc + included_files << include_statement user_options[:rawflags] = self.used_libraries. map { |lib| lib.raw_cflags_only_other }. flatten.uniq @@ -1222,7 +1203,7 @@ def load(file, add = true, user_options = Hash.new) end @pending_load_options = this_options - pending_loads << file + pending_loads << [full_path, include_statement] end def filter_unsupported_types(registry) @@ -1449,14 +1430,17 @@ def resolve_toplevel_include_mapping(toplevel_files, options) return preprocessed, owners end - def make_load_options(pending_loads, user_options) - options = { :opaques_ignore => true, :merge => false, :required_files => pending_loads.to_a } + def make_load_options(required_files, user_options) + user_options = user_options.dup + options = { opaques_ignore: true, merge: false, required_files: required_files } # GCCXML can't parse vectorized code, and the Typelib internal # parser can't parse eigen at all. It is therefore safe to do it # here options[:define] = ["OROCOS_TARGET=#{RTT_CPP.orocos_target}", '__orogen2'] - options[:include] = self.include_dirs.dup + options[:include] = (user_options.delete(:include) || Set.new).to_set | + self.include_dirs | + [automatic_public_header_dir] options = options.merge(user_options) do |key, a, b| if a.respond_to?(:to_ary) if b.respond_to?(:to_ary) @@ -1491,29 +1475,32 @@ def has_pending_loads? end def perform_pending_loads - return if pending_loads.empty? - loads = pending_loads.dup - pending_loads.clear + return if !has_pending_loads? - add, user_options = *pending_load_options + fake_include_dir = Dir.mktmpdir + @local_loads_symlinks.each do |target, link| + FileUtils.mkdir_p File.join(fake_include_dir, File.dirname(link)) + FileUtils.cp target, File.join(fake_include_dir, link) + end - include_dirs = self.include_dirs.to_a - if automatic_dir - include_dirs << File.join(automatic_dir, "types") + pending_loads_to_relative = Hash.new + loads = pending_loads.map do |full_path, include_statement| + full_path ||= File.join(fake_include_dir, include_statement) + pending_loads_to_relative[full_path] = include_statement + full_path end + pending_loads.clear + + add, user_options = *pending_load_options file_registry = Typelib::Registry.new file_registry.merge opaque_registry preprocess_options, options = make_load_options(loads, user_options) + options[:include] << fake_include_dir preprocessed, include_mappings = resolve_toplevel_include_mapping(loads, preprocess_options) - include_path = include_dirs.map { |d| Pathname.new(d) } - pending_loads_to_relative = loads.inject(Hash.new) do |map, path| - map[path] = resolve_full_include_path_to_relative(path, include_path) - map - end - + include_paths = options[:include].map { |p| Pathname.new(p) } include_mappings.each do |file, lines| lines.map! { |inc| pending_loads_to_relative[inc] } end @@ -1539,6 +1526,10 @@ def perform_pending_loads if add self.loads.concat(loads.to_a) end + ensure + if fake_include_dir + FileUtils.remove_entry fake_include_dir + end end METADATA_RELATED_TYPES = ['bitfield'] @@ -1814,8 +1805,8 @@ def handle_opaques_generation(generated_types) marshalling_code = Generation. render_template 'typekit', 'marshalling_types.hpp', binding - path = Generation.save_automatic 'typekit', 'types', self.name, "m_types", "#{type.method_name(true)}.hpp", marshalling_code - self.load(path, true, options) + path = save_automatic_public_header "m_types", "#{type.method_name(true)}.hpp", marshalling_code + self.load(path, true, relative_path_from: automatic_public_header_dir, **options) m_type = intermediate_type_for(type) copy_metadata_to_intermediate_type(type.metadata, m_type.metadata) @@ -1914,10 +1905,14 @@ def code_fromIntermediate(intermediate_type, needs_copy, indent) attr_reader :template_instanciation_files + def automatic_public_header_dir + File.join(automatic_dir, '__include_dir__') + end + def save_automatic_public_header(*args) rel = File.join(self.name, 'typekit', *args[0..-2]) - Generation.save_generated(true, automatic_dir, INCLUDE_DIR_NAME, rel, args[-1]) - rel + Generation.save_generated(true, automatic_public_header_dir, rel, args[-1]) + File.join(automatic_public_header_dir, rel) end def save_automatic(*args) @@ -1972,26 +1967,15 @@ def map_typeset_to_registry(registry, types) types.map { |t| find_type(t) }.to_set end + def relative_path_from_automatic(path) + auto = Pathname.new(automatic_dir) + Pathname.new(path).relative_path_from(auto).to_s + end + def generate typekit = self - FileUtils.mkdir_p automatic_dir - # Populate a fake installation directory so that the include - # files can be referred to as /header.h - fake_install_dir = File.join(automatic_dir, name) - - # Upgrade from directory to symlink - if !File.symlink?(fake_install_dir) - FileUtils.rm_rf fake_install_dir - end - Generation.create_or_update_symlink(automatic_dir, fake_install_dir) - - if standalone? - fake_typekit_dir = File.join(automatic_dir, "typekit") - Generation.create_or_update_symlink(automatic_dir, fake_typekit_dir) - end - # Generate opaque-related stuff first, so that we see them in # the rest of the typelib-registry-manipulation code handle_opaques_generation(registry) @@ -2167,10 +2151,6 @@ def generate save_user("Opaques.hpp", user_hh) implementation_files << save_user("Opaques.cpp", user_cc) - - Generation.create_or_update_symlink( - File.join(user_dir, "Opaques.hpp"), - File.join(automatic_dir, INCLUDE_DIR_NAME, self.name, 'typekit', "Opaques.hpp")) end end diff --git a/lib/orogen/templates/config/Base.cmake b/lib/orogen/templates/config/Base.cmake index 0ae365c8..64a74b7f 100644 --- a/lib/orogen/templates/config/Base.cmake +++ b/lib/orogen/templates/config/Base.cmake @@ -1,4 +1,4 @@ -include(OrogenPkgCheckModules) +include(OroGenTools) ADD_CUSTOM_TARGET(regen <% ruby_bin = RbConfig::CONFIG['RUBY_INSTALL_NAME'] %> <%= ruby_bin %> -S orogen <%= RTT_CPP.command_line_options.join(" ") %> <%= project.deffile %> @@ -10,21 +10,33 @@ add_custom_command( COMMENT "oroGen specification file changed. Run make regen first." COMMAND /bin/false) +option(DISABLE_REGEN_CHECK "disable the check that verifies whether regen should be run" OFF) + +if (NOT DISABLE_REGEN_CHECK) <% if File.file?(project.deffile) %> add_custom_target(check-uptodate ALL DEPENDS "${PROJECT_SOURCE_DIR}/<%= RTT_CPP::AUTOMATIC_AREA_NAME %>/<%= File.basename(project.deffile) %>") <% else %> add_custom_target(check-uptodate ALL) <% end %> +endif() # In Orogen project, the build target is specified at generation time set(OROCOS_TARGET "<%= project.orocos_target %>") # Enable -Wall for compilers that know it include(CheckCXXCompilerFlag) -CHECK_CXX_COMPILER_FLAG("-Wall" CXX_SUPPORTS_WALL) -if (CXX_SUPPORTS_WALL) - add_definitions ("-Wall") + +# Do not enable Wall on WIN32 -- it's really ALL warnings. However, set the +# _CRT_DISABLE_SECURE_WARNINGS which is currently VERY verbose on RTT, boost and +# others +if (WIN32) + add_definitions("-D_CRT_SECURE_NO_WARNINGS") +else() + CHECK_CXX_COMPILER_FLAG("-Wall" CXX_SUPPORTS_WALL) + if (CXX_SUPPORTS_WALL) + add_definitions ("-Wall") + endif() endif() CHECK_CXX_COMPILER_FLAG("-Wno-unused-local-typedefs" CXX_SUPPORTS_WUNUSED_LOCAL_TYPEDEFS) if (CXX_SUPPORTS_WUNUSED_LOCAL_TYPEDEFS) @@ -76,9 +88,9 @@ INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/<%= Generation::AUTOMATIC <% if project.typekit %> # Take care of the typekit ADD_SUBDIRECTORY( ${CMAKE_CURRENT_SOURCE_DIR}/<%= Generation::AUTOMATIC_AREA_NAME %>/typekit ) -INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/<%= Generation::AUTOMATIC_AREA_NAME %>/typekit") -INCLUDE_DIRECTORIES(BEFORE "${CMAKE_CURRENT_SOURCE_DIR}/<%= Generation::AUTOMATIC_AREA_NAME %>/typekit/types") +if (NOT DISABLE_REGEN_CHECK) add_dependencies(check-uptodate check-typekit-uptodate) +endif() <% end %> # Take care of the task library diff --git a/lib/orogen/templates/config/Deployment.cmake b/lib/orogen/templates/config/Deployment.cmake index 3dc2b070..55b90ee0 100644 --- a/lib/orogen/templates/config/Deployment.cmake +++ b/lib/orogen/templates/config/Deployment.cmake @@ -1,11 +1,22 @@ # Task files could be using headers in tasks/ so add the relevant directory in # our include path -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/<%= Generation::AUTOMATIC_AREA_NAME %>/<%= project.name %>) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/<%= Generation::AUTOMATIC_AREA_NAME %>) +include_directories(BEFORE ${PROJECT_BINARY_DIR}/__include_tree__) +include_directories(BEFORE ${PROJECT_SOURCE_DIR}/.orogen/typekit/__include_dir__) +include_directories(BEFORE ${PROJECT_BINARY_DIR}/.orogen/typekit/__include_dir__) +include_directories(BEFORE ${PROJECT_SOURCE_DIR}/__typekit_dir__) +include_directories(BEFORE ${PROJECT_SOURCE_DIR}/__transports_dir__) + +if(WIN32) + add_definitions(-DBOOST_ALL_DYN_LINK) +endif() <% dependencies = deployer.dependencies %> <%= Generation.cmake_pkgconfig_require(dependencies) %> +<%= if deployer.corba_enabled? +Generation.cmake_pkgconfig_require(dependencies, 'corba') +end %> + # Link directories need to be set before(!) providing the target orogen_pkg_check_modules(service_discovery service_discovery) if(service_discovery_FOUND) @@ -65,8 +76,10 @@ install(TARGETS <%= deployer.name %> RUNTIME DESTINATION bin) <% end %> +if (NOT DISABLE_REGEN_CHECK) add_dependencies(<%= deployer.name %> check-uptodate) +endif() configure_file(<%= Generation::AUTOMATIC_AREA_NAME %>/<%= deployer.name %>.pc.in orogen-<%= deployer.name %>.pc @ONLY) diff --git a/lib/orogen/templates/config/OrogenPkgCheckModules.cmake b/lib/orogen/templates/config/OroGenTools.cmake similarity index 50% rename from lib/orogen/templates/config/OrogenPkgCheckModules.cmake rename to lib/orogen/templates/config/OroGenTools.cmake index 6d743df3..5d7a90ea 100644 --- a/lib/orogen/templates/config/OrogenPkgCheckModules.cmake +++ b/lib/orogen/templates/config/OroGenTools.cmake @@ -15,4 +15,20 @@ macro(orogen_pkg_check_modules VARNAME) endif() endmacro() +function(orogen_create_symlink LINK TARGET) + get_filename_component(LINK "${LINK}" ABSOLUTE) + get_filename_component(TARGET "${TARGET}" ABSOLUTE) + get_filename_component(__link_dir "${LINK}" DIRECTORY) + execute_process(COMMAND ${CMAKE_COMMAND} -E make_directory "${__link_dir}") + if (WIN32) + if (IS_DIRECTORY "${TARGET}") + set(__mklink_args /D) + endif() + file(TO_NATIVE_PATH "${LINK}" __native_link) + file(TO_NATIVE_PATH "${TARGET}" __native_target) + execute_process(COMMAND cmd.exe /C mklink ${__mklink_args} "${__native_link}" "${__native_target}") + else() + execute_process(COMMAND cmake -E create_symlink "${TARGET}" "${LINK}") + endif() +endfunction() diff --git a/lib/orogen/templates/config/TaskLib.cmake b/lib/orogen/templates/config/TaskLib.cmake index e4572368..56b7ebdb 100644 --- a/lib/orogen/templates/config/TaskLib.cmake +++ b/lib/orogen/templates/config/TaskLib.cmake @@ -30,28 +30,44 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}) <% if project.typekit %> -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/typekit) +include_directories(${PROJECT_SOURCE_DIR}/.orogen/typekit/__include_dir__/) +include_directories(${PROJECT_BINARY_DIR}/.orogen/typekit/__include_dir__/<%= project.name %>/types) +include_directories(${PROJECT_BINARY_DIR}/.orogen/typekit/__include_dir__/) list(APPEND <%= project.name.upcase %>_TASKLIB_DEPENDENT_LIBRARIES <%= project.name %>-typekit-${OROCOS_TARGET}) <% end %> -<%= dependencies = project.tasklib_dependencies - Generation.cmake_pkgconfig_require(dependencies) %> +<% fake_install_dir = File.join("__include_tree__", project.name) + project.self_tasks.each do |task| + basepath = task.basepath + basename = task.basename + symlink_target_path = File.join(fake_install_dir, basepath) + symlink_source_path = File.join('tasks', basepath) %> +orogen_create_symlink( + "${PROJECT_BINARY_DIR}/<%= symlink_target_path %>/<%= task.basename %>.hpp" + "${PROJECT_SOURCE_DIR}/<%= symlink_source_path %>/<%= task.basename %>.hpp") +orogen_create_symlink( + "${PROJECT_BINARY_DIR}/<%= symlink_target_path %>/<%= task.basename %>Base.hpp" + "${PROJECT_SOURCE_DIR}/<%= AUTOMATIC_AREA_NAME %>/<%= symlink_source_path %>/<%= task.basename %>Base.hpp") +<% end %> +include_directories(${PROJECT_BINARY_DIR}/__include_tree__) + +<% dependencies = project.tasklib_dependencies %> +<%= Generation.cmake_pkgconfig_require(dependencies) %> <% dependencies.each do |dep_def| - next if !dep_def.in_context?('link') %> + next if !dep_def.in_context?('link') %> list(APPEND <%= project.name.upcase %>_TASKLIB_DEPENDENT_LIBRARIES ${<%= dep_def.var_name %>_LIBRARIES}) -<% if dep_def.var_name =~ /TASKLIB/ %> +<% if dep_def.var_name =~ /TASKLIB/ %> list(APPEND <%= project.name.upcase %>_TASKLIB_INTERFACE_LIBRARIES ${<%= dep_def.var_name %>_LIBRARIES}) -<% end %> -<% end %> +<% end + end %> CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/<%= Generation::AUTOMATIC_AREA_NAME %>/tasks/<%= project.name %>-tasks.pc.in ${CMAKE_CURRENT_BINARY_DIR}/<%= project.name %>-tasks-${OROCOS_TARGET}.pc @ONLY) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/<%= project.name %>-tasks-${OROCOS_TARGET}.pc DESTINATION lib/pkgconfig) -<% - include_files = [] +<% include_files = [] task_files = [] project.self_tasks.each do |task| if !task_files.empty? @@ -61,8 +77,7 @@ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/<%= project.name %>-tasks-${OROCOS_TAR task_files << "#{task.basepath}#{task.basename}.cpp" include_files << "${CMAKE_CURRENT_SOURCE_DIR}/../#{Generation::AUTOMATIC_AREA_NAME}/tasks/#{task.basepath}/#{task.basename}Base.hpp" include_files << "#{task.basepath}#{task.basename}.hpp" - end -%> + end %> add_definitions(-DRTT_COMPONENT) set(<%= project.name.upcase %>_TASKLIB_NAME <%= project.name %>-tasks-${OROCOS_TARGET}) diff --git a/lib/orogen/templates/main.cpp b/lib/orogen/templates/main.cpp index 9e12acf1..d8da659e 100644 --- a/lib/orogen/templates/main.cpp +++ b/lib/orogen/templates/main.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -75,7 +76,7 @@ QApplication *qapp; namespace orogen { <% task_activities.each do |task| %> - extern RTT::TaskContext* create_<%= task.task_model.name.gsub(/[^\w]/, '_') %>(std::string const& instance_name); + extern RTT_API RTT::TaskContext* create_<%= task.task_model.name.gsub(/[^\w]/, '_') %>(std::string const& instance_name); <% end %> } @@ -215,6 +216,7 @@ int ORO_main(int argc, char* argv[]) <% end %> <% end %> +<% if !project.win32? %> RTT::types::TypekitRepository::Import( new RTT::types::RealTimeTypekitPlugin ); <% if deployer.transports.include?('corba') %> RTT::types::TypekitRepository::Import( new RTT::corba::CorbaLibPlugin ); @@ -222,6 +224,7 @@ int ORO_main(int argc, char* argv[]) <% if deployer.transports.include?('mqueue') %> RTT::types::TypekitRepository::Import( new RTT::mqueue::MQLibPlugin ); <% end %> +<% end %> <% if deployer.corba_enabled? %> RTT::corba::ApplicationServer::InitOrb(argc, argv); @@ -400,6 +403,8 @@ RTT::internal::GlobalEngine::Instance(ORO_SCHED_OTHER, RTT::os::LowestPriority); } <% if deployer.corba_enabled? %> + +<% if !deployer.project.win32? %> /** Setup shutdown procedure on SIGINT. We use a pipe-based channel to do so, as we can't shutdown the ORB from the signal handler */ if (pipe(sigint_com) == -1) @@ -425,6 +430,7 @@ RTT::internal::GlobalEngine::Instance(ORO_SCHED_OTHER, RTT::os::LowestPriority); std::cerr << "failed to install SIGINT handler" << std::endl; return 1; } +<% end %> <% if has_realtime %> RTT::corba::TaskContextServer::ThreadOrb(ORO_SCHED_RT, RTT::os::LowestPriority, 0); <% else %> diff --git a/lib/orogen/templates/tasks/CMakeLists.txt b/lib/orogen/templates/tasks/CMakeLists.txt index 660b12de..545c8024 100644 --- a/lib/orogen/templates/tasks/CMakeLists.txt +++ b/lib/orogen/templates/tasks/CMakeLists.txt @@ -28,6 +28,7 @@ SET_TARGET_PROPERTIES(${<%= project.name.upcase %>_TASKLIB_NAME} INSTALL(TARGETS ${<%= project.name.upcase %>_TASKLIB_NAME} RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib/orocos LIBRARY DESTINATION lib/orocos) INSTALL(FILES ${<%= project.name.upcase %>_TASKLIB_HEADERS} diff --git a/lib/orogen/templates/tasks/DeployerComponent.cpp b/lib/orogen/templates/tasks/DeployerComponent.cpp index 65dc5140..6e1ee0d3 100644 --- a/lib/orogen/templates/tasks/DeployerComponent.cpp +++ b/lib/orogen/templates/tasks/DeployerComponent.cpp @@ -1,4 +1,5 @@ #include +#include <% deployable_tasks = project.self_tasks.find_all { |t| !t.abstract? } %> <% deployable_tasks.each do |task| %> @@ -13,7 +14,7 @@ ORO_LIST_COMPONENT_TYPE( <%= task.name %> ); namespace orogen { <% deployable_tasks.each do |task| %> - RTT::TaskContext* create_<%= task.name.gsub(/[^\w]/, '_') %>(std::string const& instance_name) + RTT_EXPORT RTT::TaskContext* create_<%= task.name.gsub(/[^\w]/, '_') %>(std::string const& instance_name) { return new <%= task.name %>(instance_name); } diff --git a/lib/orogen/templates/tasks/TaskBase.hpp b/lib/orogen/templates/tasks/TaskBase.hpp index a7ba2e37..f9cff81d 100644 --- a/lib/orogen/templates/tasks/TaskBase.hpp +++ b/lib/orogen/templates/tasks/TaskBase.hpp @@ -14,36 +14,44 @@ #include <% end %> <% if task.extended_state_support? %> -#include <<%= project.typekit.name %>/TaskStates.hpp> +#include <<%= project.typekit.name %>/typekit/types/TaskStates.hpp> <% end %> <% task.self_properties.sort_by(&:name).each do |p| %> <% type = p.type %> <%= project.typekit.cxx_gen_includes(*project.typekit.include_for_type(type)) %> +<% if !project.win32? %> extern template class RTT::Property< <%= type.cxx_name %> >; <% end %> +<% end %> <% task.self_attributes.sort_by(&:name).each do |a| %> <% type = a.type %> <%= project.typekit.cxx_gen_includes(*project.typekit.include_for_type(type)) %> +<% if !project.win32? %> extern template class RTT::Attribute< <%= type.cxx_name %> >; <% end %> +<% end %> <% task.self_ports.sort_by(&:name).each do |p| %> <% type = p.type %> <%= project.typekit.cxx_gen_includes(*project.typekit.include_for_type(type)) %> +<% if !project.win32? %> extern template class <%= p.orocos_class %>< <%= type.cxx_name %> >; extern template class RTT::base::ChannelElement< <%= type.cxx_name %> >; <% end %> +<% end %> <% types = task.self_dynamic_ports. map { |p| [p.orocos_class, p.type] if p.type }. compact %> <% types.each do |orocos_class, type| %> <%= project.typekit.cxx_gen_includes(*project.typekit.include_for_type(type)) %> +<% if !project.win32? %> extern template class <%= orocos_class %>< <%= type.cxx_name %> >; extern template class RTT::base::ChannelElement< <%= type.cxx_name %> >; <% end %> +<% end %> <% task.self_operations.sort_by(&:name).each do |op| %> <% op.used_types.each do |type| %> diff --git a/lib/orogen/templates/typekit/CMakeLists.txt b/lib/orogen/templates/typekit/CMakeLists.txt index 81499d60..7bdfd3fc 100644 --- a/lib/orogen/templates/typekit/CMakeLists.txt +++ b/lib/orogen/templates/typekit/CMakeLists.txt @@ -51,23 +51,45 @@ ADD_CUSTOM_TARGET(regen typegen_bin = 'typegen' %> <%= typegen_bin %> <%= RTT_CPP.command_line_options.join(" ") %> WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/<%= RTT_CPP.relative_generation_directory %>) - <% end %> # END if typekit.standalone? ## +add_definitions(-DRTT_DLL_EXPORT) + +orogen_create_symlink( + "${PROJECT_BINARY_DIR}/__typekit_dir__/<%= typekit.name %>/typekit" + "${CMAKE_CURRENT_SOURCE_DIR}") + +orogen_create_symlink( + "${PROJECT_BINARY_DIR}/__transports_dir__/<%= typekit.name %>/transports" + "${CMAKE_CURRENT_BINARY_DIR}/transports") + # Manually define '-DIS_ROS_PACKAGE' or include the UseOrocos.cmake file to automatically detect&set this flag. if ( IS_ROS_PACKAGE ) # When we import a typekit in a ROS package, we expect it to be in the package/lib directory set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${${CMAKE_PROJECT_NAME}_SOURCE_DIR}/lib/orocos${OROCOS_SUFFIX}/types) endif( IS_ROS_PACKAGE ) -execute_process(COMMAND cmake -E create_symlink - ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/<%= typekit.name %>) +# NOTE: CMAKE_CURRENT_SOURCE_DIR / CMAKE_CURRENT_BINARY_DIR in this file refer +# to the typekit's #automatic_dir. Use #automatic2user_dir to go to the user dir +<% if typekit.has_opaques_with_templates? %> +orogen_create_symlink( + "${PROJECT_BINARY_DIR}/__include_dir__/<%= typekit.name %>/typekit/Opaques.hpp" + "${CMAKE_CURRENT_SOURCE_DIR}/<%= typekit.relative_path_from_automatic(typekit.user_dir) %>/Opaques.hpp") +<% end %> + +<% typekit.local_loads_symlinks.each do |target, link| + target = typekit.relative_path_from_automatic(target) %> +orogen_create_symlink("${CMAKE_CURRENT_BINARY_DIR}/__include_dir__/<%= link %>" "<%= target %>") +<% end %> -include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) -include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/types) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}) +include_directories(BEFORE ${PROJECT_BINARY_DIR}/__typekit_dir__) +include_directories(BEFORE ${PROJECT_BINARY_DIR}/__transports_dir__) +include_directories(BEFORE ${PROJECT_BINARY_DIR}/__include_dir__) +include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/__include_dir__) +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/__include_dir__) +include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}) include_directories(${OrocosRTT_INCLUDE_DIRS}) add_definitions(${OrocosRTT_CFLAGS_OTHER}) @@ -101,7 +123,11 @@ add_library(${libname} SHARED ${TOOLKIT_ADDITIONAL_SOURCES}) <%= Generation.cmake_pkgconfig_link_noncorba('${libname}', typekit_deps) %> -target_link_libraries(${libname} ${OrocosRTT_LIBRARIES} ${TYPEKIT_ADDITIONAL_LIBRARIES} ${TOOLKIT_ADDITIONAL_LIBRARIES}) +target_link_libraries(${libname} ${OrocosRTT_LIBRARIES} + ${TYPEKIT_ADDITIONAL_LIBRARIES} ${TOOLKIT_ADDITIONAL_LIBRARIES}) +if (WIN32) + target_link_libraries(${libname} winmm) +endif() set_target_properties(${libname} PROPERTIES LINK_INTERFACE_LIBRARIES ${OrocosRTT_LIBRARIES}) set_target_properties(${libname} PROPERTIES INTERFACE_LINK_LIBRARIES ${OrocosRTT_LIBRARIES}) if(WITH_RPATH AND APPLE) @@ -112,7 +138,10 @@ endif() set(PKG_CONFIG_FILE ${CMAKE_CURRENT_BINARY_DIR}/<%= typekit.name %>-typekit-${OROCOS_TARGET}.pc) configure_file(<%= typekit.name %>-typekit.pc.in ${PKG_CONFIG_FILE} @ONLY) -install(TARGETS ${libname} LIBRARY DESTINATION lib/orocos${OROCOS_PKG_DIR}/types) +install(TARGETS ${libname} + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib/orocos${OROCOS_PKG_DIR}/types + LIBRARY DESTINATION lib/orocos${OROCOS_PKG_DIR}/types) install(FILES Types.hpp Opaques.hpp DESTINATION include/orocos/<%= typekit.name %>) install(FILES @@ -126,14 +155,23 @@ install(FILES relatives.sort.join("\n ") %> DESTINATION include/orocos/<%= typekit.name %>/typekit) -<% (public_header_files + typekit.included_files).each do |inc| - full_path = Pathname.new(typekit.automatic_dir).join('types', inc) - next if !full_path.exist? - target_dir = File.dirname(inc) - if full_path.symlink? - full_path = full_path.readlink - end - source_file = full_path.relative_path_from(Pathname.new(typekit.automatic_dir)) %> +<% automatic_public_header_dir = Pathname.new(typekit.automatic_public_header_dir) + automatic_dir = Pathname.new(typekit.automatic_dir) %> + +<% public_header_files.each do |full_path| + full_path = Pathname.new(full_path) + target_dir = full_path.dirname.relative_path_from(automatic_public_header_dir) + if full_path.symlink? + full_path = full_path.readlink + end + source_file = full_path.relative_path_from(automatic_dir) %> +install(FILES <%= source_file.to_path %> + DESTINATION include/orocos/<%= target_dir.to_path %>) +<% end %> + +<% typekit.local_loads_symlinks.each do |full_path, include_statement| + source_file = Pathname.new(full_path).relative_path_from(automatic_dir) + target_dir = File.dirname(include_statement) %> install(FILES <%= source_file.to_path %> DESTINATION include/orocos/<%= target_dir %>) <% end %> @@ -165,6 +203,9 @@ add_custom_command( DEPENDS ${TYPEKIT_SOURCE_HEADERS} COMMENT "Typekit input changed. Run make regen in your build directory first" COMMAND /bin/false) + +if (NOT DISABLE_REGEN_CHECK) add_custom_target(check-typekit-uptodate ALL DEPENDS "${TK_STAMP}") add_dependencies(${libname} check-typekit-uptodate) +endif() diff --git a/lib/orogen/templates/typekit/Plugin.hpp b/lib/orogen/templates/typekit/Plugin.hpp index b4a9885d..3da878bd 100644 --- a/lib/orogen/templates/typekit/Plugin.hpp +++ b/lib/orogen/templates/typekit/Plugin.hpp @@ -10,7 +10,7 @@ namespace Typelib { } namespace orogen_typekits { - class <%= typekit.name %>TypekitPlugin + class RTT_API <%= typekit.name %>TypekitPlugin : public RTT::types::TypekitPlugin { Typelib::Registry* m_registry; diff --git a/lib/orogen/templates/typekit/Types.hpp b/lib/orogen/templates/typekit/Types.hpp index 98b9446f..f265d1c0 100644 --- a/lib/orogen/templates/typekit/Types.hpp +++ b/lib/orogen/templates/typekit/Types.hpp @@ -11,6 +11,7 @@ #include <<%= tk.name %>/typekit/Types.hpp> <% end %> +<% if !project.win32? %> <% interface_types.each do |type| %> #ifdef ORO_CHANNEL_ELEMENT_HPP extern template class RTT::base::ChannelElement< <%= type.cxx_name %> >; @@ -35,6 +36,7 @@ extern template class RTT::Attribute< <%= type.cxx_name %> >; #endif <% end %> +<% end %> #endif diff --git a/lib/orogen/templates/typekit/corba/CMakeLists.txt b/lib/orogen/templates/typekit/corba/CMakeLists.txt index 20354cf5..ea604dbe 100644 --- a/lib/orogen/templates/typekit/corba/CMakeLists.txt +++ b/lib/orogen/templates/typekit/corba/CMakeLists.txt @@ -10,6 +10,8 @@ include_directories(${OrocosCORBA_INCLUDE_DIRS}) add_definitions(${OrocosCORBA_CFLAGS_OTHER}) link_directories(${OrocosCORBA_LIBRARY_DIRS}) +add_definitions(-DRTT_DLL_EXPORT) + <%= Generation.cmake_pkgconfig_require(typekit_deps, 'corba') %> # Set up generation of IDL files for CORBA support @@ -43,6 +45,9 @@ endif() target_link_libraries(${libname_corba} <%= typekit.name %>-typekit-${OROCOS_TARGET} ${OrocosCORBA_LIBRARIES}) +if (WIN32) + target_link_libraries(${libname_corba} winmm) +endif() if(WITH_RPATH AND APPLE) set_target_properties( ${libname_corba} PROPERTIES INSTALL_NAME_DIR "@rpath") @@ -56,7 +61,10 @@ set_target_properties(${libname_corba} PROPERTIES INTERFACE_LINK_LIBRARIES ${Oro SET(PKG_CONFIG_FILE_CORBA ${CMAKE_CURRENT_BINARY_DIR}/<%= typekit.name %>-transport-corba-${OROCOS_TARGET}.pc) CONFIGURE_FILE(<%= typekit.name %>-transport-corba.pc.in ${PKG_CONFIG_FILE_CORBA} @ONLY) -install(TARGETS ${libname_corba} LIBRARY DESTINATION lib/orocos${OROCOS_PKG_DIR}/types) +install(TARGETS ${libname_corba} + RUNTIME DESTINATION bin + ARCHIVE DESTINATION lib/orocos${OROCOS_PKG_DIR}/types + LIBRARY DESTINATION lib/orocos${OROCOS_PKG_DIR}/types) install(FILES ${PKG_CONFIG_FILE_CORBA} DESTINATION lib/pkgconfig) install(FILES <%= headers.join("\n ") %> diff --git a/lib/orogen/templates/typekit/corba/TransportPlugin.hpp b/lib/orogen/templates/typekit/corba/TransportPlugin.hpp index e114cdc4..a348abd1 100644 --- a/lib/orogen/templates/typekit/corba/TransportPlugin.hpp +++ b/lib/orogen/templates/typekit/corba/TransportPlugin.hpp @@ -6,7 +6,7 @@ #include namespace orogen_typekits { - class <%= typekit.name %>CorbaTransportPlugin + class RTT_API <%= typekit.name %>CorbaTransportPlugin : public RTT::types::TransportPlugin { public: diff --git a/lib/orogen/templates/typekit/mqueue/CMakeLists.txt b/lib/orogen/templates/typekit/mqueue/CMakeLists.txt index 521b3302..51e21275 100644 --- a/lib/orogen/templates/typekit/mqueue/CMakeLists.txt +++ b/lib/orogen/templates/typekit/mqueue/CMakeLists.txt @@ -33,7 +33,9 @@ target_link_libraries(${libname_mqueue} SET(PKG_CONFIG_FILE_MQueue ${CMAKE_CURRENT_BINARY_DIR}/<%= typekit.name %>-transport-mqueue-${OROCOS_TARGET}.pc) CONFIGURE_FILE(<%= typekit.name %>-transport-mqueue.pc.in ${PKG_CONFIG_FILE_MQueue} @ONLY) -install(TARGETS ${libname_mqueue} LIBRARY DESTINATION lib/orocos${OROCOS_PKG_DIR}/types) +install(TARGETS ${libname_mqueue} + ARCHIVE DESTINATION lib/orocos${OROCOS_PKG_DIR}/types + LIBRARY DESTINATION lib/orocos${OROCOS_PKG_DIR}/types) install(FILES ${PKG_CONFIG_FILE_MQueue} DESTINATION lib/pkgconfig) install(FILES <%= headers.join("\n ") %> diff --git a/lib/orogen/templates/typekit/ros/CMakeLists.txt b/lib/orogen/templates/typekit/ros/CMakeLists.txt index 87ae4a10..14b97922 100644 --- a/lib/orogen/templates/typekit/ros/CMakeLists.txt +++ b/lib/orogen/templates/typekit/ros/CMakeLists.txt @@ -100,7 +100,9 @@ configure_file(<%= typekit.name %>-transport-ros.pc.in ${PKG_CONFIG_FILE_ROS} @O # Needed to generate the config.cmake file configure_file(<%= ros_pkg_name %>-config.cmake.in <%= ros_pkg_name %>-config.cmake @ONLY) -install(TARGETS ${libname_ros} LIBRARY DESTINATION lib/orocos/types) +install(TARGETS ${libname_ros} + ARCHIVE DESTINATION lib/orocos/types + LIBRARY DESTINATION lib/orocos/types) install(FILES ${PKG_CONFIG_FILE_ROS} DESTINATION lib/pkgconfig) install(FILES <%= rosmap %> DESTINATION share/orogen/) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/<%= ros_pkg_name %>-config.cmake DESTINATION share/<%= ros_pkg_name %>/cmake) diff --git a/lib/orogen/templates/typekit/typelib/CMakeLists.txt b/lib/orogen/templates/typekit/typelib/CMakeLists.txt index ff81c040..798b5600 100644 --- a/lib/orogen/templates/typekit/typelib/CMakeLists.txt +++ b/lib/orogen/templates/typekit/typelib/CMakeLists.txt @@ -65,5 +65,7 @@ install(FILES ${PKG_CONFIG_FILE_TYPELIB} DESTINATION lib/pkgconfig) install(FILES TransportPlugin.hpp DESTINATION include/orocos/<%= typekit.name %>/transports/typelib) -install(TARGETS ${libname_typelib} LIBRARY DESTINATION lib/orocos${OROCOS_PKG_DIR}/types) +install(TARGETS ${libname_typelib} + ARCHIVE DESTINATION lib/orocos${OROCOS_PKG_DIR}/types + LIBRARY DESTINATION lib/orocos${OROCOS_PKG_DIR}/types)