| |
| # This function adds targets for a specified package within the |
| # Go standard library. This will include the *.gox file for the package, |
| # as well as targets for PIC and non-PIC objects. Example usage: |
| # |
| # Example usage: |
| # |
| # add_go_package(pkgpath <dest> |
| # GOSRC .../x.go .../y.go ... GODEP a.gox b.gox ...) |
| # |
| # Unnamed parameters: |
| # |
| # * Package path, e.g. "bufio" or "container/heap". |
| # * Destination directory for libgo build artifacts |
| # |
| # Named parameters: |
| # |
| # GOSRC Full paths of go source files to build. |
| # GODEP Names of export files for packages this package depends on. |
| # GOCFLAGS Additional arguments passed to Go compiler. |
| # NOPIC Don't bother to produce a PIC object, create only non-PIC. |
| |
| function(add_go_package pkgpath dest) |
| CMAKE_PARSE_ARGUMENTS(ARG "NOPIC" "" "GOSRC;GODEP;GOCFLAGS" ${ARGN}) |
| |
| # Split package path into name and containing_dir |
| get_filename_component(pdir "${pkgpath}" DIRECTORY) |
| get_filename_component(name "${pkgpath}" NAME) |
| if( "${pdir}" STREQUAL "") |
| set(pdir ".") |
| endif() |
| |
| # Note: currently no 32-bit support, need to revisit once we have -m32 |
| |
| # Dependent packages (*.gox files). The fully qualified paths are |
| # needed primarily for correct dependency generation; the actual |
| # export data for packages is read from *.o files picked up |
| # implicitly via the "-I ." passed to the driver. |
| set(godeps) |
| foreach( godep ${ARG_GODEP} ) |
| list(APPEND godeps "${dest}/${godep}") |
| endforeach() |
| |
| # Non-PIC object file, PIC object file |
| set(package_ofile "${dest}/${pdir}/${name}.o") |
| set(package_picofile "${dest}/${pdir}/.pic/${name}.o") |
| |
| # Export file, export file temp. |
| set(package_goxfile "${dest}/${pdir}/${name}.gox") |
| set(package_goxtmp "${dest}/${pdir}/${name}.gox.tmp") |
| |
| # All outputs |
| set(pkg_outputs) |
| |
| # Mangle packagepath (convert golang_org => vendor/golang_org). |
| string(REPLACE "golang_org" "vendor/golang_org" pkgpath "${pkgpath}") |
| |
| # Command to build non-PIC object file |
| add_custom_command( |
| OUTPUT ${package_ofile} |
| COMMAND ${CMAKE_COMMAND} -E make_directory "./${pdir}" |
| COMMAND "${gocompiler}" "-c" "-o" ${package_ofile} "-fgo-pkgpath=${pkgpath}" ${ARG_GOCFLAGS} -I . ${ARG_GOSRC} |
| DEPENDS ${ARG_GOSRC} ${godeps} ${gocdep} |
| COMMENT "Building Go package '${pkgpath}' (non-PIC)" |
| VERBATIM) |
| list(APPEND pkg_outputs "${package_ofile}") |
| |
| # Command to build PIC object file |
| if(NOT ARG_NOPIC) |
| add_custom_command( |
| OUTPUT "${package_picofile}" |
| COMMAND ${CMAKE_COMMAND} -E make_directory "./${pdir}/.pic" |
| COMMAND "${gocompiler}" "-c" "-o" ${package_picofile} -fPIC "-fgo-pkgpath=${pkgpath}" ${ARG_GOCFLAGS} -I . ${ARG_GOSRC} |
| DEPENDS ${ARG_GOSRC} ${godeps} ${gocdep} |
| COMMENT "Building Go package '${pkgpath}' (PIC)" |
| VERBATIM) |
| list(APPEND pkg_outputs "${package_picofile}") |
| else() |
| set(package_picofile) |
| endif() |
| |
| # Command to build *.gox.tmp |
| set(objcopycommand "objcopy") |
| if (GOLLVM_DRIVER_DIR) |
| set(objcopycommand "${LLVM_DEFAULT_TARGET_TRIPLE}-objcopy") |
| endif() |
| |
| add_custom_command( |
| OUTPUT "${package_goxtmp}" |
| COMMAND "${objcopycommand}" -j .go_export "${package_ofile}" "${package_goxtmp}" |
| DEPENDS ${package_ofile} ${package_picofile} |
| COMMENT "Building Go exports file for package '${pkgpath}'" |
| VERBATIM) |
| |
| # Command to update *.gox if different from *.gox.tmp |
| add_custom_command( |
| OUTPUT "${package_goxfile}" |
| COMMAND ${CMAKE_COMMAND} -E copy_if_different |
| "${package_goxtmp}" "${package_goxfile}" |
| DEPENDS "${package_goxtmp}" |
| COMMENT "Updating Go exports file for package '${pkgpath}'" |
| VERBATIM) |
| list(APPEND pkg_outputs "${package_goxfile}") |
| |
| # Target name, using underscores, e.g. "container/heap" |
| # creates a target of "libgo_container_heap" |
| string(REPLACE "/" "_" ptarget "${pkgpath}") |
| set(pkgtarget "libgo_${ptarget}") |
| |
| # Create target |
| add_custom_target(${pkgtarget} ALL DEPENDS ${pkg_outputs}) |
| set_target_properties(${pkgtarget} PROPERTIES FOLDER "Object Libraries") |
| add_dependencies(gollvm ${pkgtarget}) |
| |
| # Caller needs to know these. |
| set(package_ofile ${package_ofile} PARENT_SCOPE) |
| set(package_picofile ${package_picofile} PARENT_SCOPE) |
| set(package_goxfile ${package_goxfile} PARENT_SCOPE) |
| |
| # *.gox files are installed in <lib>/go/<ver>/<triple> |
| set(goxinstalldest "lib${library_suffix}/go/${libversion}/${LLVM_DEFAULT_TARGET_TRIPLE}/${pdir}") |
| |
| # Configure for install. |
| install(PROGRAMS ${package_goxfile} |
| COMPONENT ${pkgtarget} |
| DESTINATION ${goxinstalldest}) |
| |
| # Add an install target. |
| add_custom_target(install-${pkgtarget} |
| DEPENDS ${pkgtarget} |
| COMMAND "${CMAKE_COMMAND}" |
| -DCMAKE_INSTALL_COMPONENT=${pkgtarget} |
| -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") |
| add_dependencies(install-gollvm install-${pkgtarget}) |
| |
| endfunction() |