Question
I'm compiling the following code using catkin_make. I have a c file schedule_wrappers.c
and two c files deadline_thread.cpp
, stepper_motor.cpp
that are being used to create an executable in cmake with the following line:
add_executable(stepper_motor src/stepper_motor.cpp src/deadline_thread.cpp src/schedule_wrappers.c)
The stepper_motor.cpp
file produces a "reasonable" .o
file (the objdump produces output I would expect), but when cmake gets to the link step it says:
/usr/bin/ld: CMakeFiles/stepper_motor.dir/src/stepper_motor.cpp.o: in function `StepperMotorTB6600::run()':
/home/spovilus/catkin_ws/src/beginner_tutorials/include/stepper_motor_TB6600.hpp:73: undefined reference to `wrapper_sched_yield'
/usr/bin/ld: CMakeFiles/stepper_motor.dir/src/stepper_motor.cpp.o: in function `Motor::Motor(int, int)':
/home/spovilus/catkin_ws/src/beginner_tutorials/include/motor.hpp:43: undefined reference to `DeadlineThread::DeadlineThread(int, int)'
/usr/bin/ld: CMakeFiles/stepper_motor.dir/src/stepper_motor.cpp.o:(.data.rel.ro._ZTI5Motor[_ZTI5Motor] 0x18): undefined reference to `typeinfo for DeadlineThread'
I tried to objdump the filed with objdump -t ./build/beginner_tutorials/CMakeFiles/stepper_motor.dir/src/schedule_wrappers.c.o
and got:
./build/beginner_tutorials/CMakeFiles/stepper_motor.dir/src/schedule_wrappers.c.o: file format elf64-littleaarch64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 schedule_wrappers.c
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .debug_info 0000000000000000 .debug_info
0000000000000000 l d .debug_abbrev 0000000000000000 .debug_abbrev
0000000000000000 l d .debug_aranges 0000000000000000 .debug_aranges
0000000000000000 l d .debug_line 0000000000000000 .debug_line
0000000000000000 l d .debug_str 0000000000000000 .debug_str
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .comment 0000000000000000 .comment
and I'm very confused as to why the .text section is empty.
The compiler command cd /home/spovilus/catkin_ws/build/beginner_tutorials && /usr/bin/cc -DROSCONSOLE_BACKEND_LOG4CXX -DROS_BUILD_SHARED_LIBS=1 -DROS_PACKAGE_NAME=\"beginner_tutorials\" -I/home/spovilus/catkin_ws/devel/include -I/home/spovilus/catkin_ws/src/beginner_tutorials/include -I/opt/ros/noetic/include -I/opt/ros/noetic/share/xmlrpcpp/cmake/../../../include/xmlrpcpp -I/home/spovilus/catkin_ws/src/beginner_tutorials/yaml-cpp/include -I/home/spovilus/catkin_ws/src/beginner_tutorials/boost/units/include -O2 -g -DNDEBUG -o CMakeFiles/stepper_motor.dir/src/schedule_wrappers.c.o -c /home/spovilus/catkin_ws/src/beginner_tutorials/src/schedule_wrappers.c
emits warnings:
/home/spovilus/catkin_ws/src/beginner_tutorials/src/schedule_wrappers.c: In function ‘wrapper_sched_set_deadline’:
/home/spovilus/catkin_ws/src/beginner_tutorials/src/schedule_wrappers.c:35:7: warning: implicit declaration of function ‘perror’ [-Wimplicit-function-declaration]
35 | perror("Unable to get scheduler attributes");
| ^~~~~~
/home/spovilus/catkin_ws/src/beginner_tutorials/src/stepper_motor.cpp: In function ‘void positionCallback(const ConstPtr&)’:
/home/spovilus/catkin_ws/src/beginner_tutorials/src/stepper_motor.cpp:34:23: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘const ConstPtr’ {aka ‘const boost::shared_ptr<const beginner_tutorials::RelativePosition_<std::allocator<void> > >’} [-Wformat=]
34 | printf("position %d\n",position);
| ~^
| |
| int
so I have to assume it'd doing something.
Source code
/**
* @file schedule_wrappers.c
* @author Sam Povilus ([email protected])
* @brief A file to wrap Linux Scheduler calls
* @version 0.1
* @date 2023-01-07
*
* @copyright Copyright (c) 2023
*
*/
#include <linux/ioctl.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <linux/sched/types.h>
#include "schedule_wrappers.h"
static int wrapper_sched_getattr(pid_t pid, struct sched_attr *attr,
unsigned int size, unsigned int flags)
{
return syscall(__NR_sched_getattr, pid, attr, size, flags);
}
static int wrapper_sched_set_deadline(int deadline)
{
struct sched_attr attr;
int ret = wrapper_sched_getattr(0, &attr, sizeof(attr), 0);
if (ret < 0)
{
perror("Unable to get scheduler attributes");
// throw scheduler_exception;
}
attr.sched_policy = SCHED_DEADLINE;
attr.sched_deadline = deadline;
return syscall(__NR_sched_setattr, 0, attr, 0);
}
static int wrapper_sched_set_runtime(int runtime)
{
struct sched_attr attr;
int ret = wrapper_sched_getattr(0, &attr, sizeof(attr), 0);
if (ret < 0)
{
perror("Unable to get scheduler attributes");
// throw scheduler_exception;
}
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = runtime;
return syscall(__NR_sched_setattr, 0, attr, 0);
}
static int wrapper_sched_yield()
{
return syscall(__NR_sched_yield);
}
cc version
$ /usr/bin/cc --version
cc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
CodePudding user response:
Why would the .text section of my object file be empty?
Because all your functions are static, they are optimized out.
undefined reference to `wrapper_sched_yield'
If you want the function to be externally visible, remove static
. Also note extern "C"
needed between C <-> C interoperability.
warning: implicit declaration of function ‘perror’
You did not include stdio.h
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘const ConstPtr’ {aka ‘const boost::shared_ptr<const beginner_tutorials::RelativePosition_std::allocator<void > >’}
No idea what you are expecting here to happen. The code is invalid, you can't printf
a boost::shared_ptr
.