2013-03-07 11 views
8

Jestem nowy w CMake i mam problem, że nie mogę znaleźć rozwiązania. Używam CMake do kompilacji projektu z grupą opcjonalnych podkatalogów i buduje pliki biblioteki współdzielonej zgodnie z oczekiwaniami. Ta część wydaje się działać dobrze. Każdy z tych podkatalogów zawiera plik sql. Muszę połączyć wszystkie wybrane pliki sql w jeden plik nagłówkowy sql i zainstalować wynik. Więc jeden plik jak:Używanie CMake, jak mogę połączyć pliki i je zainstalować

sql_header.sql 
sub_dir_A.sql 
sub_dir_C.sql 
sub_dir_D.sql 

Gdybym zrobił to bezpośrednio w pliku make mogę zrobić coś jak następuje tylko inteligentniejsze do czynienia tylko z wybranych podrzędnych katalogów:

cat sql_header.sql > "${INSTALL_PATH}/somefile.sql" 
cat sub_dir_A.sql >> "${INSTALL_PATH}/somefile.sql" 
cat sub_dir_C.sql >> "${INSTALL_PATH}/somefile.sql" 
cat sub_dir_D.sql >> "${INSTALL_PATH}/somefile.sql" 

mam porządek z zorientowali się kawałki to, jak mogę używać:

LIST(APPEND PACKAGE_SQL_FILES "some_file.sql") 

które zakładam mogę umieścić w każdym z plików sub-katalogi CMakeLists.txt zbierać nazwy plików. I mogę utworzyć makro takie jak:

CAT(IN "${PACKAGE_SQL_FILES}" OUT "${INSTALL_PATH}/somefile.sql") 

Ale jestem zagubiony między kiedy CMake początkowo działa i kiedy działa od make install. Być może jest lepszy sposób na zrobienie tego. Potrzebuję tego do pracy zarówno w systemie Windows, jak i Linux.

Byłbym szczęśliwy z pewnymi wskazówkami wskazującymi na mnie we właściwym kierunku.

Odpowiedz

10

Możesz utworzyć połączony plik głównie za pomocą poleceń CMake'a: file i function.

Najpierw utwórz cat funkcję:

function(cat IN_FILE OUT_FILE) 
    file(READ ${IN_FILE} CONTENTS) 
    file(APPEND ${OUT_FILE} "${CONTENTS}") 
endfunction() 

Zakładając masz listę plików wejściowych w zmiennej PACKAGE_SQL_FILES, można korzystać z funkcji takich jak to:

# Prepare a temporary file to "cat" to: 
file(WRITE somefile.sql.in "") 

# Call the "cat" function for each input file 
foreach(PACKAGE_SQL_FILE ${PACKAGE_SQL_FILES}) 
    cat(${PACKAGE_SQL_FILE} somefile.sql.in) 
endforeach() 

# Copy the temporary file to the final location 
configure_file(somefile.sql.in somefile.sql COPYONLY) 

Powodem piśmie do pliku tymczasowego jest tak, że prawdziwy plik docelowy jest aktualizowany tylko wtedy, gdy jego zawartość uległa zmianie. Zobacz, this answer, dlaczego jest to dobre.

Należy pamiętać, że jeśli dodajesz podkatalogi za pomocą polecenia add_subdirectory, wszystkie podkwarki mają własny zakres, jeśli chodzi o zmienne CMake. W podkatalogach użycie parametru list wpłynie tylko na zmienne w zakresie tego podkatalogu.

Jeśli chcesz utworzyć listę dostępną w zasięgu nadrzędnym, musisz użyć set(... PARENT_SCOPE), np.

set(PACKAGE_SQL_FILES 
    ${PACKAGE_SQL_FILES} 
    ${CMAKE_CURRENT_SOURCE_DIR}/some_file.sql 
    PARENT_SCOPE) 

Wszystko to do tej pory stworzyło po prostu połączony plik w katalogu głównym twojego drzewa kompilacji. Aby go zainstalować, prawdopodobnie chcesz użyć komendy install(FILES ...):

install(FILES ${CMAKE_BINARY_DIR}/somefile.sql 
     DESTINATION ${INSTALL_PATH}) 

Tak więc, gdy CUpewnij działa (albo dlatego, ręcznie wywołać ją albo dlatego, że wykrywa zmiany, jeśli nie „make”), to zaktualizuje łączone plik w drzewie kompilacji. Dopiero po uruchomieniu "make install" plik zostanie ostatecznie skopiowany z katalogu głównego instalacji do lokalizacji instalacji.

+0

Przyjemne użycie pliku configure_file ... ;-) – DLRdave

+0

Dzięki, to było bardzo pomocne.Trudno jest uzyskać efekt bubble, jeśli masz wiele katalogów na wielu głębokościach, ale mam go do pracy z bardzo pomocnymi sugestiami. Dzięki! –

+0

Próbowałem tego, i zadziałało ... chyba że plik ma średniki, w którym to się nie powiedzie, ponieważ średniki są po cichu rozebrane. Jest to normalna konsekwencja średników będących separatorem listy w cmake. Najprostszym przypadkiem testowym wskazującym problem jest plik 'set (CONTENTS" a; b; c \ n ") (WRITE out.txt $ {CONTENTS})' Poprawka polega na cytowaniu zawartości podczas pisania, np. '" $ {CONTENTS} "' –

Powiązane problemy