Hopefully, somebody else doing something similar to what you're doing will chime in here.
Seems overly complicated from an outsider's perspective. If what you say is true ...: "If 'copy_dlls' happens while 'B' is building, then it's possible the post-build event run by B that deletes the 'libs' directory also deletes some files copied by 'copy_dlls'" ...then copy_dlls depends on B, because if it runs before or while B is running, you have problems. So it has to run after. Seems like you have some untangling to do. On Thu, May 18, 2017 at 3:42 PM, Robert Dailey <rcdailey.li...@gmail.com> wrote: > To be clear, I do have a "package" target per real native target. > However, if I set up the dependencies like so: > > Target 'A' depends on 'copy_dlls' > Target 'A' depends on target 'B' > Target 'A_package' depends on 'A' > Target 'A_package' depends on 'copy_dlls' > > Furthermore, the add_custom_command() to delete 'libs' and copy the > *.so is added to 'A' and 'B' (each for their own 'libs' directory and > their own *.so output) > > Then when I do: > > $ ninja A_package > > The following items are built in any order (due to parallel builds): > > * B > * A (after B) > * copy_dlls > > If 'copy_dlls' happens while 'B' is building, then it's possible the > post-build event run by B that deletes the 'libs' directory also > deletes some files copied by 'copy_dlls', which means those files will > not get packaged when 'A_package' invokes `ant release` for the APK > packaging. > > I hope that makes the issue a little clearer... sorry for the confusion. > > On Thu, May 18, 2017 at 1:22 PM, David Cole <dlrd...@aol.com> wrote: >> Seems to me the simplest thing to do would be to have copy_dlls depend >> on nothing, and have package depend on copy_dlls and all the native >> targets, and then tell your developers to run: >> >> make individualTarget && make package >> >> Either that, or introduce a packageIndividualTarget target for each >> individualTarget. >> >> Maybe I just don't understand fully, but why would you ever "make >> individualTarget" and then expect package to work properly? What if >> stuff that depends on that individualTarget also needs to rebuild >> before packaging? Shouldn't you have to do a build all to guarantee >> that packaging the results works properly? >> >> >> >> >> >> >> On Thu, May 18, 2017 at 12:16 PM, 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