Tworzenie biblioteki i załączanie jej

0

Cześć,
Znowu CMake dręczę i przychodzę z zapytaniem,
screenshot-20230521161142.png
W taki sposób wygląda struktura moich plików, z zawartości folderu lib chcę stworzyć bibliotekę dynamiczną, stworzoną bibliotekę oraz pliki z tego procesu wrzucić do lib/build. Bibliotekę chcę udostępnić w main.cpp, a pliki z tego budowania wrzucić do build "głównego".

CMakeLists.txt w folderze głównym

cmake_minimum_required(VERSION 3.22)

project(my_app)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

add_executable(${PROJECT_NAME} main.cpp)

add_subdirectory(lib)

target_link_libraries(${PROJECT_NAME} libsort)

target_include_directories(${PROJECT_NAME} PUBLIC include)

CMakeLists.txt w folderze lib

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY /build)
add_library(libsort SHARED src/sort.cpp include/sort.h)

Coś mi się wydaje że mogłem nie do końca zrozumieć CMAKE_LIBRARY_OUTPUT_DIRECTORY, ale jakbym tego nie przestawiał to też mi nie idzie. Skrypty się wykonują, ale po pierwsze w lib/build nie tworzy się nic, a po drugie przy próbie stworzenia pliku wykonywalnego, wykracza się.

Z góry dzięki za pomoc (;

1

Daj link do projektu na jakimś Gitlabie. Albo przynajmniej komunikat błędu.

set(CMAKE_LIBRARY_OUTPUT_DIRECTORY /build) nie powinno być do niczego potrzebne.

0

Zamiast mówić cmake gdzie ma budować bibliotekę - może po prostu ją zainstaluj ?

Kiedyś w CMakeLits.txt biblioteki miałem coś w tym stylu (nie wszystko mi działało, ale to była zabawa więc nie diagnozowałem do końca)

install ( TARGETS mylib EXPORT mylib-targets
        LIBRARY DESTINATION lib
        ARCHIVE DESTINATION lib
        RUNTIME DESTINATION bin
#       INCLUDES DESTINATION include            # to nie działa... dlaczego ?
        PUBLIC_HEADER DESTINATION include/foo/config
)

# install package configurations in lib/cmake/nrs (add this path to CMAKE_PREFIX_PATH)
install ( EXPORT mylib-targets
        FILE mylibTargets.cmake
        NAMESPACE foo::
        DESTINATION lib/cmake/foo

1

Ogólnie masz program C/C++, CMake to generator Makefile lub innego zależnie od systemu, wygeneruj ten makefile zobacz czy jest poprawny dla twojego programu i potem googluj co chcesz zmienić w wynikowym pliku.

Dodaj VERBOSE, żeby widzieć więcej jakie operacje są wykonywane.

Ja CMake używam tak, że każdą libkę dodaję jako projekt z githuba link i mi się pobiera do katalogu i dodaje.

Generujesz sobie libkę powiedzmy, że jest statyczna żeby dodać bibliotekę do kompilator trzeba dodać flagę -L ze ścieżką gdzie znajduje się libka, możesz dodać główny katalog żeby tam kompilator szukał czy znajduje się libka.

Ja już za dużo dzisiaj wypiłem i nic mi się nie chce.
Można też w cache CMake edytować jakieś variables zmienne ręcznie gdzie tylko otwierasz plik i nadpisujesz wygenerowane zmienne tam łatwo ręcznie spatchować problem i potem poprzez to dojść co poprawić w głównym pliku.

Tak to nie mogę sobie wyobrazić co ty akurat robisz, możesz też podać pliki żeby ktoś lokalnie mógł na to zerknąć czemu to nie działa, bo tak będzie trzeba spreparować example na swoim dysku gdyż z głowy ciężko coś wywnioskować trochę nieintuicyjny jest CMake dlatego ja zawsze patrzę na wygenerowany z CMake Makefile, który akurat ogarniam bardzo dobrze i widzę jakie błędy są w wygenerowanym Makefile i wiem co muszę googlować zeby poprawić w CMake.

2

@ByleDoPrzodu myśl o bibliotece jako o samodzielnym komponencie który może być raz potrzeby a raz nie !

target_link_libraries(${PROJECT_NAME} libsort)
target_include_directories(${PROJECT_NAME} PUBLIC include)

Pierwsza linia OK
Druga linia już jest zbędna , bo samo dodanie biblioteki powinno z automatu dodać wszystkie INCLUDE

Poprawna wersja:
EXE: target_link_libraries(${PROJECT_NAME} libsort)
LIB: target_include_directories(libsort PUBLIC include)

Co do samego problemy pytającego:

		set_target_properties(TARGET_NAME
			PROPERTIES
			RUNTIME_OUTPUT_DIRECTORY "${BIN_I}"
			LIBRARY_OUTPUT_DIRECTORY "${BIN_I}"
			ARCHIVE_OUTPUT_DIRECTORY "${BIN_I}"
			PDB_OUTPUT_DIRECTORY "${BIN_I}")

W głownym pliku cmake mozna dodac funkcję i używać we wszystkich targetach

function(SET_BIN_I name )
		# Set the output directory for build artifacts
		set_target_properties(${name}
			PROPERTIES
			RUNTIME_OUTPUT_DIRECTORY "${BIN_I}"
			LIBRARY_OUTPUT_DIRECTORY "${BIN_I}"
			ARCHIVE_OUTPUT_DIRECTORY "${BIN_I}"
			PDB_OUTPUT_DIRECTORY "${BIN_I}")
endfunction()

SET_BIN_I(libsort)
SET_BIN_I(${PROJECT_NAME})

AHA !
Moim skromnym zdaniem uzywanie wszedzie ${PROJECT_NAME} jest lekka przesadą ;) Ale to moje zdanie

1 użytkowników online, w tym zalogowanych: 0, gości: 1