# # Copyright 2011 Free Software Foundation, Inc. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # ######################################################################## # Parse the arches xml file: # Test each arch to see if the compiler supports the flag. # If the test passes append the arch to the available list. ######################################################################## #extract the arch lines from the xml file using crazy python execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "from xml.dom import minidom; print ';'.join(map(lambda a: '%s %s'%(a.attributes['name'].value,a.getElementsByTagName('flag')[0].firstChild.data),minidom.parse('${CMAKE_SOURCE_DIR}/gen/archs.xml').getElementsByTagName('arch')))" OUTPUT_VARIABLE arch_lines OUTPUT_STRIP_TRAILING_WHITESPACE ) #get any mutually exclusive archs so we can exclude them #this is really for compilers which can do both 32- and 64-bit compilations. execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "from xml.dom import minidom; print ';'.join(map(lambda a: '%s %s'%(a.parentNode.attributes['name'].value,a.firstChild.data),minidom.parse('${CMAKE_SOURCE_DIR}/gen/archs.xml').getElementsByTagName('mutex')))" OUTPUT_VARIABLE mutex_lines OUTPUT_STRIP_TRAILING_WHITESPACE ) #This macro sets the ${arch}_flag variable, #and handles special cases for MSVC arch flags. macro(set_arch_flag name flag) if(MSVC AND ${name} STREQUAL "mmx") set(${name}_flag "/arch:SSE") #no /arch:MMX elseif(MSVC AND ${name} STREQUAL "sse") set(${name}_flag "/arch:SSE") elseif(MSVC AND ${name} STREQUAL "sse2") set(${name}_flag "/arch:SSE2") else() set(${name}_flag -${flag}) endif() endmacro(set_arch_flag) macro(handle_arch name flag) #handle special case for none flag if(${flag} STREQUAL "none") set(have_${name} TRUE) #otherwise test the flag against the compiler else() include(CheckCXXCompilerFlag) set_arch_flag(${name} ${flag}) CHECK_CXX_COMPILER_FLAG(${${name}_flag} have_${name}) endif() if(have_${name}) list(APPEND available_arches ${name}) endif() endmacro(handle_arch) macro(remove_mutex name mutex) if(have_${name}) unset(have_${mutex}) endif() list(REMOVE_ITEM available_arches ${mutex}) endmacro(remove_mutex) #create a list of available arches foreach(arch_line ${arch_lines}) separate_arguments(args UNIX_COMMAND "${arch_line}") handle_arch(${args}) endforeach(arch_line) #strip out mutex archs foreach(mutex_line ${mutex_lines}) separate_arguments(args UNIX_COMMAND "${mutex_line}") remove_mutex(${args}) endforeach(mutex_line) message(STATUS "Available arches: ${available_arches}") ######################################################################## # Parse the machines xml file: # Test each machine to see if its arch dependencies are supported. # Build a list of supported machines and the machine definitions. ######################################################################## #extract the machine lines from the xml file using crazy python execute_process( COMMAND ${PYTHON_EXECUTABLE} -c "from xml.dom import minidom; print ';'.join(map(lambda a: '%s %s'%(a.attributes['name'].value,a.getElementsByTagName('archs')[0].firstChild.data),minidom.parse('${CMAKE_SOURCE_DIR}/gen/machines.xml').getElementsByTagName('machine')))" OUTPUT_VARIABLE machine_lines OUTPUT_STRIP_TRAILING_WHITESPACE ) macro(handle_machine1 name) unset(machine_flags) string(TOUPPER LV_MACHINE_${name} machine_def) #check if all the arches are supported foreach(arch ${ARGN}) set(is_match ${have_${arch}}) if(NOT is_match) set(is_match FALSE) break() endif(NOT is_match) set(machine_flags "${machine_flags} ${${arch}_flag}") endforeach(arch) if(is_match) #this is a match, append the source and set its flags set(machine_source ${CMAKE_CURRENT_BINARY_DIR}/volk_machine_${name}.c) set_source_files_properties(${machine_source} PROPERTIES COMPILE_FLAGS ${machine_flags}) list(APPEND machine_sources ${machine_source}) list(APPEND machine_defs ${machine_def}) list(APPEND available_machines ${name}) endif() endmacro(handle_machine1) macro(handle_machine name) set(arches ${ARGN}) list(FIND arches "32|64" index) if(${index} EQUAL -1) handle_machine1(${name} ${arches}) else() list(REMOVE_ITEM arches "32|64") handle_machine1(${name}_32 32 ${arches}) handle_machine1(${name}_64 64 ${arches}) endif() endmacro(handle_machine) #setup the available machines foreach(machine_line ${machine_lines}) separate_arguments(args UNIX_COMMAND "${machine_line}") handle_machine(${args}) endforeach(machine_line) message(STATUS "Available machines: ${available_machines}") ######################################################################## # Create rules to run the volk generator ######################################################################## #list of the generated sources set(volk_gen_sources ${CMAKE_BINARY_DIR}/include/volk/volk.h ${CMAKE_BINARY_DIR}/lib/volk.c ${CMAKE_BINARY_DIR}/lib/volk_init.h ${CMAKE_BINARY_DIR}/include/volk/volk_typedefs.h ${CMAKE_BINARY_DIR}/include/volk/volk_cpu.h ${CMAKE_BINARY_DIR}/lib/volk_cpu.c ${CMAKE_BINARY_DIR}/include/volk/volk_config_fixed.h ${CMAKE_BINARY_DIR}/lib/volk_environment_init.c ${CMAKE_BINARY_DIR}/lib/volk_environment_init.h ${CMAKE_BINARY_DIR}/lib/volk_machines.h ${CMAKE_BINARY_DIR}/lib/volk_machines.c ${machine_sources} ) #dependencies are all python, xml, and header implementation files file(GLOB xml_files ${CMAKE_SOURCE_DIR}/gen/*.xml) file(GLOB py_files ${CMAKE_SOURCE_DIR}/gen/*.py) file(GLOB h_files ${CMAKE_SOURCE_DIR}/include/volk/*.h) #make sure we can use -B with python (introduced in 2.6) execute_process( COMMAND ${PYTHON_EXECUTABLE} -B -c "" OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT ) if(PYTHON_HAS_DASH_B_RESULT EQUAL 0) set(PYTHON_DASH_B "-B") endif() add_custom_command( OUTPUT ${volk_gen_sources} DEPENDS ${xml_files} ${py_files} ${h_files} COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B} ${CMAKE_SOURCE_DIR}/gen/volk_register.py ${CMAKE_BINARY_DIR} ) ######################################################################## # Handle orc support ######################################################################## find_package(PkgConfig) if(PKG_CONFIG_FOUND) PKG_CHECK_MODULES(ORC "orc-0.4 > 0.4.11") endif(PKG_CONFIG_FOUND) find_program(ORCC_EXECUTABLE orcc) if(ORC_FOUND AND ORCC_EXECUTABLE) #setup orc library usage include_directories(${ORC_INCLUDE_DIRS}) link_directories(${ORC_LIBRARY_DIRS}) add_definitions(-DLV_HAVE_ORC) #setup orc functions file(GLOB orc_files ${CMAKE_SOURCE_DIR}/orc/*.orc) foreach(orc_file ${orc_files}) #extract the name for the generated c source from the orc file get_filename_component(orc_file_name_we ${orc_file} NAME_WE) set(orcc_gen ${CMAKE_CURRENT_BINARY_DIR}/${orc_file_name_we}.c) #create a rule to generate the source and add to the list of sources add_custom_command( COMMAND ${ORCC_EXECUTABLE} --implementation -o ${orcc_gen} ${orc_file} DEPENDS ${orc_file} OUTPUT ${orcc_gen} ) list(APPEND volk_sources ${orcc_gen}) endforeach(orc_file) else() message(STATUS "Did not find liborc and orcc, disabling orc support...") endif() ######################################################################## # Setup the volk sources list and library ######################################################################## if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32) #http://gcc.gnu.org/wiki/Visibility add_definitions(-fvisibility=hidden) endif() include_directories( ${CMAKE_BINARY_DIR}/include ${CMAKE_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) list(APPEND volk_sources ${CMAKE_CURRENT_SOURCE_DIR}/volk_prefs.c ${CMAKE_CURRENT_SOURCE_DIR}/volk_rank_archs.c ${volk_gen_sources} ) #set the machine definitions where applicable set_source_files_properties( ${CMAKE_CURRENT_BINARY_DIR}/volk.c ${CMAKE_CURRENT_BINARY_DIR}/volk_machines.c PROPERTIES COMPILE_DEFINITIONS "${machine_defs}") if(MSVC) #add compatibility includes for stdint types include_directories(${CMAKE_SOURCE_DIR}/msvc) #compile the sources as C++ due to the lack of complex.h under MSVC set_source_files_properties(${volk_sources} PROPERTIES LANGUAGE CXX) endif(MSVC) #create the volk runtime library add_library(volk SHARED ${volk_sources}) target_link_libraries(volk ${ORC_LIBRARIES}) set_target_properties(volk PROPERTIES SOVERSION ${LIBVER}) set_target_properties(volk PROPERTIES DEFINE_SYMBOL "volk_EXPORTS") install(TARGETS volk LIBRARY DESTINATION lib${LIB_SUFFIX} COMPONENT "volk_runtime" # .so file ARCHIVE DESTINATION lib${LIB_SUFFIX} COMPONENT "volk_devel" # .lib file RUNTIME DESTINATION bin COMPONENT "volk_runtime" # .dll file ) ######################################################################## # Build the QA test application ######################################################################## find_package(Boost COMPONENTS unit_test_framework) if(Boost_FOUND) set_source_files_properties( ${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc PROPERTIES COMPILE_DEFINITIONS "BOOST_TEST_DYN_LINK;BOOST_TEST_MAIN" ) include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) add_executable(test_all ${CMAKE_CURRENT_SOURCE_DIR}/testqa.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_utils.cc ) target_link_libraries(test_all volk ${Boost_LIBRARIES}) #ADD_TEST(qa_volk_test_all test_all) endif()