Parent CMakeLists.txt overwriting child CMakeLists.txt output directory options

后端 未结 1 1492
一个人的身影
一个人的身影 2020-12-12 07:11

I am trying to place a library from a project into a certain directory in my build output, but the parent CMakeLists.txt is overwriting the output settings. The parent CMake

相关标签:
1条回答
  • 2020-12-12 07:36

    Turning my comments into an answer

    I successfully tested the following with MinGW and CMake 3.3.0 (I reduced your example a little to concentrate on the output directories):

    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()
    

    Now python_shape.pyd is created in python subdirectory.

    What I have changed/removed:

    • Setting the ..._OUTPUT_DIRECTORY global variables in the child CMakeLists.txt is not necessary and/or won't work
    • Added LIBRARY_OUTPUT_DIRECTORY to overwrite the output directory for python_shape MODULE library target (see also e.g. Custom Directory for CMake Library Output)
    • Removed the "by config" settings, because I think it's a feature that multi-configuration make environments like Visual Studio put different configuration binaries into equally named sub-folders.
    • Added some if statements around -std=c++11. It has also only to be set once in the main CMakeLists.txt
    • You don't need to create the output directories "manually", they are created automatically by the make environments

    For the reasoning why your first approach didn't work, see my comments above.

    And I wouldn't recommend the use of file(GLOB ...) to collect source files (see e.g. Why is cmake file GLOB evil? or CMake/Ninja attempting to compile deleted `.cpp` file).

    Alternatives

    As with all languages/frameworks like CMake there is more then one way to do things.

    E.g. you could also use POST_BUILD steps to copy your binaries to a common output directory:

    • see Cmake: use add_custom_command to copy binary to specific location failed when location doesn't exist
    • and - a little more up-to-date utilizing "generator expressions" - CMake: how to specify different steps for different build configurations for Visual Studio?
    0 讨论(0)
提交回复
热议问题