Имеется примерно следующий проект на Cmake
:
+-----------------+
+----| lpviop_server |
| +-----------------+
+------------+ | | |
| |----------------+ | |
| lpviop |----------+ | |
| |----+ | +---------------+ |
+------------+ | +--------| lpvoip_client | |
| +---------------+ |
+---------------+----/ |
| lpvoip_core |------------------------+
+---------------+
Что бы было более понятно опишу словами: lpviop_client
так же как lpviop_server
должны ссылаться на проект lpvoip_core
.
Проект Cmake
lpvoip:
cmake_minimum_required(VERSION 3.12)
project(lpvoip)
add_subdirectory(lpvoip_server) # executable
add_subdirectory(lpvoip_client) # executable
add_subdirectory(lpvoip_core) # library
Как мне правильно слинковать оба проекта, на проект lpviop_core
?
Я не понимаю как линковаться на проект расположенный в сабдиректории.
Знакомая проблема: дело дело в том, что если вы использовали переменные, то они так и остались в области видимости файла (субдиректории) и не доступны ни в главной ни в других субдиректориях. Для того, чтобы можно было использовать переменные в другой директории их нужно поместить в кэш
set(ANY_LIB "my_lib" CACHE STRING "it is my lib" FORCE)
Последний параметр указывает что если имеется глобальная переменная с этим же именем, то перезаписать его. Так что сдесь есть по крайней мере одна проблема. К тому же если вы в этом файле поменяете имя переменной, то придется менять его и в других файлах. Я предложу лучший способ - он прекрасен)
В главном CMakeLists.txt
указываете:
set(TARGETS_LIST CACHE STRING "list for all targets" FORCE)
Этим действием мы заводим список в глобальной области видимости - в него то мы и будем записывать все переменные (названия библиотек). Дальше в ваших субдиректориях добавляете только одну строку:
set(TARGETS_LIST "${TARGETS_LIST};${ANY_LIB}" CACHE STRING "reload list" FORCE)
Сдесь нельзя использовать APPEND
так как он не работает с глобальной областью видимости. Таким образом, после обхода субдиректорий вы получите список всех библиотек. А дальше их линковку можно автоматизировать с помощью foreach
:
foreach(SOME_TARGET ${TARGETS_LIST})
target_link_libraries(${PROJECT_NAME} ${SOME_TARGET})
endforeach()
Таким образом, сколько бы у вас не бало библиотек, вам не нужно прыгать по всем файлам и добавлять данные, просто пишите смаке файл для субдиректории и в главном файле добавляете субдиректорию. Кстати, с субдиректориями тоже можно поступить также.
Примерно так, с плюшками для MS студии
:
project(mytest)
set_property( GLOBAL PROPERTY USE_FOLDERS ON )
set( CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Configs" FORCE )
set( CMAKE_SUPPRESS_REGENERATION true )
set( CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true )
set( CMAKE_SKIP_PACKAGE_ALL_DEPENDENCY true )
set( PREDEFINED_TARGETS_FOLDER "CmakeDepends" )
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}/../src
)
set(lib_hdrs
${CMAKE_CURRENT_SOURCE_DIR}/../include/header1.h
${CMAKE_CURRENT_SOURCE_DIR}/../src/header2.h
....
)
set(lib_srcs
${CMAKE_CURRENT_SOURCE_DIR}/../src/func1.c
${CMAKE_CURRENT_SOURCE_DIR}/../src/func2.c
....
)
set( lib_target "libmy" )
add_library( ${lib_target} STATIC ${lib_srcs} ${lib_hdrs} )
set( app_target "TestMy" )
add_executable( ${app_target} "../my-main.c" )
target_link_libraries( ${app_target} ${lib_target} )
set_property( DIRECTORY
${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${app_target}
)
пояснять мне кажется тут нечего :)
Виртуальный выделенный сервер (VDS) становится отличным выбором
Вообще хотел бы получить данные из камеры, преобразовать это в flv формат, и вывести по rtmp, но наверное это только мечтаПробывал ffmpeg программу...
Написал сокет-сервер на python (ubuntu), а клиента на c++ (windows)Проблема в том, что на сервере функция recv требует оповещение об закрытиии сокета (shutdown)...
При компиляции кода в IntelliJ IDEA всё работает отлично, но как только вывожуjar и пытаюсь запустить его, пишет ошибку:
Есть массив, нужно каждый элемент массива прогнать через цикл с добавлением цифрПроблема в том, что код прогоняет только первый элемент массива