versiones guia español actualizar unix cmake cross-platform

unix - guia - Parent CMakeLists.txt sobrescribe las opciones de directorio de salida de CMakeLists.txt hijo



qgis español (1)

Estoy tratando de colocar una biblioteca de un proyecto en un determinado directorio en mi salida de compilación, pero el padre CMakeLists.txt sobrescribe la configuración de salida. El padre CMakeLists.txt establece todas las bibliotecas que se colocarán en un directorio / lib.

Sin embargo, una de mis bibliotecas debe colocarse en una biblioteca / python. La configuración que tengo funciona en Windows. Es decir, todas las librerías excluyendo mi biblioteca específica de python se colocan en una carpeta / lib, y la lib de python se coloca en la carpeta / python.

El problema aparece cuando construyo en Linux. Todas las bibliotecas, incluida la biblioteca específica de Python, se colocan en la carpeta / lib. La opción FORCE no hace nada.

Si solo estuviera construyendo para una plataforma, podría tratar con cualquier diseño de directorio. Pero realmente quiero preservar el mismo diseño en todas las plataformas.

CMakeLists.txt de la siguiente manera:

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

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


Convertir mis comentarios en una respuesta

Probé con éxito lo siguiente con MinGW y CMake 3.3.0 (reduje un poco tu ejemplo para concentrarme en los directorios de salida):

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://.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()

Ahora python_shape.pyd se crea en el subdirectorio python .

Lo que he cambiado / eliminado:

  • Establecer las variables globales__ ..._OUTPUT_DIRECTORY en el niño CMakeLists.txt no es necesario y / o no funcionará
  • Se agregó LIBRARY_OUTPUT_DIRECTORY para sobrescribir el directorio de salida para python_shape MODULE library target (ver también p. Ej. Custom Directory para CMake Library Output )
  • Se eliminó la configuración "por configuración", porque creo que es una característica que los entornos de configuración multiconfiguración como Visual Studio pongan diferentes binarios de configuración en subcarpetas igualmente nombradas.
  • Se agregaron algunas sentencias if alrededor de -std=c++11 . También solo debe establecerse una vez en el principal CMakeLists.txt
  • No es necesario que cree los directorios de salida "manualmente", sino que los crea automáticamente

Por el razonamiento de por qué su primer enfoque no funcionó, vea mis comentarios arriba.

Y no recomendaría el uso de file(GLOB ...) para recopilar archivos fuente (consulte, por ejemplo, ¿Por qué el archivo cmake GLOB está mal? O CMake / Ninja intentando compilar el archivo `.cpp` eliminado ).

Alternativas

Al igual que con todos los lenguajes / marcos como CMake hay más de una forma de hacer las cosas.

Por ejemplo, también podría usar los pasos de POST_BUILD para copiar sus binarios en un directorio de salida común: