diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..0f683c24 --- /dev/null +++ b/.gitignore @@ -0,0 +1,56 @@ +**.dirstamp +**.ko +**.ko.cmd +**.lo +**.m4 +**.mod +**.mod.c +**.mod.cmd +**.o +**.o.cmd +**.order +**.order.cmd +**.swp +**.symvers.cmd +**/.tmp_*.gcno +**/Module.symvers +**~ +.deps +.libs +ChangeLog +Doxyfile +Kbuild +Makefile +Makefile.in +autoconf +autom4te.cache/ +config.h +config.h.in +config.log +config.status +configure +ethercat.spec +examples/dc_user/ec_dc_user_example +examples/user/ec_user_example +examples/user/build/ +fake_lib/libfakeethercat.la +lib/*.cmake +lib/libethercat.la +lib/libethercat.pc +libtool +master/*.o.d +script/ethercat +script/ethercat.service +script/ethercatctl +script/init.d/ethercat +stamp-h1 +tool/ethercat +device_drivers.md +generated_table.md +doxygen-output/ +build/ +build_test/ + +# Conan +test_package/build/ +CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..030bd996 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.15) + +project( + ethercat + VERSION 1.5.2 + DESCRIPTION "IgH EtherCAT Master userspace client library" + LANGUAGES C) + +# Options +option(BUILD_SHARED_LIBS "Build shared library" ON) +set(EC_MAX_NUM_DEVICES + 1 + CACHE STRING + "Max number of Ethernet devices per master (must match kernel module)" +) + +# Library sources +set(LIB_SOURCES + lib/common.c + lib/domain.c + lib/master.c + lib/reg_request.c + lib/sdo_request.c + lib/slave_config.c + lib/voe_handler.c) + +set(LIB_PUBLIC_HEADERS include/ecrt.h include/ectty.h) + +# Create the library +add_library(ethercat ${LIB_SOURCES}) +add_library(EtherLab::ethercat ALIAS ethercat) + +# Set library properties +set_target_properties( + ethercat + PROPERTIES VERSION ${PROJECT_VERSION} + SOVERSION 3 + PUBLIC_HEADER "${LIB_PUBLIC_HEADERS}") + +# Compile definitions These defines substitute for config.h which is generated +# by autotools and primarily used for kernel module. The userspace library only +# needs VERSION, REV, and EC_MAX_NUM_DEVICES. +target_compile_definitions( + ethercat PRIVATE ethercat_EXPORTS EC_MAX_NUM_DEVICES=${EC_MAX_NUM_DEVICES} + VERSION="${PROJECT_VERSION}" REV="") + +# Create a minimal config.h that just checks if defines already exist +file( + WRITE ${CMAKE_CURRENT_BINARY_DIR}/config.h + "/* Minimal config.h for CMake build */ +#ifndef CONFIG_H +#define CONFIG_H +#ifndef VERSION +#define VERSION \"${PROJECT_VERSION}\" +#endif +#ifndef REV +#define REV \"\" +#endif +// #ifndef EC_MAX_NUM_DEVICES +// #define EC_MAX_NUM_DEVICES 1 +// #endif +#endif +") + +# Include directories +target_include_directories( + ethercat + PUBLIC $ + $ + PRIVATE ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/lib + # client lib still needs some header from kernel module + ${CMAKE_CURRENT_SOURCE_DIR}/master) + +# Compile options +target_compile_options(ethercat PRIVATE -fno-strict-aliasing -Wall + -Wmissing-prototypes) + +# Link libraries +if(UNIX) + target_link_libraries(ethercat PRIVATE rt) +endif() + +install( + TARGETS ethercat + EXPORT ethercatTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/conanfile.py b/conanfile.py new file mode 100644 index 00000000..c2927c27 --- /dev/null +++ b/conanfile.py @@ -0,0 +1,99 @@ +from conan import ConanFile +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout +from conan.tools.files import copy +from conan.errors import ConanInvalidConfiguration +import os + + +class IgHEtherCATConan(ConanFile): + name = "igh-ethercat" + version = "1.5.2" + license = "LGPL-2.1-only" + author = "Florian Pose " + url = "https://gitlab.com/etherlab.org/ethercat" + description = "IgH EtherCAT Master userspace client library" + topics = ("ethercat", "industrial", "automation", "fieldbus", "realtime") + settings = "os", "compiler", "build_type", "arch" + options = { + "shared": [True, False], + "fPIC": [True, False], + "max_num_devices": ["ANY"], + } + default_options = { + "shared": True, + "fPIC": True, + "max_num_devices": 1, + } + + exports_sources = ( + "CMakeLists.txt", + "include/*", + "lib/*", + "master/globals.h", + "master/ioctl.h", + "globals.h", + "COPYING", + "COPYING.LESSER", + ) + + def validate(self): + if self.settings.os != "Linux": + raise ConanInvalidConfiguration("IgH EtherCAT Master is only supported on Linux") + + # Validate max_num_devices is a positive integer + try: + max_devices = int(self.options.max_num_devices) + if max_devices < 1: + raise ConanInvalidConfiguration("max_num_devices must be >= 1") + except ValueError: + raise ConanInvalidConfiguration("max_num_devices must be an integer") + + def config_options(self): + if self.settings.os == "Windows": + del self.options.fPIC + + def configure(self): + # This is a C library + self.settings.rm_safe("compiler.libcxx") + self.settings.rm_safe("compiler.cppstd") + + def requirements(self): + self.build_requires("cmake/[>=3.15]") + + def layout(self): + cmake_layout(self, src_folder=".") + + def generate(self): + tc = CMakeToolchain(self) + tc.variables["BUILD_SHARED_LIBS"] = self.options.shared + tc.variables["EC_MAX_NUM_DEVICES"] = str(self.options.max_num_devices) + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + copy( + self, + "COPYING.LESSER", + src=self.source_folder, + dst=os.path.join(self.package_folder, "licenses"), + ) + copy( + self, + "COPYING", + src=self.source_folder, + dst=os.path.join(self.package_folder, "licenses"), + ) + cmake = CMake(self) + cmake.install() + + def package_info(self): + self.cpp_info.libs = ["ethercat"] + self.cpp_info.set_property("cmake_file_name", "ethercat") + self.cpp_info.set_property("cmake_target_name", "EtherLab::ethercat") + self.cpp_info.set_property("pkg_config_name", "libethercat") + if self.settings.os == "Linux": + self.cpp_info.system_libs = ["rt", "pthread"] diff --git a/test_package/CMakeLists.txt b/test_package/CMakeLists.txt new file mode 100644 index 00000000..ca35c2d7 --- /dev/null +++ b/test_package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package C) + +find_package(ethercat REQUIRED CONFIG) + +add_executable(test_package test_package.c) +target_link_libraries(test_package EtherLab::ethercat) diff --git a/test_package/conanfile.py b/test_package/conanfile.py new file mode 100644 index 00000000..64edd6b8 --- /dev/null +++ b/test_package/conanfile.py @@ -0,0 +1,25 @@ +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout +from conan.tools.build import can_run +import os + + +class IgHEtherCATTestConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "CMakeToolchain", "CMakeDeps" + + def requirements(self): + self.requires(self.tested_reference_str) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def layout(self): + cmake_layout(self) + + def test(self): + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "test_package") + self.run(cmd, env="conanrun") diff --git a/test_package/test_package.c b/test_package/test_package.c new file mode 100644 index 00000000..0e8ec0d3 --- /dev/null +++ b/test_package/test_package.c @@ -0,0 +1,20 @@ +#include +#include + +int main(void) +{ + printf("IgH EtherCAT Master Library - Conan Package Test\n"); + printf("ECRT Version: %d.%d\n", ECRT_VER_MAJOR, ECRT_VER_MINOR); + printf("Version magic: 0x%04X\n", ecrt_version_magic()); + + /* Verify that the version magic matches what we expect */ + if (ecrt_version_magic() != ECRT_VERSION_MAGIC) { + fprintf(stderr, "ERROR: Version magic mismatch!\n"); + fprintf(stderr, " Expected: 0x%04X\n", ECRT_VERSION_MAGIC); + fprintf(stderr, " Got: 0x%04X\n", ecrt_version_magic()); + return 1; + } + + printf("Package test passed!\n"); + return 0; +}