Как скомпилировать и запустить библиотеку SFML/Network.hpp в Visual Studio Code
использую Visual Studio Code, операционная система Debian 12. Программа из учебника - простейший сканер порта. Идёт обращение на локальном хосте к порту 80, если порт открыт то возвращается строка OPEN, иначе CLOSED. Код файла scaner5_2.cpp:
#include <iostream>
#include <SFML/Network.hpp>
#include <string>
using namespace std;
bool is_port_open(const std::string& address, int port)
{
return (sf::TcpSocket().connect(address,port) == sf::Socket::Done);
}
int main()
{
if (is_port_open("localhost",80))
{
cout << "OPEN";
}else{
cout << "CLOSED";
}
return 0;
}
Код файла Makefile:
CXX := g++
CXX_FLAGS := -Wall -Wextra -std=c++17 -ggdb
BIN := bin
SRC := src
INCLUDE := include
LIB := lib
LIBRARIES :=
EXECUTABLE := scaner5_2
all: $(BIN)/$(EXECUTABLE)
run: clean all
clear
./$(BIN)/$(EXECUTABLE)
$(BIN)/$(EXECUTABLE): $(SRC)/*.cpp
$(CXX) $(CXX_FLAGS) -I$(INCLUDE) -L$(LIB) $^ -o $@ $(LIBRARIES)
clean:
-rm $(BIN)/*
Ссылка на zip архив с проектом на githab https://github.com/goodwin039/C-/blob/main/Scaner_5_2.zip. Ссылка на архив, а не на сам код потому, что пока не разобрался как гитом на линуксе пользоваться.
В общем на Visual studio Code, используя расширение Easy C++ projects v2.0.0 создал проект, далее в терминале воспользовался командой make, но вышли ошибки:
user@debian:~/projects/Scaner_5_2$ make
g++ -Wall -Wextra -std=c++17 -ggdb -Iinclude -Llib src/scaner5_2.cpp -o bin/scaner5_2
/usr/bin/ld: /tmp/ccegUOta.o: предупреждение: перемещение указывает на «_ZN2sf4Time4ZeroE» из раздела только для чтения «.text»
/usr/bin/ld: /tmp/ccegUOta.o: в функции «is_port_open(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int)»:
/home/user/projects/Scaner_5_2/src/scaner5_2.cpp:9: неопределённая ссылка на «sf::TcpSocket::TcpSocket()»
/usr/bin/ld: /home/user/projects/Scaner_5_2/src/scaner5_2.cpp:9: неопределённая ссылка на «sf::IpAddress::IpAddress(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)»
/usr/bin/ld: /home/user/projects/Scaner_5_2/src/scaner5_2.cpp:9: неопределённая ссылка на «sf::Time::Zero»
/usr/bin/ld: /home/user/projects/Scaner_5_2/src/scaner5_2.cpp:9: неопределённая ссылка на «sf::TcpSocket::connect(sf::IpAddress const&, unsigned short, sf::Time)»
/usr/bin/ld: /tmp/ccegUOta.o:(.data.rel.ro._ZTIN2sf9TcpSocketE[_ZTIN2sf9TcpSocketE]+0x10): неопределённая ссылка на «typeinfo for sf::Socket»
/usr/bin/ld: /tmp/ccegUOta.o: в функции «sf::TcpSocket::~TcpSocket()»:
/usr/include/SFML/Network/TcpSocket.hpp:46: неопределённая ссылка на «sf::Socket::~Socket()»
/usr/bin/ld: предупреждение: создаётся DT_TEXTREL в PIE
collect2: error: ld returned 1 exit status
make: *** [Makefile:20: bin/scaner5_2] Ошибка 1
Так понимаю в файле Makefile, в строке LIBRARIES := требуется указать список библиотек. Подскажите какие библиотеки требуется подключить чтобы исправить ошибку.
P.S. SFML командой sudo apt-get install libsfml-dev уже установил.
Ответы (1 шт):
Вместо того, чтобы спрашивать у нас конкретный флаг (вы же не собираетесь про каждую новую библиотеку тут спрашивать), лучше понять принцип.
Нормальные библиотеки сообщают необходимые флаги через pkg-config.
Сначала определяем имя библиотеки в pkg-config: pkg-config --list-all | grep -i sfml.
Если вдруг такой поиск ничего не находит (для SFML находит), открываем список файлов в пакете и ищем там .pc. Имя файла без пути и без расширения .pc = имя для pkg-config.
Потом зовем pkg-config --libs ИмяБиблиотеки используя это имя, чтобы узнать флаги линковщика. Бонусные очки, если будете делать это автоматически из мейкфайла.
Еще стоит позвать pkg-config --cflags ИмяБиблиотеки и вписать это во флаги компилятора (для каких-то библиотек и без этого работает, но лучше это делать всегда).
Если в списке файлов в пакете нет .pc, то вместо этого ищем там одно из: lib??.a, lib??.so (только линукс), lib??.dll.a (только винда), и используем флаг -l?? (-l плюс имя файла без префикса lib и без расширения).