#c #meson-build
#c #meson-build
Вопрос:
У меня есть проект Meson C со следующей компоновкой:
├── include
│ ├── cxxopts.hpp
│ ├── json.hpp
│ ├── loguru
│ └── redis-cpp
├── meson.build
└── src
├── frame_utils
│ ├── frame_utils.cpp
│ ├── frame_utils.h
│ └── meson.build
├── meson.build
├── source.cpp
Основной meson.build
файл включает в себя следующее:
project(
'test',
'cpp',
version : '0.1',
default_options :
['warning_level=3', 'cpp_std=c 17']
)
compiler = meson.get_compiler('cpp')
all_deps = [
dependency('threads'),
compiler.find_library('dl', required : false),
# additional deps filled by subdirectories
]
all_includes = [
include_directories('include/redis-cpp'),
include_directories('include/loguru'),
include_directories('include')
]
# filled by subdirectories
source_files = []
subdir('src')
Тот, который находится внутри src
, имеет следующий код:
subdir('frame_utils')
exe = executable(
'source',
'source.cpp',
install : false,
include_directories : all_includes,
dependencies : all_deps,
link_with: frame_utils_lib
)
И тот, который в frame_utils
:
all_includes = include_directories('.')
frame_utils_lib = static_library(
'frame_utils',
'frame_utils.cpp',
install : false
)
Библиотека очень проста, состоит из пространства имен и одной функции:
#ifndef FRAME_UTILS_H
#define FRAME_UTILS_H
#include <cstdlib>
namespace frame_utils {
double timecode_to_ms(int64_t timestamp);
}
#endif
Теперь в моем source.cpp
файле я вызываю функцию из frame_utils
, например, так:
#include "frame_utils.h"
// ...
frame_utils::timecode_to_ms(video_frame.timestamp)
Здесь video_frame.timestamp
int64_t
.
Когда я создаю проект, я получаю следующую ошибку из ld
:
FAILED: src/source
c -o src/source src/source.p/source.cpp.o -Wl,--as-needed -Wl,--no-undefined -Wl,--start-group src/frame_utils/libframe_utils.a -pthread -ldl -Wl,--end-group
/usr/bin/ld: src/source.p/source.cpp.o: in function `...':
/builddir/../src/source.cpp:111: undefined reference to `frame_utils::timecode_to_ms(long)'
/usr/bin/ld: /builddir/../src/source.cpp:112: undefined reference to `frame_utils::timecode_to_ms(long)'
collect2: error: ld returned 1 exit status
Код Visual Studio способен правильно разрешать пространство имен и имя / подпись функции. Чего мне не хватает?
Библиотека определенно экспортирует эту функцию:
$ nm builddir/src/frame_utils/libframe_utils.a
frame_utils.cpp.o:
0000000000000000 T _Z14timecode_to_msl
Кроме того, когда я копирую ту же функцию с той же подписью (только без пространства имен) в source.cpp
файл, она работает правильно.
Ответ №1:
Ошибка была связана с определением самой функции в .cpp
файле. Это должно быть настроено следующим образом:
#include "frame_utils.h"
namespace frame_utils {
double timecode_to_ms(int64_t timestamp) {
return (double)timestamp / 10000.0;
}
}
Раньше это было так:
#include "frame_utils.h"
using namespace frame_utils;
double timecode_to_ms(int64_t timestamp) {
return (double)timestamp / 10000.0;
}
По какой-то причине VS Code смог разрешить эту функцию, но компоновщик — нет.