Testowanie plików wykonywalnych

0

Mam projekt CMake z plikiem wykonywalnym, oraz testy do tego projektu. Korzystam z boost unit test. W jaki sposób powinienem zalinkować binarkę projektu z binarką testów?

Próbowałem ustawić ENABLE_EXPORTS dla binarki projektu, jednak z tego issue wynika że binarki można linkować tylko do bibliotek, więc w ten sposób się nie zalinkuję.

Drugie podejście to zalinkowanie binarki testów do bibliotek i plików obiektowych projektu. Jednak w tym podejściu pojawia się kolejny problem - wielokrotne definicje funkcji main - main głównego projektu i main z boosta. Wolałbym uniknąć atrybutu weak przy głównej funkcji.

Projekt piszę obecnie na linuksie, docelowo chciałbym żeby działał również na windowsie, więc potrzebuję rozwiązania multiplatformowego. W jaki sposób mogę to osiągnąć?

Rozwiązanie które mi przychodzi do głowy to biblioteka na cały kod, do której będą się linkować binarka projektu z mainem i binarka testów, jednak jestem ciekawy czy nie ma mniej zmieniających strukturę projektu rozwiązań tego problemu.

1
arciobus napisał(a):

Mam projekt CMake z plikiem wykonywalnym, oraz testy do tego projektu. Korzystam z boost unit test. W jaki sposób powinienem zalinkować binarkę projektu z binarką testów?

Próbowałem ustawić ENABLE_EXPORTS dla binarki projektu, jednak z tego issue wynika że binarki można linkować tylko do bibliotek, więc w ten sposób się nie zalinkuję.

Drugie podejście to zalinkowanie binarki testów do bibliotek i plików obiektowych projektu. Jednak w tym podejściu pojawia się kolejny problem - wielokrotne definicje funkcji main - main głównego projektu i main z boosta. Wolałbym uniknąć atrybutu weak przy głównej funkcji.

Projekt piszę obecnie na linuksie, docelowo chciałbym żeby działał również na windowsie, więc potrzebuję rozwiązania multiplatformowego. W jaki sposób mogę to osiągnąć?

Rozwiązanie które mi przychodzi do głowy to biblioteka na cały kod, do której będą się linkować binarka projektu z mainem i binarka testów, jednak jestem ciekawy czy nie ma mniej zmieniających strukturę projektu rozwiązań tego problemu.

Ja spotkałem się z dwoma rozwiązaniami tego problemu:

  1. Tak jak piszesz w ostatnim zdaniu - czyli cała esencja kodu jest w projekcie bibliotecznym, do tego jest dodawany projekt tworzący plik wykonywalny, sam pozbawiony logiki, który jedynie tworzy i uruchamia obiekt z biblioteki. Tę bibliotekę możemy potem dolinkować do testów.

  2. W cmake'u projektu mamy:

project (aaa LANGUAGES CXX)
...
enable_testing()
add_subdirectory(tests)

a w katalogu 'tests' mamy drugiego cmake'a, dla projektu testowego, w którym definiujemy binarki testowe i dołączamy projekt zewnętrzny.

add_executable(aaa_test aaa_test.cpp)
add_definitions(-DBOOST_TEST_DYN_LINK) 

target_link_libraries(aaa_test PRIVATE
	${PROJECT_NAME}
        Boost::unit_test_framework
)
0

Drugie podejście to to, co obecnie mam. Jednak nie mogę zalinkować binarki projektu, do binarki testu. Bo do tego sprowadza się to rozwiązanie, prawda?

1
arciobus napisał(a):

Drugie podejście to to, co obecnie mam. Jednak nie mogę zalinkować binarki projektu, do binarki testu. Bo do tego sprowadza się to rozwiązanie, prawda?

Faktycznie, wziąłem przykład z jakiegoś swojego projektu, a to była biblioteka, a nie wykonywalny.
No to pozostaje chyba tylko pierwsze rozwiązanie. Z grubsza wygląda to tak, że masz katalog projektu z kodem, CMakeLists.txt (1), i katalogiem 'tests', a w nim kolejny CMakeLists.txt (2) i kody testów.

CMakelists.txt (1)

project (aaa LANGUAGES CXX)
...
add_library(${PROJECT_NAME}_lib STATIC
      // tu ida Twoje zrodla
     ...
)

target_link_libraries(${PROJECT_NAME}_lib PUBLIC
      // tu ida wszystkie zaleznosci
      ...
)

add_executable(${PROJECT_NAME}_app
	src/main.cpp
)

target_link_libraries(${PROJECT_NAME}_app PRIVATE
	${PROJECT_NAME}_lib
)

enable_testing()
add_subdirectory(tests)

CMakeLists.txt (2)

add_executable(aaa1_test aaa1_test.cpp)
set_target_properties (aaa1_test PROPERTIES FOLDER tests)
add_definitions(-DBOOST_TEST_DYN_LINK) 

target_link_libraries(aaa1_test PRIVATE
	${PROJECT_NAME}_lib
        Boost::unit_test_framework
	Boost::disable_autolinking 
	Boost::dynamic_linking
)
0

W takim razie dodam tą bibliotekę, dzięki za pomoc :D

0
arciobus napisał(a):

W takim razie dodam tą bibliotekę, dzięki za pomoc :D

Teraz mi się przypomniało, że to drugie rozwiązanie to wcale nie było to co napisałem (bo to co napisałem w sumie nie różniło się zbytnio od pierwszego), tylko że w Cmake'u testowym dodawało się do targetu te same źródła co do pliku wykonywalnego. Oczywiście wewnątrz katalogu tests, każdy plik źródłowy foo.cpp będzie ../foo.cpp, więc nie za się wszystkich zródel wrzucic do jednej zmiennej i dołączyć do obu targetów, i trzeba chyba niestety kazdy plik dodawac osobno, poprzedzajac ... Rozwiązanie mniej eleganckie, ale dla mniejszych projektów może być wygodniejsze.

0

Można to zrobić łatwiej, dodając zamiast plików cpp już skompilowane pliki .o. Problem jednak jest z tym, że mamy zduplikowaną funkcję main. Trzeba wtedy plik z jej definicją wyłączyć z listy plików. Dodatkowo trzeba wyciągnąć z targetu ścieżki include, biblioteki i ustawić takie same flagi kompilacji. Działa, ale to bardziej obejście, a nie rozwiązanie.

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