Skip to content

Commit 6541f47

Browse files
committed
ENH: Split Running and Parsing examples into an ExternalProject
This 1. Makes repeated builds of the ITKSoftwareGuide better because it does not need to run all the examples again durning CMake configuration. 2. Improves build dependency robustness when starting from a fresh build. Change-Id: Ib50994d97f760eeea6498d543f76df16fdd87ae7
1 parent 0f207a4 commit 6541f47

10 files changed

+407
-298
lines changed

CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,19 @@ set(PRIMARY_PROJECT_NAME ITKSoftwareGuide)
2222
option(${PRIMARY_PROJECT_NAME}_SUPERBUILD "Build ${PRIMARY_PROJECT_NAME} and the projects it depends on via SuperBuild.cmake." ON)
2323
mark_as_advanced(${PRIMARY_PROJECT_NAME}_SUPERBUILD)
2424

25+
set(PDF_QUALITY_LEVEL "Screen" CACHE STRING "PDF Quality. Options are: Screen, Printer, PrePress")
26+
2527
#-----------------------------------------------------------------------------
2628
# Superbuild script
2729
#-----------------------------------------------------------------------------
30+
project(${PRIMARY_PROJECT_NAME}) # <- NOTE: Here is the main project name setting
2831
if(${PRIMARY_PROJECT_NAME}_SUPERBUILD)
2932
project(SuperBuild_${PRIMARY_PROJECT_NAME}) # <- NOTE: Project name for pre-requisites is different form main project
3033
include("${CMAKE_CURRENT_SOURCE_DIR}/SuperBuild.cmake")
3134
return()
3235
else()
33-
project(${PRIMARY_PROJECT_NAME}) # <- NOTE: Here is the main project name setting
3436
include("${CMAKE_CURRENT_SOURCE_DIR}/${PRIMARY_PROJECT_NAME}.cmake")
3537
return()
3638
endif()
3739

3840
message(FATAL_ERROR "You should never reach this point !")
39-

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Following is a brief description of the build process:
5454
3. PNG files are generated by running ITK examples and converted to EPS using
5555
MagicTools; the resulting EPS files are saved in Art/Generated directory of
5656
the binary output directory.
57-
4. A Python script SoftwareGuide/ParseCxxExamples.py is invoked to extract the
57+
4. A Python script SoftwareGuide/Examples/ParseCxxExamples.py is invoked to extract the
5858
comments in the ITK examples source file delimited with BeginLaTeX, EndLaTeX
5959
and BeginCodeSnippet, EndCodeSnippet and generate LaTeX files which are
6060
copied into the Examples subdirectory of the binary output directory.

SoftwareGuide/Art/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,21 @@
99
file(GLOB PNGandJPG_IMAGES *.jpg *.png)
1010
file(GLOB EPS_IMAGES *.eps)
1111

12+
find_package(ImageMagick REQUIRED)
13+
if(NOT IMAGEMAGICK_CONVERT_EXECUTABLE)
14+
message("ImageMagick convert utility was not found. Please pass to advanced mode and provide its full path")
15+
endif()
16+
# Convert an image from some file format to EPS for inclusion in Latex using
17+
# ImageMagick. This image is an input image. A separate macro is necessary
18+
# because input images do not have any dependecies
19+
set(EPS_INPUT_CONVERT_FLAGS)
20+
set(EPS_OUTPUT_CONVERT_FLAGS)
21+
if( PDF_QUALITY_LEVEL STREQUAL "Printer" )
22+
# Upsample to satify the printer
23+
set( EPS_INPUT_CONVERT_FLAGS -density 72 )
24+
set( EPS_OUTPUT_CONVERT_FLAGS -density 72 -scale 4194304@ )
25+
endif()
26+
1227
set(OutputEPSFilePath "${SoftwareGuide_BINARY_DIR}/Art")
1328
foreach(ImageFile ${PNGandJPG_IMAGES})
1429
get_filename_component(ImageFileNoExt ${ImageFile} NAME_WE)

SoftwareGuide/CMakeLists.txt

Lines changed: 0 additions & 289 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,6 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake ${CMAKE_MODULE_PATH})
3232

3333
find_package(ITK 4 REQUIRED)
3434
include(${ITK_USE_FILE})
35-
find_path(ITK_EXECUTABLES_DIR
36-
NAMES ImageReadWrite ImageReadWrite.exe
37-
PATHS
38-
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}"
39-
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release"
40-
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug"
41-
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/RelWithDebInfo"
42-
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MinSizeRel"
43-
DOC "Where the ITK examples executables are"
44-
)
4535

4636
set(PDF_QUALITY_LEVEL "Screen" CACHE STRING "PDF Quality. Options are: Screen, Printer, PrePress")
4737
#
@@ -75,285 +65,6 @@ else()
7565
set(SoftwareGuide_DRAFT_WATERMARK_LATEX_BOOLEAN "\\itkDraftWatermarkfalse")
7666
endif()
7767

78-
#
79-
# Generate .cmake files containing those macros defined above.
80-
#
81-
# First make a directory to store generated images
82-
set(ART_GENERATED_FOLDER "${SoftwareGuide_BINARY_DIR}/Art/Generated" )
83-
make_directory( "${ART_GENERATED_FOLDER}" )
84-
85-
#
86-
# Rebuild the Software Guide figures
87-
set(RUN_EXAMPLES_SCRIPT "${SoftwareGuide_SOURCE_DIR}/Examples/RunExamples.py" CACHE FILEPATH "Where the RunExamples Script is")
88-
89-
90-
#
91-
# Find ImageMagick tools
92-
# This is used to convert image formats
93-
#
94-
#
95-
# Find ImageMagick tools
96-
# This is used to convert image formats
97-
#
98-
#include(${CMAKE_ROOT}/Modules/FindImageMagick.cmake)
99-
find_package(ImageMagick REQUIRED)
100-
if(NOT IMAGEMAGICK_CONVERT_EXECUTABLE)
101-
message("ImageMagick convert utility was not found. Please pass to advanced mode and provide its full path")
102-
endif(NOT IMAGEMAGICK_CONVERT_EXECUTABLE)
103-
104-
105-
#
106-
# ADD THE LIST OF INPUT IMAGES YOU WANT FLIPPED HERE.
107-
#
108-
# NOTE:
109-
# All input images in the list and all outputs that use these images
110-
# as inputs in cmd line args will be flipped about 'y'. The command line
111-
# argument itself does not run using the flipped images; instead the eps
112-
# images corresponding to the inputs mentioned in the list and their output
113-
# dependencies are flipped for inclusion in the TEX document.
114-
115-
option(ITK_FLIP_INPUTS_AND_THEIR_OUTPUTS "Flip the input images specified in CMakeLists and their corresponding outputs" ON)
116-
set(ITK_FLIP_IMG
117-
BrainProtonDensitySlice
118-
BrainT1Slice
119-
BrainT1SliceBorder20
120-
BrainProtonDensitySliceBorder20
121-
BrainProtonDensitySliceRotated10
122-
BrainProtonDensitySliceR10X13Y17
123-
BrainProtonDensitySliceR10X13Y17S12
124-
ConfidenceConnectedOutput1
125-
ConfidenceConnectedOutput2
126-
ConfidenceConnectedOutput3
127-
VisibleWomanEyeSlice
128-
VisibleWomanHeadSlice
129-
BinaryImage
130-
VentricleModel
131-
FivePoints
132-
ThresholdSegmentationLevelSetImageFilterVentricle
133-
BrainProtonDensitySliceShifted13x17y
134-
IsolatedConnectedImageFilterOutput1
135-
OtsuThresholdImageFilterOutput
136-
FastMarchingFilterOutput1
137-
FastMarchingFilterOutput2
138-
FastMarchingFilterOutput3
139-
ShapeDetectionLevelSetFilterOutput1
140-
ShapeDetectionLevelSetFilterOutput2
141-
ShapeDetectionLevelSetFilterOutput3
142-
ThresholdSegmentationLevelSetImageFilterWhiteMatter
143-
ThresholdSegmentationLevelSetImageFilterVentricle
144-
ThresholdSegmentationLevelSetImageFilterGrayMatter
145-
BinaryThresholdImageFilterOutput
146-
BinaryMedianImageFilterOutput
147-
SigmoidImageFilterOutput
148-
GradientMagnitudeImageFilterOutput
149-
GradientMagnitudeRecursiveGaussianImageFilterOutput3
150-
GradientMagnitudeRecursiveGaussianImageFilterOutput5
151-
DerivativeImageFilterOutput
152-
MeanImageFilterOutput
153-
MedianImageFilterOutput
154-
MathematicalMorphologyGrayscaleErosionOutput
155-
MathematicalMorphologyGrayscaleDilationOutput
156-
DiscreteGaussianImageFilterOutput
157-
BinomialBlurImageFilterOutput
158-
GradientAnisotropicDiffusionImageFilterOutput
159-
ThresholdImageFilterOutputBelow
160-
ThresholdImageFilterOutputAbove
161-
ThresholdImageFilterOutputOutside
162-
LaplacianRecursiveGaussianImageFilterOutput3
163-
LaplacianRecursiveGaussianImageFilterOutput5
164-
MathematicalMorphologyGrayscaleErosionOutput
165-
MathematicalMorphologyGrayscaleDilationOutput
166-
MathematicalMorphologyBinaryErosionOutput
167-
MathematicalMorphologyBinaryDilationOutput
168-
VotingBinaryHoleFillingImageFilterOutput1
169-
VotingBinaryHoleFillingImageFilterOutput2
170-
VotingBinaryHoleFillingImageFilterOutput3
171-
VotingBinaryIterativeHoleFillingImageFilterOutput1
172-
VotingBinaryIterativeHoleFillingImageFilterOutput2
173-
VotingBinaryIterativeHoleFillingImageFilterOutput3
174-
SmoothingRecursiveGaussianImageFilterOutput3
175-
SmoothingRecursiveGaussianImageFilterOutput5
176-
CurvatureAnisotropicDiffusionImageFilterOutput
177-
CurvatureFlowImageFilterOutput
178-
MinMaxCurvatureFlowImageFilterOutput
179-
BilateralImageFilterOutput
180-
RGBGradientAnisotropicDiffusionImageFilterOutput
181-
RGBCurvatureAnisotropicDiffusionImageFilterOutput
182-
ResampleImageFilterOutput1
183-
ResampleImageFilterOutput2
184-
ResampleImageFilterOutput10
185-
ImageRegistration1Output
186-
ImageRegistration1DifferenceBefore
187-
ImageRegistration1DifferenceAfter
188-
ImageRegistration2Output
189-
ImageRegistration2CheckerboardBefore
190-
ImageRegistration2CheckerboardAfter
191-
ImageRegistration5Output
192-
ImageRegistration5DifferenceBefore
193-
ImageRegistration5DifferenceAfter
194-
ImageRegistration5Output2
195-
ImageRegistration5DifferenceBefore2
196-
ImageRegistration5DifferenceAfter2
197-
ImageRegistration6Output
198-
ImageRegistration6DifferenceBefore
199-
ImageRegistration6DifferenceAfter
200-
ImageRegistration7Output
201-
ImageRegistration7DifferenceBefore
202-
ImageRegistration7DifferenceAfter
203-
ImageRegistration8Output
204-
ImageRegistration8DifferenceBefore
205-
ImageRegistration8DifferenceAfter
206-
ImageRegistration9Output
207-
ImageRegistration9DifferenceBefore
208-
ImageRegistration9DifferenceAfter
209-
MultiResImageRegistration1Output
210-
MultiResImageRegistration1CheckerboardBefore
211-
MultiResImageRegistration1CheckerboardAfter
212-
MultiResImageRegistration2Output
213-
MultiResImageRegistration2CheckerboardBefore
214-
MultiResImageRegistration2CheckerboardAfter
215-
ConnectedThresholdOutput1
216-
ConnectedThresholdOutput2
217-
ConnectedThresholdOutput3
218-
FastMarchingImageFilterOutput5
219-
FastMarchingImageFilterOutput6
220-
FastMarchingImageFilterOutput7
221-
FastMarchingImageFilterOutput8
222-
ShapeDetectionLevelSetFilterOutput5
223-
ShapeDetectionLevelSetFilterOutput6
224-
ShapeDetectionLevelSetFilterOutput7
225-
ShapeDetectionLevelSetFilterOutput8
226-
GeodesicActiveContourImageFilterOutput1
227-
GeodesicActiveContourImageFilterOutput2
228-
GeodesicActiveContourImageFilterOutput3
229-
GeodesicActiveContourImageFilterOutput5
230-
GeodesicActiveContourImageFilterOutput6
231-
GeodesicActiveContourImageFilterOutput7
232-
GeodesicActiveContourImageFilterOutput8
233-
CannySegmentationLevelSetImageFilterVentricle1
234-
LaplacianSegmentationLevelSetImageFilterVentricle
235-
BrainT1Slice_labelled
236-
ScalarImageMarkovRandomField1Output
237-
ImageSliceIteratorWithIndexOutput
238-
NeighborhoodIterators1a
239-
NeighborhoodIterators4a
240-
NeighborhoodIterators4b
241-
NeighborhoodIterators4c
242-
NeighborhoodIterators4d
243-
ShapedNeighborhoodIterators1b
244-
ImageAdaptorThresholdingA
245-
ImageAdaptorThresholdingB
246-
ImageRegistration4Output
247-
ImageRegistration4CheckerboardBefore
248-
ImageRegistration4CheckerboardAfter
249-
MultiStageImageRegistration1Output
250-
MultiStageImageRegistration1CheckerboardBefore
251-
MultiStageImageRegistration1CheckerboardAfter
252-
MultiStageImageRegistration2Output
253-
MultiStageImageRegistration2CheckerboardBefore
254-
MultiStageImageRegistration2CheckerboardAfter
255-
ImageRegionIteratorOutput
256-
)
257-
# END FLIP_INPUTS LIST
258-
259-
# Convert an image from some file format to EPS for inclusion in Latex using
260-
# ImageMagick. This image is an input image. A separate macro is necessary
261-
# because input images do not have any dependecies
262-
set(EPS_INPUT_CONVERT_FLAGS)
263-
set(EPS_OUTPUT_CONVERT_FLAGS)
264-
if( PDF_QUALITY_LEVEL STREQUAL "Printer" )
265-
# Upsample to satify the printer
266-
set( EPS_INPUT_CONVERT_FLAGS -density 72 )
267-
set( EPS_OUTPUT_CONVERT_FLAGS -density 72 -scale 4194304@ )
268-
endif()
269-
macro(CONVERT_INPUT_IMG SOME_IMG EPS_IMG IMAGEMAGICK_FLAGS)
270-
get_filename_component(IMG_BASENAME ${SOME_IMG} NAME_WE)
271-
list(FIND ITK_FLIP_IMG "${IMG_BASENAME}" _index)
272-
if(${_index} GREATER -1)
273-
if(NOT "${FLAGS}" MATCHES "-flip")
274-
set(FLAGS ${FLAGS} -flip)
275-
endif()
276-
endif()
277-
if( NOT DEFINED ${EPS_IMG}_HAS_CUSTOM_COMMAND)
278-
add_custom_command(
279-
OUTPUT "${EPS_IMG}"
280-
COMMAND ${IMAGEMAGICK_CONVERT_EXECUTABLE}
281-
ARGS ${FLAGS} -quality 100 ${EPS_INPUT_CONVERT_FLAGS} "${SOME_IMG}" ${EPS_OUTPUT_CONVERT_FLAGS} "${EPS_IMG}"
282-
DEPENDS ${RUN_EXAMPLES_SCRIPT}
283-
)
284-
set(${EPS_IMG}_HAS_CUSTOM_COMMAND 1)
285-
endif()
286-
set(FLAGS "")
287-
endmacro(CONVERT_INPUT_IMG)
288-
289-
#
290-
# Find Python executable
291-
include(${CMAKE_ROOT}/Modules/FindPythonInterp.cmake)
292-
if( NOT PYTHONINTERP_FOUND )
293-
message(FATAL_ERROR "Python executable was not found")
294-
endif( NOT PYTHONINTERP_FOUND )
295-
set(PYTHONCXXPARSER ${SoftwareGuide_SOURCE_DIR}/ParseCxxExamples.py)
296-
if( NOT EXISTS ${PYTHONCXXPARSER} )
297-
message(FATAL_ERROR "Missing script: ${SoftwareGuide_SOURCE_DIR}/ParseCxxExamples.py")
298-
endif()
299-
300-
#
301-
# Search for all the example sources
302-
#
303-
file( GLOB_RECURSE all_sources ${ITK_SOURCE_DIR}/Examples/*.cxx)
304-
# Exclude the RegistrationITKv3 sources.
305-
set( ITK_EXAMPLES_SRCS )
306-
foreach( source ${all_sources} )
307-
if( ITKv3_COMPATIBILITY )
308-
set(exclude RegistrationITKv4)
309-
else()
310-
set(exclude RegistrationITKv3)
311-
endif()
312-
if( NOT "${source}" MATCHES "${exclude}" )
313-
list( APPEND ITK_EXAMPLES_SRCS "${source}" )
314-
endif()
315-
endforeach()
316-
317-
message(STATUS "PRE_RUN_PYTHON ART GENERATION.")
318-
message(STATUS "Running: ${PYTHON_EXECUTABLE} ${RUN_EXAMPLES_SCRIPT} --itkSource ${ITK_SOURCE_DIR} --itkBuildDir ${ITK_BINARY_DIR} --itkExecDir ${ITK_EXECUTABLES_DIR} --SWGuidBaseOutput ${SoftwareGuide_BINARY_DIR} "
319-
)
320-
execute_process(
321-
COMMAND ${PYTHON_EXECUTABLE}
322-
${RUN_EXAMPLES_SCRIPT}
323-
--itkSource ${ITK_SOURCE_DIR}
324-
--itkBuildDir ${ITK_BINARY_DIR}
325-
--itkExecDir ${ITK_EXECUTABLES_DIR}
326-
--SWGuidBaseOutput ${SoftwareGuide_BINARY_DIR}
327-
WORKING_DIRECTORY "${ART_GENERATED_FOLDER}"
328-
RESULT_VARIABLE RUN_EXAMPLES_RESULT
329-
)
330-
if( NOT ${RUN_EXAMPLES_RESULT} EQUAL 0)
331-
message(FATAL_ERROR "POST_RUN_PYTHON ART GENERATION ${RUN_EXAMPLES_RESULT}.")
332-
endif()
333-
334-
include(${SoftwareGuide_BINARY_DIR}/Examples/GeneratedDependancies.cmake)
335-
336-
#
337-
# Parse Latex file for latex includes
338-
#
339-
set(TEX_DEPENDENCIES "")
340-
foreach(example ${ITK_EXAMPLES_SRCS})
341-
get_filename_component(TEX_FILE_BASE ${example} NAME_WE)
342-
set(TEX_FILE ${SoftwareGuide_BINARY_DIR}/Examples/${TEX_FILE_BASE}.tex)
343-
add_custom_command(
344-
OUTPUT ${TEX_FILE}
345-
COMMAND ${PYTHON_EXECUTABLE}
346-
ARGS ${PYTHONCXXPARSER} ${example} ${TEX_FILE}
347-
DEPENDS ${PYTHONCXXPARSER} ${example} ${${TEX_FILE_BASE}-DEPS}
348-
)
349-
set(TEX_DEPENDENCIES ${TEX_DEPENDENCIES} ${TEX_FILE})
350-
endforeach(example)
351-
352-
add_custom_target(BuildTexFiles ALL
353-
DEPENDS ${TEX_DEPENDENCIES}
354-
)
355-
356-
35768
add_subdirectory(Examples)
35869
add_subdirectory(Art)
35970
add_subdirectory(Latex)

0 commit comments

Comments
 (0)