Now that you described in more detail what you're trying to do I realized that I had a similar problem to solve.
It's about generating packages for an arm-based linux-build (Yocto-based). I decided against integrating my build into the Yocto-build and instead I'm using cmake to cross-compile the executables and libraries (C and C++). Packaging is done with an IPK-file via a script launched by cmake as the last step of the build process. For each library and executable which belongs to a future ipk-package I'm adding an install()-command which will, when the install-target is run, place the files into a directory inside the build dir. This directory is a dedicated one for the package: For example: top-level: set(PACKAGE_DIR ${CMAKE_BINARY_DIR}/common-exe-package) Somewhere in the hierarchy of the project's CMakeLists.txt add_library(common src.cpp [..]) install(TARGETS common DESTINATION ${PACKAGE_DIR}/usr/lib) and again somewhere else add_executable(exe exe.cpp) target_link_libraries(exe PRIVATE common) install(TARGETS exe DESTINATION ${PACKAGE_DIR}/usr/bin) Then I create a custom_target to create the package: add_custom_target( ipk-common-exe COMMAND [..] # commands to finalize the ipk-tree and # tar xfz ... to make the ipk-files COMMENT "creating common-exe IPK" WORKING_DIRECTORY ${PACKAGE_DIR} ) # add dependencies to a install-and-strip-target add_dependencies(ipk-common-exe install-and-strip) The "install-and-strip"-target is defined at the top-level add_custom_target( install-and-strip COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target install/strip) the built-in install/strip-target has a dependency to all targets use with install(TARGET ...) I'm using ninja and make -jX, both work in parallel. I'm build several packages in one cmake-build. Works like a charm. An additional bonus is that the install-target also removed RPATHs from executables. HTH, -- Patrick. On Thu, 18 May 2017 11:16:47 -0500 Robert Dailey <rcdailey.li...@gmail.com> wrote: > So let me go over the problem I'm trying to solve, because it's > possible at this point I'm over-engineering it, but it's hard to fix. > > So my build process is for native shared library targets that > eventually get included in an APK for Android. I'm using the NDK > toolchain to build my native targets. The general flow from nothing to > complete APK is as follows: > > 1. Build all native library targets > 2. Copy native *.so outputs from the CMake build to `libs/armeabi-v7a` > in the android project directory (where the src, res, and other > android directories are located) > 3. Run custom commands that basically invoke 'ant release', and since > I positioned the *.so files under 'libs' they get packaged with the > APK itself. > > This is how I provide support for using CMake to build native, run > java build, and perform APK packaging. > > There's a lot of setup that happens in CMake in order to make sure the > 'ant release' command behaves as expected. I have to handle a few > corner cases: > > * Each new build of the custom target that runs the 'ant release' > command has to only contain the *.so files that were built during that > run > * Various third-party libraries (pre-compiled *.so files) have to also > be copied to libs/armeabi-v7a for only certain android projects, > because we do not want duplicated *.so files across multiple android > libraries (ant release will fail if there are duplicate *.so files > across android project dependencies) > > So given this, my complete pipeline is as follows: > > 1. A `android_clean_libs` custom target is run which iterates all > known native targets with mapped java projects and completely deletes > its 'libs' directory (this is a forced clean prior to building) > 2. A `copy_dlls` target runs next, which copies third party > (precompiled) *.so files to a single common java project, in its > 'libs/armeabi-v7a' directory. > 3. Each native target now builds in parallel, as a post-build event it > copies its output *.so file to its respective libs/armeabi-v7a > directory for packaging. > 4. A final 'package' custom target runs which runs 'ant release' on > the bottom-most android project (that is not a library target by > itself). > > The part I don't like here is step #1. I don't like the clean to > require keeping track of a global property of a list of directories to > remove. Ideally, #1 should run as a post-build event during step 3. > Basically each native target should delete its 'libs' directory prior > to copying its own *.so target to that directory. However, I can't do > this because of step #2. Step 2 must happen first, because it's the > only way I can guarantee that it will execute regardless of which > target I build (all, or specific target). I make `copy_dlls` a > dependency of every other target, so it always runs. If I could force > it to run *last*, then I could simplify step 1. > > Sorry if this is too much information or if I've not explained things > clearly, but I wanted to hash out the details because maybe there is a > better approach. I'm willing to start from scratch on this if it > improves the design of the targets. > > Thanks again!! > > > On Thu, May 18, 2017 at 10:51 AM, David Cole <dlrd...@aol.com> wrote: > > I'm sorry, I misunderstood that you wanted it to run last regardless > > of what target you are building. I was assuming you wanted it to > > happen when you build the "all" target. I didn't think you wanted to > > run it after any other *individual* target which you might specify. > > > > I don't know of an easy way to do that. You could add a custom > > command as a post-build command on every single target, but that > > seems like it wouldn't work for you either, as it would run the > > command potentially multiple times, with no way to tell whether > > you're being called last or not. > > > > Sorry. > > > > Why does this need to run after the build of any individual target? > > Why not just say there are two ways to get it to run: build "all" or > > explicitly build it after you build the other individual thing you > > want? > > > > > > > > > > On Thu, May 18, 2017 at 10:24 AM, Robert Dailey > > <rcdailey.li...@gmail.com> wrote: > >> David, > >> > >> Thanks for your help. So if I do it as you suggest, this will also > >> require I specify `ALL` to add_custom_target(), correct? If I do it > >> this way, will it still run even if it isn't a dependency of the > >> target I'm building? > >> > >> Let me set up a simple scenario for my own understanding. Suppose I > >> have the following targets: > >> > >> * A (add_library target) > >> * B (add_library target) > >> * C (add_custom_target target) > >> > >> Dependencies: > >> > >> B depends on A > >> C depends on B and A > >> > >> Normally if I build B, only A and B will build. However, if C was > >> set up using `ALL`, will it build C when I build B? So the > >> expected build order in this case would be: > >> > >> 1. A > >> 2. B > >> 3. C > >> > >> Thanks in advance. > >> > >> On Wed, May 17, 2017 at 4:26 PM, David Cole <dlrd...@aol.com> > >> wrote: > >>> The way I know how to do this is to add it last at the bottom of > >>> the top-level CMakeLists.txt file, and then use add_dependencies > >>> to make it depend on all other targets. (Or at least all other > >>> "leaf" targets, which further depend on others, ... the sum of > >>> which is "all other targets" besides the new "last" target.) > >>> > >>> So it's not pretty, but it's possible. > >>> > >>> > >>> HTH, > >>> David C. > >>> > >>> > >>> > >>> On Wed, May 17, 2017 at 11:36 AM, Robert Dailey > >>> <rcdailey.li...@gmail.com> wrote: > >>>> I have a custom target that must meet the following requirements: > >>>> > >>>> * It must always run, regardless of what subset of other targets > >>>> are being built > >>>> * It must always be the very last thing run. In parallelized > >>>> builds, it must wait until all other targets are done building > >>>> before starting, so that it is the very last target run, and > >>>> should not run in parallel with others. > >>>> > >>>> Is this possible? I'm willing to use hackery if needed... > >>>> > >>>> Running CMake 3.8.0. Thanks! > >>>> -- > >>>> > >>>> Powered by www.kitware.com > >>>> > >>>> Please keep messages on-topic and check the CMake FAQ at: > >>>> http://www.cmake.org/Wiki/CMake_FAQ > >>>> > >>>> Kitware offers various services to support the CMake community. > >>>> For more information on each offering, please visit: > >>>> > >>>> CMake Support: http://cmake.org/cmake/help/support.html > >>>> CMake Consulting: http://cmake.org/cmake/help/consulting.html > >>>> CMake Training Courses: http://cmake.org/cmake/help/training.html > >>>> > >>>> Visit other Kitware open-source projects at > >>>> http://www.kitware.com/opensource/opensource.html > >>>> > >>>> Follow this link to subscribe/unsubscribe: > >>>> http://public.kitware.com/mailman/listinfo/cmake -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake