2017-05-30 345 views
0

我正在嘗試使用CMake(Windows上的CLion)構建我的C++應用程序。應用程序使用儲蓄庫,以及那些已經成功地建立與Microsoft Visual 2015年我可以用內置SCons的應用程序(至少我希望如此):CMake無法找到Thrift庫

import os 
from os import path, listdir 

gen_cpp = [path.join('gen-cpp', f) for f in listdir('gen-cpp') if f.endswith('.cpp')] 
client_source = [path.join('logic', folder, f) for folder in ['', 'parser', 'mars', 'view'] 
       for f in listdir(path.join('logic', folder)) if f.endswith('.cpp')] 
server_source = [path.join('server', 'server.cpp')] 
tests_source = [path.join('test_cases', f) for f in listdir('test_cases') if f.endswith('.cpp')] 

cpppath = ['.','c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\src\\','c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\src\\thrift\\server', 
'c:\\Users\\Antek\\libs\\boost_1_64_0\\boost\\'] 

libpath = ['C:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\x64\\Release\\', 'c:\\Users\\Antek\\libs\\boost_1_64_0\\boost\\stage\\x64\\lib\\', 
      'C:\\OpenSSL-Win64\\lib'] 

libs = ['libthrift','libssl','openssl','libcrypto'] 

env = Environment(CPPPATH = cpppath, 
        LIBS = libs, 
        LIBPATH = libpath, 
        MSVC_VERSION='14.0', 
        CPPFLAGS='/EHsc', 
        ) 


gen_cpp_o = env.Object(gen_cpp) 
client_o = env.Object(client_source) 
tests_o = env.Object(tests_source) 
tests_files = gen_cpp_o + [f for f in client_o if str(f) != path.join('logic', 'main.obj')] + tests_o 

env.Program('CoreWars', gen_cpp_o + client_o) 
env.Program('Server', gen_cpp_o + server_source) 
env.Program('tests', tests_files) 

.exe文件,作爲「scons的」的結果創建命令,工作得很好。但是,當我嘗試做構建應用程序與CMake的,這樣的:

cmake_minimum_required(VERSION 3.7) 
project(client) 

SET (THRIFT_ROOT "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0") 
SET (THRIFT_INCLUDEDIR "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\src") 
SET (THRIFT_LIBRARYDIR "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\x64\\Release") 

include_directories(${THRIFT_INCLUDEDIR}) 

MESSAGE("Thrift_LIBRARIES: ${THRIFT_LIBRARYDIR}") 
MESSAGE("Thrift_INCLUDES: ${THRIFT_INCLUDEDIR}") 

#find_package(Thrift REQUIRED) 

set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 

SET (BOOST_ROOT "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost") 
SET (BOOST_INCLUDEDIR "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost") 
SET (BOOST_LIBRARYDIR "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost\\libs") 

find_package(Boost 1.64.0 REQUIRED) 

include_directories(${Boost_INCLUDE_DIRS}) 



set(SOURCE_FILES ../gen-cpp/MARS.cpp ../gen-cpp/mars_constants.cpp ../gen-cpp/mars_types.cpp main.cpp 
     parser/InstructionFactory.cpp parser/RedcodeParser.cpp parser/InstructionData.cpp ServerConnector.cpp 
     mars/Instruction.cpp mars/InstructionOperator.cpp parser/ParserException.cpp MainController.cpp 
     mars/MarsSimulator.cpp Initializer.cpp Player.cpp Player.h PlayerInfo.cpp PlayerInfo.h Warrior.cpp 
     Warrior.h PlayerCreator.cpp PlayerCreator.h view/ViewInput.cpp view/ViewInput.h MarsResult.cpp MarsResult.h 
     mars/DatInstruction.cpp mars/DatInstruction.h mars/MovInstruction.cpp mars/MovInstruction.h) 
add_executable(CoreWars ${SOURCE_FILES}) 

target_link_libraries(CoreWars ${Boost_LIBRARIES} $(THRIFT_LIBRARYDIR)) 

CMake的報告錯誤:

[ 4%] Linking CXX executable CoreWars.exe 
G__~1.EXE: error: $(THRIFT_LIBRARYDIR): No such file or directory 
mingw32-make.exe[3]: *** [logic/CoreWars.exe] Error 1 

如果我試圖找到節儉庫find_package(Thrift REQUIRED)命令,我收到以下錯誤:

CMake Error at logic/CMakeLists.txt:13 (find_package): 
    By not providing "FindThrift.cmake" in CMAKE_MODULE_PATH this project has 
    asked CMake to find a package configuration file provided by "Thrift", but 
    CMake did not find one. 

    Could not find a package configuration file provided by "Thrift" with any 
    of the following names: 

    ThriftConfig.cmake 
    thrift-config.cmake 

我將不勝感激任何幫助。


EDIT1

我試圖解決我的問題,這個問題的幫助:CMake link to external library,但不幸的是,它並沒有爲我工作。 我已經編輯我的CMakeList.txt:

cmake_minimum_required(VERSION 3.7) 
project(client) 

set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 

SET (THRIFT_ROOT "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0") 
SET (THRIFT_INCLUDEDIR "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\src") 
SET (THRIFT_LIBRARYDIR "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\x64\\Release") 

MESSAGE("Thrift_LIBRARIES: ${THRIFT_LIBRARYDIR}") 
MESSAGE("Thrift_INCLUDES: ${THRIFT_INCLUDEDIR}") 

find_library(THRIFT_FOUND_LIB thrift PATHS ${THRIFT_LIBRARYDIR}) 
MESSAGE("Thrift found lib: ${THRIFT_FOUND_LIB}") 

link_libraries(thrift "${THRIFT_FOUND_LIB}") 
link_directories(${THRIFT_LIBRARYDIR}) 
include_directories(${THRIFT_INCLUDEDIR}) 

SET (BOOST_ROOT "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost") 
SET (BOOST_INCLUDEDIR "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost") 
SET (BOOST_LIBRARYDIR "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost\\libs") 

find_package(Boost 1.64.0 REQUIRED) 
include_directories(${Boost_INCLUDE_DIRS}) 

set(SOURCE_FILES ../gen-cpp/MARS.cpp ../gen-cpp/mars_constants.cpp ../gen-cpp/mars_types.cpp main.cpp 
     parser/InstructionFactory.cpp parser/RedcodeParser.cpp parser/InstructionData.cpp ServerConnector.cpp 
     mars/Instruction.cpp mars/InstructionOperator.cpp parser/ParserException.cpp MainController.cpp 
     mars/MarsSimulator.cpp Initializer.cpp Player.cpp Player.h PlayerInfo.cpp PlayerInfo.h Warrior.cpp 
     Warrior.h PlayerCreator.cpp PlayerCreator.h view/ViewInput.cpp view/ViewInput.h MarsResult.cpp MarsResult.h 
     mars/DatInstruction.cpp mars/DatInstruction.h mars/MovInstruction.cpp mars/MovInstruction.h) 
add_executable(CoreWars ${SOURCE_FILES}) 


MESSAGE("Cmake prefix path: ${CMAKE_PREFIX_PATH}") 
LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) 
target_link_libraries(CoreWars ${Boost_LIBRARIES} thrift) 

CMake的commnad find_library成功找到我的節儉。下面是CMake的輸出:

C:\Users\Antek\AppData\Local\JetBrains\Toolbox\apps\CLion\ch-0\171.4073.41\bin\cmake\bin\cmake.exe -DCMAKE_BUILD_TYPE=Release -G "CodeBlocks - MinGW Makefiles" C:\Users\Antek\Documents\MEGAsync\_STUDIA\ZPR\proj1\Core-Wars-ZPR 
Thrift_LIBRARIES: c:\Users\Antek\libs\thrift-0.10.0\thrift-0.10.0\lib\cpp\x64\Release 
Thrift_INCLUDES: c:\Users\Antek\libs\thrift-0.10.0\thrift-0.10.0\lib\cpp\src 
Thrift found lib: C:/Users/Antek/libs/thrift-0.10.0/thrift-0.10.0/lib/cpp/x64/Release/libthrift.lib 
-- Boost version: 1.64.0 
Cmake prefix path: 
-- Configuring done 
-- Generating done 
-- Build files have been written to: C:/Users/Antek/Documents/MEGAsync/_STUDIA/ZPR/proj1/Core-Wars-ZPR/cmake-build-release 

但是,當我嘗試將我的項目中,有一個錯誤:

[ 4%] Linking CXX executable CoreWars.exe 
C:/PROGRA~1/MINGW-~1/X86_64~1.2-P/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/4.9.2/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lthrift 

我缺少的東西?請注意,節儉採用x64/Release模式構建,我在CLion中使用x64 mingw,而CMake也處於發佈模式。 謝謝。


EDIT2

fiew改進後,連接器似乎能夠找到節儉。但是,現在,我得到未定義的參考...錯誤。爲節儉和一些提升庫。例如:

CMakeFiles\CoreWars.dir/objects.a(MARS.cpp.obj):MARS.cpp:(.text+0x454): undefined reference to `apache::thrift::TApplicationException::write(apache::thrift::protocol::TProtocol*) const' 

CMakeFiles\CoreWars.dir/objects.a(MARS.cpp.obj):MARS.cpp:(.text.startup+0x11): undefined reference to `boost::system::generic_category()' 

什麼可能是這個錯誤的原因是什麼? $ {Boost_LIBRARIES}不應該包含Boost.System庫路徑嗎?谷歌搜索解決方案似乎不適合在這種情況下。

更新的CMakeLists.txt:

cmake_minimum_required(VERSION 3.7) 
project(client) 

set(CMAKE_CXX_STANDARD 11) 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 

SET (THRIFT_ROOT "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0") 
SET (THRIFT_INCLUDE_DIR "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\src") 
SET (THRIFT_LIB_DIR "c:\\Users\\Antek\\libs\\thrift-0.10.0\\thrift-0.10.0\\lib\\cpp\\x64\\Release") 

find_library(THRIFT_FOUND_LIB thrift PATHS ${THRIFT_LIB_DIR}) 
MESSAGE("Found Thrift lib: ${THRIFT_FOUND_LIB}") 

find_path(THRIFT_FOUND_HEADERS thrift PATHS ${THRIFT_INCLUDE_DIR}) 
MESSAGE("Found Thrift headers: ${THRIFT_FOUND_HEADERS}") 

include_directories(${THRIFT_FOUND_HEADERS}) 
link_directories(${THRIFT_FOUND_HEADERS}) 
link_directories(${THRIFT_FOUND_LIB}) 

SET (BOOST_ROOT "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost") 
#SET (BOOST_INCLUDEDIR "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost") 
#SET (BOOST_LIBRARYDIR "c:\\Users\\Antek\\libs\\boost_1_64_0\\boost\\libs") 

find_package(Boost 1.64.0 REQUIRED) 
include_directories(${Boost_INCLUDE_DIRS}) 
link_directories(${Boost_LIBRARIES}) 

set(SOURCE_FILES ../gen-cpp/MARS.cpp ../gen-cpp/mars_constants.cpp ../gen-cpp/mars_types.cpp main.cpp 
     parser/InstructionFactory.cpp parser/RedcodeParser.cpp parser/InstructionData.cpp ServerConnector.cpp 
     mars/Instruction.cpp mars/InstructionOperator.cpp parser/ParserException.cpp MainController.cpp 
     mars/MarsSimulator.cpp Initializer.cpp Player.cpp Player.h PlayerInfo.cpp PlayerInfo.h Warrior.cpp 
     Warrior.h PlayerCreator.cpp PlayerCreator.h view/ViewInput.cpp view/ViewInput.h MarsResult.cpp MarsResult.h 
     mars/DatInstruction.cpp mars/DatInstruction.h mars/MovInstruction.cpp mars/MovInstruction.h) 
add_executable(CoreWars ${SOURCE_FILES}) 

target_include_directories(CoreWars SYSTEM PUBLIC ${THRIFT_FOUND_HEADERS}) 
target_link_libraries(CoreWars LINK_PUBLIC ${THRIFT_FOUND_LIB} ${Boost_LIBRARIES}) 

再次感謝你。

+1

看起來你是路過的目錄到哪裏尋找庫,但實際庫'的不是名稱libthrift.lib' [CMake的鏈接到外部庫 –

+0

可能的複製](https://stackoverflow.com/questions/8774593/cmake-link-to-external-library) – Tsyvarev

+1

至於給定的錯誤信息,它會導致錯字:'$(THRIFT_LIBRARYDIR)'應該替換爲'$ {THRIFT_LIBRARYDIR }',因爲在CMake變量中引用'$ {}'。 (但修正了錯字後,你會得到錯誤'無法打開文件,它是目錄'而不是。) – Tsyvarev

回答

1

看起來您正在傳遞查找庫的目錄,而不是實際庫的名稱。加入你的CMakelists。TXT,它應該工作:

target_include_directories(${THRIFT_INCLUDEDIR}) 
target_link_libraries(CoreWars ${Boost_LIBRARIES} libthrift.lib) # Or may be just 'thrift' 
+0

是的,你說得對。但是,糾正這個錯誤後,它仍然找不到節儉:(請參閱我的問題的編輯。 – 3voC