2015-09-05 67 views
0

我想从项目放置到我的生成输出中的某个目录,但父CMakeLists.txt覆盖输出设置。 父CMakeLists.txt将所有库设置为放置在/ lib目录中。父CMakeLists.txt覆盖子CMakeLists.txt输出目录选项

但是,我的一个库需要放在/ python库中。我在Windows上工作的设置。意思是说,除了我的python特定库之外的所有库都被放置在一个/ lib文件夹中,并且python库被放置到/ python文件夹中。

当我在Linux上构建时出现问题。所有库,包括python特定的库,都被放置到/ lib文件夹中。 FORCE选项什么都不做。

如果我只是建立一个平台,我可以处理任一目录布局。但我真的想要保持跨平台的相同布局。

的CMakeLists.txt如下:

-Parent的CMakeLists.txt

cmake_minimum_required(VERSION 2.6) 
project(renderer2d) 

#enable debug symbols by default 
if(CMAKE_BUILD_TYPE STREQUAL "") 
    set(CMAKE_BUILD_TYPE Debug) 
endif() 
#(you can also set on cl: -D CMAKE_BUILD_TYPE=Release) 

#place outside of Debug/Release folders 
SET(OUTPUT_BINDIR ${PROJECT_BINARY_DIR}/bin) 
MAKE_DIRECTORY(${OUTPUT_BINDIR}) 

SET(OUTPUT_LIBDIR ${PROJECT_BINARY_DIR}/lib) 
MAKE_DIRECTORY(${OUTPUT_LIBDIR}) 

SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_LIBDIR} CACHE PATH "build directory") 
SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_BINDIR} CACHE PATH "build directory") 
IF(WIN32) 
    SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_BINDIR} CACHE PATH "build directory") 
ELSE(WIN32) 
    SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_LIBDIR} CACHE PATH "build directory") 
ENDIF(WIN32) 

# For each configuration (Debug, Release, MinSizeRel... and/or anything the user chooses) 
FOREACH(CONF ${CMAKE_CONFIGURATION_TYPES}) 
# Go uppercase (DEBUG, RELEASE...) 
STRING(TOUPPER "${CONF}" CONF) 
SET("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONF}" "${OUTPUT_LIBDIR}") 
SET("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONF}" "${OUTPUT_BINDIR}") 
IF(WIN32) 
    SET("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONF}" "${OUTPUT_BINDIR}") 
ELSE() 
    SET("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONF}" "${OUTPUT_LIBDIR}") 
ENDIF() 
ENDFOREACH() 

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

#set the source directory 
file(GLOB SOURCES src/*.cpp) 

add_subdirectory(shape) 
add_subdirectory(py_shape) 
add_subdirectory(scripts) 

#define sources and executable 
set(EXECUTABLE_NAME "renderer2d") 
add_executable(${EXECUTABLE_NAME} ${SOURCES}) 

#find python 
find_package(PythonInterp) 
find_package(PythonLibs 2.7 REQUIRED) 
include_directories(${PYTHON_INCLUDE_DIRS}) 

#detect and add SFML 
#this line checks a cmake file for hints on where to find cmake 
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) 
#find any version 2.x of SFML 
#see the FindSFML.cmake file for additional details and instructions 
find_package(SFML 2 REQUIRED system window graphics network audio) 
include_directories(${SFML_INCLUDE_DIR}) 

#find and include Boost python libraries 
set(Boost_USE_STATIC_LIBS OFF) 
find_package(Boost COMPONENTS python system filesystem REQUIRED) 
include_directories(${Boost_INCLUDE_DIR}) 

#link all found libraries to the executable 
if(WIN32) 
    target_compile_definitions(${EXECUTABLE_NAME} PRIVATE $<$<BOOL:${MSVC}>:BOOST_ALL_NO_LIB>) 
endif(WIN32) 

target_link_libraries(${EXECUTABLE_NAME} ${PYTHON_LIBRARIES} ${SFML_LIBRARIES} ${Boost_LIBRARIES} shape) 

- 儿童的CMakeLists.txt

cmake_minimum_required(VERSION 2.8) 

project(py_shape CXX) 

#set file variables 
file(GLOB SOURCE src/*.cpp) 
file(GLOB HEADERS inc/*.hpp) 

#place outside of Debug/Release folders 
SET(OUTPUT_BINDIR ${CMAKE_BINARY_DIR}/python) 
MAKE_DIRECTORY(${OUTPUT_BINDIR}) 

set(OUTPUT_LIBDIR ${CMAKEK_BINARY_DIR}/python) 
MAKE_DIRECTORY(${OUTPUT_LIBDIR}) 

SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${OUTPUT_LIBDIR} CACHE PATH "build directory") 
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${OUTPUT_BINDIR} CACHE PATH "build directory") 
IF(WIN32) 
    SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_BINDIR} CACHE PATH "build directory") 
ELSE(WIN32) 
    SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${OUTPUT_LIBDIR} CACHE PATH "build directory") 
ENDIF(WIN32) 

#for each configuration 
FOREACH(CONF ${CMAKE_CONFIGURATION_TYPES}) 
#Go uppercase {DEBUG, RELEASE...) 
SET("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONF}" "${OUTPUT_LIBDIR}") 
SET("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONF}" "${OUTPUT_BINDIR}") 
IF(WIN32) 
    SET("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONF}" "${OUTPUT_BINDIR}") 
ELSE() 
    SET("CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONF}" "${OUTPUT_LIBDIR}") 
ENDIF() 
ENDFOREACH() 

#find packages 
find_package(PythonInterp) 
find_package(PythonLibs 2.7 REQUIRED) 
include_directories(${PYTHON_INCLUDE_DIRS}) 

find_package(Boost COMPONENTS python REQUIRED) 
include_directories(${Boost_INCLUDE_DIR}) 

set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH}) 
find_package(SFML 2 REQUIRED system window graphics network audio) 
include_directories(${SFML_INCLUDE_DIR}) 

#build the library 
add_library(python_shape MODULE ${SOURCE}) 
#enable C++11 if available 
target_compile_features(python_shape PRIVATE cxx_range_for) 
#link library 
target_link_libraries(python_shape shape ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} ${SFML_LIBRARIES}) 
#drop "lib" from the library name 
set_target_properties(python_shape PROPERTIES PREFIX "") 

if(WIN32) 
    #set extension to ".pyd" 
    set_target_properties(python_shape PROPERTIES SUFFIX ".pyd") 
endif(WIN32) 
+0

的变量 - 像'CMAKE_ARCHIVE_OUTPUT_DIRECTORY' - 你正在改变的是全局变量。这些值在解析时并不适用于所有目标,而是在主CMakeLists.txt结尾处(配置步骤结束,1st)被应用于所有目标作为默认值(在make环境生成步骤中,第2次)。 'add_subdirectory()'打开它自己的变量作用域,所以在那里改变为全局变量将无济于事。并且改变子元素“CMakeLists.txt”中的缓存值不会覆盖父元素“CMakeLists.txt”中设置的“正常”变量。 – Florian

+1

请参阅[设置和使用变量的CMake语法是什么?](http://stackoverflow.com/questions/31037882/whats-the-cmake-syntax-to-set-and-use-variables/31044116)以获取更多详细信息。因此,使用'FORCE'(在父类和子类'CMakeLists.txt'中)设置/更改缓存中的所有全局值,或者根据您的描述更改 - 只更改/覆盖相应的'python_shape'目标属性,例如['ARCHIVE_OUTPUT_DIRECTORY' ](http://www.cmake.org/cmake/help/v3.3/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.html)(仅在'python_shape'中覆盖在父'CMakeLists.txt'中设置的默认值)。 – Florian

+0

@弗洛里安我真的想要解决这个问题,而不必回来打扰你,但是我一直没有能够得到它的工作。我试过在我的孩子'CMakeLists.txt'中设置'LIBRARY_OUTPUT_DIRECTORY',但它什么也没做。 'python_shape'仍然被放置在/ lib目录中。由于这个问题,我真的在这个项目中处于停滞状态,所以如果你有任何建议,我会很感激。 – rearden

回答

0

谈到我的意见为答案

我成功测试了以下内容克与MinGW和CMake的3.3.0(I降低你的例子一点集中在输出目录):

的CMakeLists.txt

cmake_minimum_required(VERSION 2.6) 
project(renderer2d C CXX) 

# TODO: Remove, this is just for testing 
file(WRITE "src/renderer2d.cpp" "int main(void) {}") 
file(WRITE "py_shape/src/py_shape.cpp" "") 

#enable debug symbols by default 
if(CMAKE_BUILD_TYPE STREQUAL "") 
    set(CMAKE_BUILD_TYPE Debug) 
endif() 
#(you can also set on cl: -D CMAKE_BUILD_TYPE=Release) 

#place outside of Debug/Release folders 
#see http://www.cmake.org/Wiki/CMake_Useful_Variables 
set(EXECUTABLE_OUTPUT_PATH "${PROJECT_BINARY_DIR}/bin") 
if(WIN32) 
    set(LIBRARY_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}") 
else() 
    set(LIBRARY_OUTPUT_PATH "${PROJECT_BINARY_DIR}/lib") 
endif() 

#see https://stackoverflow.com/questions/10851247/how-to-activate-c-11-in-cmake 
if (CMAKE_VERSION VERSION_LESS "3.1") 
    if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 
    set(CMAKE_CXX_FLAGS "--std=gnu++11 ${CMAKE_CXX_FLAGS}") 
    endif() 
else() 
    set(CMAKE_CXX_STANDARD 11) 
endif() 

#set the source directory 
file(GLOB SOURCES src/*.cpp) 

add_subdirectory(py_shape) 

#define sources and executable 
add_executable(${PROJECT_NAME} ${SOURCES}) 

add_dependencies(${PROJECT_NAME} python_shape) 

py_shape /的CMakeLists.txt

#set file variables 
file(GLOB SOURCE src/*.cpp) 
file(GLOB HEADERS inc/*.hpp) 

#build the library 
add_library(python_shape MODULE ${SOURCE}) 

set_target_properties(python_shape PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/python") 

#drop "lib" from the library name 
set_target_properties(python_shape PROPERTIES PREFIX "") 

if(WIN32) 
    #set extension to ".pyd" 
    set_target_properties(python_shape PROPERTIES SUFFIX ".pyd") 
endif() 

现在python_shape.pyd创建于python子目录。

我已经修改/删除:

  • 在孩子CMakeLists.txt设置..._OUTPUT_DIRECTORY全局变量是没有必要的和/或将无法正常工作
  • 增加LIBRARY_OUTPUT_DIRECTORY覆盖输出目录为python_shapeMODULE库目标(另请参阅,例如Custom Directory for CMake Library Output
  • 删除了“by config”设置,因为我认为这是多配置环境(如Visual Studio将不同的配置二进制文件放入e qually命名的子文件夹。
  • -std=c++11附近增加了一些if陈述。它也仅是在主CMakeLists.txt
  • 设置一次,你并不需要“手动”创建输出目录,它们通过使环境更加

对于推理自动创建的,为什么你的第一种方法没有工作,看到我上面的评论。

而且我也不会建议使用file(GLOB ...)收集源文件(见例如Why is cmake file GLOB evil?CMake/Ninja attempting to compile deleted `.cpp` file)。

替代

与像CMake所有语言/框架有做的事情更多,其中一个方法。

例如你也可以使用POST_BUILD步骤将二进制文件复制到一个公用输出目录: