Я хотел бы знать, как правильно построить проект с использованием SCons, когда он зависит от внешних пакетов.
Рассмотрим следующую программу hello_world.cpp
#include <iostream>
#include "external_package/external_header.hpp"
int main(int argc, char* argv[])
{
std::cout<<"Hello World!"<<std::endl;
return 0;
}
Я мог бы собрать его с помощью CMake через следующий файл CMakeLists.txt
find_package(external_package REQUIRED)
include_directories(${external_package_INCLUDE_DIRS})
add_executable(hello_world hello_world.cpp)
target_link_libraries(hello_world ${external_package_LIBRARIES})
install(TARGETS hello_world
DESTINATION bin)
Что было бы эквивалентным файлом SConstruct? В частности, как имитировать функциональность find_package?
Это то, что я до сих пор придумал. Sconstruct
env = Environment()
env.Append(CPPPATH = [])
env.Append(LIB_PATH=[])
env.Program("hello_world", ["hello_world.cpp"])
Я думаю, что мне следует заполнить CPPPATH с помощью $ {external_package_INCLUDE_DIRS} и LIBPATH с помощью $ {external_package_LIB_DIRS}, но я не понимаю, как их автоматически найти.
ОБНОВЛЕНИЕ: мой вопрос не очень ясен. Я хотел бы иметь файл SConstruct, который выполняет те же функции, что и предоставленный CMake. Он должен построить проект, который имеет внешнюю зависимость.
Я спрашиваю, как мне создать файл Sconstruct, который дает тот же результат, что и файл CMakeLists. Моя интуиция подсказывает, что мне каким-то образом нужны списки файлов $ {external_package_INCLUDE_DIRS} и $ {external_package_LIBRARIES}, которые в рабочем примере создаются с помощью find_package ()
Возможным вариантом может быть использование подсистемы pkg-config
. Предоставляет ли ваш внешний пакет соответствующий файл конфигурации?
Вы спрашиваете, как реализовать find_package ()? Или просто разумный способ установить для каждого пакета путь и библиотеки?
@bdbaddog второй. Спасибо
@dirkbaechle, не могли бы вы привести пример того, как проверить наличие такого файла и как использовать pkg-config для моих целей? Спасибо
Если вы хотите использовать pkg-config, тогда это действительно другой вопрос, чем выбор метода для именования переменных для используемых пакетов. Тем не менее вы можете использовать метод инструмента, указанный в моем ответе ниже, чтобы отделить файл pkg-config. См. ParseFlags здесь: (scons.org/doc/production/HTML/scons-man.html#f-ParseFlags)
Итак, есть несколько способов сделать это:
1) Имейте префикс для переменных среды, которые вы используете для указания путей к пакетам и т. д. Предполагая, что вы включите некоторую логику, которая устанавливает PACKAGE_A_INCLUDE_DIRS и т. д.
env = Environment()
env.AppendUnique(CPPPATH = '$PACKAGE_A_INCLUDE_DIRS')
env.AppendUnique(LIBPATH = '$PACKAGE_A_LIBS')
env.Program("hello_world", ["hello_world.cpp"])
2) Используйте инструмент для установки требуемых переменных. Это использование может не совпадать с названием «инструмент», но другие использовали это хорошо.
env = Environment()
env.Tool('PACKAGE_A')
env.Program("hello_world", ["hello_world.cpp"])
Тогда в site_scons / site_tools у вас будет файл с именем PACKAGE_A.py следующим образом:
def exists(env):
return True
def generate(env):
env.AppendUnique('LIBPATH'=['/path/to/libs'])
env.AppendUnique('CPPPATH'=['/path/to/headers',...])
Затем вы можете просто добавить env.Tool ('some_package') в каждую среду, которая должна его использовать.
Спасибо за ответ. Однако для этого мне потребуется вручную указать путь к заголовкам и библиотекам, которые зависят от того, как пользователь установил этот пакет. Есть ли способ для Scons автоматически находить эти файлы (как это делает CMake)? Еще раз спасибо
cmake ищет файлы Find <package> .cmake. Так вы спрашиваете, могут ли SCons их использовать? Или сработает использование файлов pkg-config? В этом случае ParseFlags () должен работать, и, как я сказал в своем комментарии к вашим исходным вопросам, вы можете обернуть их в инструмент. В основном любое решение, которое не использует файлы Find <PACKAGE> .cmake, потребует либо a) знание того, где они установлены, указано выше. б) использование файлов pkg-config, в) какой-либо метод извлечения информации из других источников. Однако есть ли такие пакеты в вашей песочнице и вам просто нужно ссылаться на верхнюю?
Вы можете попытаться прояснить исходный вопрос дальше. Если мой ответ правильный, то ваш вопрос может быть более ясным: «Как я могу использовать scons для управления добавлением флагов для других пакетов в мою среду сборки?» Потому что мой ответ не совсем отвечает, как делать то, что делает ваш cmake.
Насколько я понимаю, find_package () работает, находя файл с именем Find <package> .cmake в CMAKE_MODULE_PATH. Вы спрашиваете, может ли SCons загрузить файл пакета cmake find? Или что-то другое?